Jump to content


Popular Content

Showing content with the highest reputation since 03/21/21 in Posts

  1. angusj

    Resource Hacker

    Resource Hacker A resource editor for 32bit and 64bit Windows applications. It's both a resource compiler and a decompiler - enabling viewing and editing of resources in executables (*.exe; *.dll; *.scr; etc) and compiled resource libraries (*.res, *.mui). Resource Hacker also provides many options for compiling and decompiling resources from the command-line. http://www.angusj.com/resourcehacker/ Download: http://www.angusj.com/resourcehacker/reshacker_setup.exe
  2. Stefan Glienke

    Introducing Delphi Uses Helper

    Introducing "Uses Helper" - some little but incredibly helpful IDE plugin https://delphisorcery.blogspot.com/2021/03/introducing-delphi-uses-helper.html
  3. Rollo62

    Delphi 10.4 Portable

    My version, is portable. I have installed it on a notebook
  4. balabuev

    Delphi WAT of the day

    Task completed:
  5. Stefan Glienke

    Determining why Delphi App Hangs

    You know that annoying person constantly interrupting and asking you the status of some very busy task you are performing? That person is called Application.ProcessMessages
  6. Dalija Prasnikar

    Determining why Delphi App Hangs

    This is bad idea. First, Application.ProcessMessages has some global side effects that can bite you in behind when you least expect them. Next, depending on the code, it is possible that some pieces still take too long to keep UI fully responsive. Using background threads for simple operations is not rocket science and at the end when you take all pros and cons it is not more complicated than using Application.ProcessMessages.
  7. David Heffernan

    QueryPerformanceCounter precision

    Am I the only one who finds it odd that we have a two page thread on replacing TStopwatch with QPC when in fact TStopwatch is QPC. Perhaps somebody else could point out to @Mike Torrettinni that when he says It's actually what he had originally with TStopwatch.
  8. everybyte

    VCL Handling of dpi changes - poor performance

    We used a workaround in our application to make a smooth transition from one monitor to another. I think the problem is not so much as refresh time but the fact that refresh kicks in when crossing monitor boundary. As a result user cannot continue moving the form (for refresh period) and this does not feel right. For smooth transition we detect the start of crossing using WM_ENTERSIZEMOVE and WM_MOVING. At that moment we ensure that the form does not update (e.g. WM_SETREDRAW) . Once movement is finished (WM_EXITSIZEMOVE) we let the form update. Still a lot of code gets executed even without refresh, so an additional trick was helpful. In our case the content of the MainForm was on an embedded form, so on crossing we set embedded form invisible and without parent. In that case it was not scaled so we avoided this on crossing. After crossing was finished we reinstated content visibility and the parent, which finished the scaling. To improve visual outlook we captured content onto scaled TImage and put it on top of the MainForm. As a result only TImage gets quickly scaled on crossing and provides (possibly blurred) visual feedback until content finishes scaling and is ready to show.
  9. David Heffernan

    QueryPerformanceCounter precision

    TStopwatch is implemented on Windows using QueryPerformanceCounter......
  10. Dalija Prasnikar

    Determining why Delphi App Hangs

    The code where you call Application.ProcessMessages procedure TMainForm.BtnClick1(Sender: TObject); begin DoFoo; DoBar; DoFork; end; procedure TMainForm.BtnClick2(Sender: TObject); begin DoFoo; Application.ProcessMessages; DoBar; Application.ProcessMessages; DoFork; end; procedure TMainForm.BtnClick3(Sender: TObject); begin TThread.CreateAnonymousThread( procedure begin DoFoo; DoBar; DoFork; end).Start; end; Problem with Application.ProcessMessages is that code that would execute in one block without interruptions, like in first example, can now be interrupted and some other code can start running in the middle of it. For instance you can click same button twice. Or you can close form and destroy it while other code is still running and using it. Now moving in background thread does not solve those issues, because you can still click the button twice and you can close the form while you running something in the background. But, there are few things to consider here. First, while code with ApplicationProcessMessages can be interrupted at any point, code in background thread will run serially, one line after the other, just like the code that does not call Application.ProcessMessages. It is far easier to follow the logic (and debug) such code. One of the arguments for Application.ProcessMessages was that it is easy to use, comparing to multithreading. That is true only on the surface, it seems easy and that is why we were all using it. So you have beginner developer writing all kind of poor code in event handlers and application becomes unresponsive, so he is advised to use ApplicationProcessMessages, and he sprinkles his code with those and application might work better (seemingly). In the reality, he learned nothing, his code is really bad, and sooner or later when some user clicks something unexpected everything will fall apart. When you have to move code to the background thread, you need to think more about it and you need to isolate it better. Mere process of isolating functionality will make that code better. Now, you can still have developer that will just move the whole thing to the background without doing any of that, but that code will not seemingly work (that rarely happens) and it will not work properly, which will hopefully trigger the developer to ask for help and learn how to do that properly. There is a difference. If the UI reacts slowly that means when you drag the window and it will not drag smoothly, when you click the button you may not get immediate response, so you will click it again. Background thread does not block the UI so it does not matter how long it takes to cancel the operation. You can write your code in such manner that when action is canceled, user can immediately continue doing something else. You don't have to move data between threads - data is not contained within threads (unless you specifically create thread local data), you just need to prevent multiple threads changing the same data simultaneously.
  11. Dalija Prasnikar

    Determining why Delphi App Hangs

    First, as we all know (I hope) if application cannot process messages, it becomes unresponsive and OS (and user) can kill it, because it may look like it is dead. Application.ProcessMessages pumps the message queue so the OS can see that application is still alive. There are few problems with that approach. Most obvious problem is that such code becomes re-entrant. That can cause some nasty side-effects depending on the code you are executing. But main issue is that you are still running slow operation in main thread, and no matter how much you are able to interrupt that execution with calls to Application.ProcessMessages, this will still slow down UI processing and application may respond to user input slowly. Also, this is not just the problem with reacting to input, but all the calls to Application.ProcessMessages will make that long operation running even longer. Next issue that is often overlooked is that some parts of the long running process may not always execute fast enough. Imagine connecting to some web service and retrieving some very small amount of data. In perfect conditions that may take blink of an eye, but if connection is bad for any reason, this operation can block the main thread for much longer. And Application.ProcessMessages will not help you with that. Also, for cross-platform development, this is more important because mobile devices will kill non responsive application much faster. On Android you cannot even freely perform network operations in the context of the main thread because OS will thow exception if you try. Also on android Application.ProcessMessages no longer works and can deadlock the application.
  12. Stefan Glienke

    Improving type safety

    Please vote if you think the compiler could help us writing more robust code: https://quality.embarcadero.com/browse/RSP-33504
  13. Attila Kovacs

    Min & Max

    Am I the only one annoyed that these are in System.Math?
  14. pyscripter

    TTreeNode leak when VCL styles are active

    Somebody had to do it: [RSP-33448] Memory leaks when using styles - Embarcadero Technologies Feel free to add to the report.
  15. https://delphisorcery.blogspot.com/2021/03/how-to-hide-codeinsight-status-panel.html
  16. Stefan Glienke

    Delphi WAT of the day

    function (const arr: TArray<T>): RecWithTwoFields (Pointer, Integer) Bonus: inlining that function looks like this - go go eax, you got it eventually!
  17. Dalija Prasnikar

    Determining why Delphi App Hangs

    When I said put your code in background thread, I didn't mean literally like run exactly the same code in background thread. But for any code that runs long, Application.ProcessMessages is always the wrong solution. It may be quick fix at some point, but it is still a wrong solution. First step in writing better code is acknowledging that Application.ProcessMessages is wrong solution. Then and only then one can start going in different direction and start learning and applying better solutions. It can be long process, depending on the existing code you (I don't literally mean you) already have. But the sooner you start, the less work you will have in the future when you start removing Application.ProcessMessages. If you never start doing that, sooner or later you will encounter code where Application.ProcessMessages will not work as intended and you will not be able to make UI fully responsive when using it. Learning how to use background threads at that point - when you cannot properly take time to experiment and learn will only make it harder. It depends, but certainly more often than with Application.ProcessMessages approach.
  18. David Heffernan

    Determining why Delphi App Hangs

    Run in the debugger. When it hangs, use Run | Program pause to pause execution. Look at the thread window, and double click the main thread since I guess that is the thread which is hung. Look at the call stack window which will tell you what the thread is doing that is not completing.
  19. Stefan Glienke

    Warning and Error at the same time?

    The correct word is "Warror", sometimes also called "Errning" /s
  20. Dalija Prasnikar

    Delphi WAT of the day

    That is useful if you get paid by the LOC compiler generates-
  21. Stefan Glienke

    Min & Max

    Not that I know of because the compiler unfortunately does not utilize the cmovxx instruction. This has been reported already (I think there are other reports similar to this one): https://quality.embarcadero.com/browse/RSP-21955 Edit: Here is what clang and gcc generate: https://godbolt.org/z/4hnYrjYM6 And this is what Delphi generates: Project1.dpr.16: Result := min(i, 42); 00408F94 83F82A cmp eax,$2a 00408F97 7E05 jle $00408f9e 00408F99 B82A000000 mov eax,$0000002a Project1.dpr.17: end; 00408F9E C3 ret Project1.dpr.16: Result := min(i, 42); 000000000040D4F0 83F92A cmp ecx,$2a 000000000040D4F3 7F04 jnle Main + $9 000000000040D4F5 89C8 mov eax,ecx 000000000040D4F7 EB05 jmp Main + $E 000000000040D4F9 B82A000000 mov eax,$0000002a Project1.dpr.17: end; 000000000040D4FE C3 ret Yeah yeah branch predictors and all that - but if they are filled up with garbage conditional jumps like this they have less room for the important ones.
  22. I guess if there are no firm rules on the expected behaviour, then that makes it easier to write faster code.
  23. Hi there, I want to show you my approach how to organize and ease modular designs. Usually I like to have one main access unit, and all much granularized sub-features distributed in separate units. The main and sub-units build a kind of tree of functionality, where each unit can stand alone, but usually all units are highly related between each other. To access and open those deeper layer units is usually much of a click-drill-down the unit tree, or a lot of search and select via search function or other tools. Here is the general layout I like to use, which has a lot of advantages for me: unit My.Thing; interface uses My.Thing.Intf , My.Thing.Factory // // , My.Thing.Impl // QuickAccessUses // , My.Thing.Events.Intf // , My.Thing.Events.Carrier.Intf // , My.Thing.Events.Carrier // , My.Thing.Common // , My.Thing.Features // , My.Thing.Features.Factory // , My.Thing.Features.Impl // , My.Thing.Feature.Intf ; You can place the cursor on the unit names, even if its inside of a comment, and with right click "Open file at cursor" you can directly open the desired unit. The advantages I see from my point of view: - a single point of access, for a larger structural, modularized tree - immediately all of the close-related units are visible on the screen - directly see the kind of structure, maybe leads to further unit refactorings - it is a most easy and fast way to find and navigate to the desired unit, and to open it - no tipping of unit names into searchboxes The disadvantages: - None ( except putting some extra lines in comments ) I like this a lot, and this works only due to the fact that "Open file at cursor" works also within comments. Thats why I want to ensure that the Embarcadero team is aware of this, and never is going to change the open behaviour in the future editors
  24. Wil van Antwerpen

    Delphi 10.4 : Unlock Windows by call to Windows API

    There's no supported way to do what you want and that's a good thing.
  25. Attila Kovacs

    Min & Max

    _exactly_ Because if someone sees it, he could think I can do math 🙂