-
Content Count
2297 -
Joined
-
Last visited
-
Days Won
119
Posts posted by Anders Melander
-
-
You need to examine the call stack of all the threads.
When you break the call stack is just shown for the currently active thread which is rarely the one you're interested in.
P.S. I can see from your video that you have DropBox installed...
-
If you can reproduce the problem then simply run the application in the debugger, break when the problem occurs and examine the callstacks.
...however; My usual advice when people experience this kind of progressive or periodic slowdown/lockup is to uninstall the various cloud storage services they have running (ITunes, Google Drive, OneDrive, etc.). Solves the problem in 9 out of 10 cases.
-
I've been using it since the first version (which AFAIR was before XE) with no major problems. Maybe because my style is pretty standard (aka the One True Style ).
One thing I've never gotten to work though is formatting a block of text: It always formats the whole file. No biggie.
It's usually the first step I do when I'm brought in to fix other peoples code.
-
25 minutes ago, Joseph MItzen said:Professor Lee goes on
To paraphrase David Heffernan: That is utter nonsense and it doesn't appear that your Professor Lee has much practical knowledge about how to work safely with threads. Or maybe he's just using hyperbole to get a point across.
Under any circumstances, Quoting academia? To disprove the opinions of a professional, highly skilled and experienced developer? Really? How about some arguments based on your own knowledge and experience...
Many of us use threads on a daily basis and do so without wreaking havoc in the universe. If you understand the pitfalls of multi threading, know how to protect your resources, synchronize execution, understand race conditions, etc. etc., then threads are just another tool in the box. If you don't understand threading then yes, it will hurt you in a gazzilion ways you literally (and I use that word in the European sense) didn't think possible.
-
13 minutes ago, dummzeuch said:In that case obviously not.
Actually it might. One of my grieves with the Refactor menu item is that if you accidentally move the mouse over the menu item (e.g. on the way to the View or Project menu item) then there's a noticeable delay (very noticeable on low end systems) as the IDE loads the refactor stuff (among it the J# run time I suspect) in order to populate the sub menu.
2 hours ago, Dany Marmur said:we should maybe start another thread
Agree, but I don't think I'll have more to contribute on the subject.
-
-
-
-
Just now, Fr0sT.Brutal said:What if CallStuffThatMightBlockForever never returns?
Then the thread will be killed when the application terminates.
The point is that it's better to forget about the thread, report a timeout and continue as if the thread had been forcefully terminated.
Of course if the thread has allocated or is blocking resources then that solution might not work.
-
49 minutes ago, aehimself said:If Self.IsRunning Then TerminateThread(Self.Handle, 1);
I'm assuming the above is just an example to explain what you need - since if you can kill the thread from within the thread, then the thread isn't frozen and you could just exit it the normal way.
3 minutes ago, Dalija Prasnikar said:if you need to kill the thread, you basically need to kill the application itself.
I completely agree. Just don't do it.
What you could do is signal the thread (use an event, a boolean, whatever) that it has become thread-non-grata and then just forget about it.
If the blocking call ever returns then your thread can check the signal and terminate. E.g. something like this in your TThread.Execute
procedure TMyThread.Execute; begin while (not Terminated) do begin CallStuffThatMightBlockForever; if (FNotInterestedAnymore) then break; end; end;
-
3 hours ago, Remy Lebeau said:TRegistry.SaveKey() uses the Win32 API RegSaveKey() function
Additionally, RegSaveKey doesn't save in .reg format but in registry hive format.
There is no API for saving in .reg format.
- 1
-
7 hours ago, chkaufmann said:The only question that remains, how can I set the IDE font used during designing to "Segoe UI, 9pt" because right now, when I choose "ParentFont = True" then I still get "Tahoma 8pt".
I'm afraid I can't answer that.
Supposedly there used to be a registry key that could do the trick (HKCU\Software\Embarcadero\BDS\19.0\FormDesign\DefaultFont) but that didn't work with the embedded form designer and as far as I can tell it no longer work with the detached designer either.
I guess you could create an IDE plugin that modifies the form designer but that's probably more work than it's worth.
Maybe just a design time package that modifies Application.DefaultFont like above will do the trick, but that will affect the whole IDE.
FWIW I understand the OCD in you that wants the form to use SegoeUI at design time but it shouldn't really matter. If you have designed it "properly" then the form should be able to display correctly with both SegoeUI and Tahoma. After all you don't know what font the end-user will be using.
-
1 minute ago, David Heffernan said:It's a bug for the very reasons that you raised!
I guess it's a matter of perspective.
If you didn't expect the thread to start until after the constructor then I can see how the behavior would be seen as a bug. I never expected it to behave any other way so to me it was just an annoyance.
A bit like FreeOnTerminate. A pretty good way to shoot one self in the foot.
-
1 minute ago, David Heffernan said:That was a bug fixed in Delphi 6, and one of the reasons for the introduction of AfterCreation.
That must have been around the time when I stopped reading the documentation 🙂
I can't see why it would be classed as a bug though.
-
1 minute ago, Dalija Prasnikar said:Actually, there is no race condition because thread is actually started in AfterConstruction. So you can put just about anything you need in thread constructor and create thread in non suspended state.
Oh... You're right. It's even documented:
QuoteI think I'll continue to use the create-suspended pattern anyway since it explicitly does what I wish.
-
3 hours ago, David Heffernan said:What happens if you pass False and so don't create suspended?
I know that this isn't really what you're asking but I don't think I've ever had a case where one didn't need to create suspended.
You always have to either pass some information to the thread or initialize it's data and if you don't create it suspended there will be a race between the creator and the thread for access to the thread data structures. For example:
type TMyThread = class(TThread) private FData: TSomeType; protected procedure Execute; override; public construtor Create(const AValue: TSomeType); end; construtor TMyThread.Create(const AValue: TSomeType); begin inherited Create(False); // Thread starts immediately FData := AValue; // Race condition here end; procedure TMyThread.Execute; begin FData.WhatEver; // Race condition here end; var Thread: TMyThread; begin Thread := TMyThread.Create(SomeData); end;
-
@Vandrovnik A new version with the Duplicate View is now available:
http://melander.dk/download/amTranslationManagerInstall-1.0.7254.4932.exe
I had a bit of trouble getting this version up as BitDefender kept insisting that amResourceModuleBuilder.exe contained the Gen:Variant.DCry.1 ransomware.
In the end I had to simply include the previous version of that file instead.
Description of the Duplicate View above.
I have also included the "Locate in TM action:
As the hint says, the action attempts to locate the focused source/target pair. It tries to be a bit intelligent about it in case there are multiple candidates (due to sanitation/equalization) so it will give priority to exact matches, case insensitive matches, sanitized matches and equalized matches, in that order. If a match is found the TM is opened and the matching row is selected:
This version also includes Copy to clipboard (as CSV) and Save to CSV. Next up is Paste and Import from CSV.
- 1
-
On 11/9/2019 at 10:05 AM, Vandrovnik said:If you add the button for finding duplicates in Translation Memory, please could this button follow the same rules for equalization as the rest of BTM?
Done. The action performed on values to check for equality isn't called equalization though. It's called normalization. Internally, in the source, I call it Sanitation (i.e. I remove all the junk).
Anyway, here's what I have implemented:
The "duplicate view" is invoked via the popup menu:
When viewing duplicates a new column is added. This column displays the sanitized value of the selected language. You can control what sanitation rules to apply.
Only rows that have duplicate values are displayed in duplicate view.
In case you wonder why I'm not grouping on the Duplicate column; I tried it but found that it just cluttered the user interface and made the grid too cumbersome to navigate.
I'll try to get a new version with these changes released tomorrow or Tuesday.
On 11/9/2019 at 10:05 AM, Vandrovnik said:If I press Yes, a duplicate record will be created; what I need is to replace original German text with the new one. Or is it possible to go directly to TM to the record which was used to translate this term to German and make changes there?
I understand the problem.
The dialog is already trying to communicate too much information and has become too complex for a standard message dialog. I have already redesigned it a bit (see below) but in order to add a "Replace" action I would have to switch to using a full blown Task Dialog or even better a custom dialog. That however will have to wait.
I think the best I can do in the short term is to add a "Find in TM" action. This would open the TM, try to locate the currently focused Source/Target value pair and focus the target value in the TM.
- 1
-
On 11/7/2019 at 9:55 AM, chkaufmann said:Font.Height = -12 Font.Name = 'Segoe UI'
Is there a simple way to achieve this?
In the project file (the DPR file) I do this before the first form is created:
if (CheckWin32Version(6, 0)) then begin // Application.DefaultFont is the font used when TForm.ParentFont=True. // It is Tahoma by default but should be Segoe UI on Vista and later (according to MS UI guide lines). // See InitDefFontData() in graphics.pas Application.DefaultFont.Assign(Screen.MessageFont); // DefFontData.Name specifies the default font for everything that doesn't specify a specific font. // For now we leave it as is (Tahoma). At some point it should follow the system default like above: // DefFontData.Name := Screen.MessageFont.Name; end;
And then I just make sure to set all forms ParentFont=True at design time.
- 3
- 1
-
17 minutes ago, Joseph MItzen said:Classic OOP would, for instance, create a deck of cards class and then inherit from that to produce a blackjack game
Nope. A deck is model, data, state and maybe presentation. The game is logic.
A game is not a deck. A game uses a deck. Really basic OOP since we're going there.
18 minutes ago, Joseph MItzen said:n the VCL, TJpegImage, TPNGImage, etc. are all inheriting from the TGraphic base class. If they all inherited from the TImage class instead
Why stop there?
What about layers, filters, transformations, scanner and cloud support. Yes, let's add SOAP, REST, FTP and Kermit support in case need to transfer these images between systems.
Why do we need different classes at all? We could just create a single class that does EVERYTHING.
6 minutes ago, Joseph MItzen said:It's the VCL inheritance scheme that seems rather ad hoc and unusual.
You're confusing high level ease of use with low level architecture. The difference between the VCL and f.ex. ImageMagic is that one of them has it and the other doesn't. I'm guessing you've never read through the ImageMagick source code since you use it as a reference. I have. It's written in C. That might give you an idea of the inheritance scheme it uses... No?
There's really no point in me trying to explain my point further since our reference frames are obviously worlds apart. Good night and good luck.
- 1
-
27 minutes ago, Joseph MItzen said:Why not have just one image type that can read/write multiple formats?
Monolithic design... Pick up any book on software design and it will explain why that is not a good idea. I'm not going to do it here.
32 minutes ago, Joseph MItzen said:Or at least have TJPEGImage, etc. descend from TBitmap rather than TGraphic?
Unnecessary coupling. The above book will explain that too, but ask instead: Why should it?
Make a toolbox of individual tools that does as little as possible as good as possible and then assemble them into something larger. A swiss army knife is good to have if you're stranded on a deserted island. Besides that it's only good for impressing your 7 year old friends.
Anyway, we're hijacking Foersom's thread. I'm outta here.
-
1 hour ago, Anders Melander said:at what level should it be configurable
Here's what I have implemented for now. It's very rudimentary and applies globally:
-
54 minutes ago, Joseph MItzen said:Do you know what the reason might be for that design decision?
BMP, PNG, JPEG, GIF etc. are encoding formats. The sole purpose of TPNGImage, TJPEGImage and TGIFImage is to read, write and display these formats. Their internal representation is optimized to handle the features of the file format. They are not optimized to handle image manipulation.
TBitmap on the other hand implements the BMP encoding and is internally represented as a native Windows DIB or DDB. TBitmap can wrap these with a TCanvas and thus provide access to most of the functionality of the GDI through the canvas.
Additionally almost all other formats can convert to and from TBitmap so there's no reason why all the other formats should duplicate the functionality in TBitmap/TCanvas/GDI. They would just have to convert to/from TBitmap internally to do so anyway.Btw, using TCanvas.Pixels is extremely slow but fine for learning and very minor drawing tasks. For anything serious you have to mess with the raw DIB data directly - or use something like Graphics32 which does that for you. When you're using Pixels to manipulate the whole bitmap then the optimizations in the code become pretty pointless and only obfuscates the algorithm.
- 1
-
2 hours ago, Vandrovnik said:The equalization - is it possible to customize it somehow?
No. But...
2 hours ago, Vandrovnik said:Upper/lower is problematic between Czech and German (in Czech noons begin with lower case, in German with upper case).
OK. I will have to do something about that.
For matches from TM the rule is that if I find an exact match in the TM then I do not equalize case (*). For example if I'm translating "Foo" and I find "Foo"->"bar" then I use "bar" as the translation. If I find "FOO"->"BAR" then I equalize "BAR" to "Bar" and use that.
*) I still equalize endings and accelerators regardless of match exactness since the I consider TM data fidelity/consistency somewhat poor.I currently have the following equalization rules:
- If source has an accelerator then make sure target also has one. If possible use the same hot key.
- If source does not have an accelerator then accelerators are removed from the target.
- If source ends with a colon, semicolon or ellipsis then make sure the target also does so, but only add new ending if the target ends with an alphanumeric character.
- If source does not end with a colon, semicolon or ellipsis but the target does then remove the ending from the target.
- If source is surrounded with ( ), [ ], { }, " ", ' ' or < > then make sure the target also does so.
- If source is UPPER CASE, lower case, Title Case, Sentence case or simply Starts with an uppercase letter followed by a lowercase letter then make sure the target is too.
It's implemented in the MakeAlike function in amLocalization.Utils.pas
If I'm understanding you correctly then the only safe case rule between Czech and German is the UPPER CASE and maybe the Title Case rule.
So if I'm making equalization configurable at what level should it be configurable. I mean I could make everything optional and all values configurable but it will be a nightmare to implement the UI for it and probably far too complex for the user to manage. I'm also guessing that the desired rules would differ between projects or even within projects, between languages.
2 hours ago, Vandrovnik said:have disabled Apply to similar values, will it disable all these equalization and look for exact mathes only?
No.
The "Apply new translations..." and "Apply to similar values" options controls if new translations are automatically applied to other identical or similar (via normalization) terms.
For example if I translate "Foo" to "Bar" in once place, then it can automatically apply this translation to all other instances of "Foo" in the project. If the "similar" option is enabled then it will also apply the translation to "&Foo"->"&Bar", "FOO"->"BAR", "[foo]"->"[bar]" etc.
Sourcetrail support for Delphi
in Delphi IDE and APIs
Posted
https://www.sourcetrail.com/blog/open_source/
Also Wow. Bold move and I hope it turns out good for them.
I can't help but think of Borland who went for the exact opposite solution (remember Inprise?) and almost killed Delphi in the process. And we're still paying the price for that fiasco - literally.