Jump to content

David Heffernan

Members
  • Content Count

    3534
  • Joined

  • Last visited

  • Days Won

    175

Posts posted by David Heffernan


  1. 37 minutes ago, aehimself said:

    My guess is that there is a reason for suspended creation, it is just not included in the example code above. What I try to say is, I always create TThreads suspended myself but mostly because I want to do stuff with them before the actual execution (e.g. .NameThreadForDebugging, etc.).

    Do that in the constructor of the thread if you wish. No need to create the thread suspended.


  2. 19 minutes ago, Anders Melander said:

    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.

    That was a bug fixed in Delphi 6, and one of the reasons for the introduction of AfterCreation. I never create threads suspended.

    • Thanks 1

  3. 4 hours ago, aehimself said:

    Code is from D7-era. Maybe it worked different back then...? In 10.2 .LoadFromFile effectively does the same (only without the .BeginUpdate and .EndUpdate).

    But I remember that I had to change due to insanely long loading times.

    I don't think that there was any difference regarding the streams. I think you've just mixed up the begin/end update with the streams and got a bit of cargo cult. FWIW your try/finally is not right.


  4. 1 hour ago, aehimself said:

    Memo.Lines.LoadFromFile suffers from performance issues if the file is n x 10 MB, especially if it is on a network location. I changed most of my sensitive methods to use Streams instead:

    
      fs := TFileStream.Create('filename.txt', fmOpenRead + fmShareDenyNone);
      Try
       Memo.Lines.BeginUpdate;
       Memo.Lines.LoadFromStream(fs);
      Finally
       FreeAndNil(fs);
       Memo.Lines.EndUpdate;
      End;

     

    This looks a bit bogus to my eyes. Why would this change anything. Surely LoadFromFile use a file stream. 


  5. 43 minutes ago, Remy Lebeau said:

    Not in the IDE, no.  However, the DefFontData variable is publicly accessible, so you can modify it at runtime before creating any of your TForm objects.

    I guess you could modify DefFontData in a design time package

    • Like 1

  6. No need for a workaround. Creating processes, and waiting for them to terminate is routine stuff on all platforms.

     

    Definitely worth seconding everything that @Remy Lebeau said. You don't want to replicate ShellExecute because you don't want to use it at all. ShellExecute is used to execute shell verbs. But you want to create a process. A quite different thing altogether. Albeit the open verb on an executable file often results in a new process being created. 


  7. @Stefan Glienke Your code above (and in spring4d) uses WriteProcessMemory to modify executable pages. This relies on an undocumented implementation detail of WriteProcessMemory. Namely that it will handle the protection flags on your behalf.  Personally I would prefer to use VirtualProtect with this sort of pattern:
     

    procedure PatchCode(Address: Pointer; const NewCode; Size: Integer);
    var
      OldProtect: DWORD;
    begin
      if not VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, OldProtect) then begin
        Fail;
      end;
      Move(NewCode, Address^, Size);
      FlushInstructionCache(GetCurrentProcess, nil, 0);
      if not VirtualProtect(Address, Size, OldProtect, @OldProtect) then begin
        Fail;
      end;
    end;

     

    • Thanks 1

  8. 1 hour ago, McScotty said:

    My question was that I thought setting PopUpParent was the same (more or less) as setting WndParent in the CreateParams.

    It is the same if you do it right. You didn't. Your code set the popup parent to be the application handle. But we were previously talking about making the main form the popup parent. You even had a potldt claiming to have done this but then your code told a different story. 

     

    1 hour ago, McScotty said:

    I really want to know why setting WndParent corrects a bug in the taskbar thumbnail that a standard Delphi application suffers from ordinarily if the dialog is not destroyed.

    It doesn't. Setting WndParent doesn't fix your issue. It is setting WndParent to be the application handle that changes the behaviour. The reason that it changes the behaviour is that with application handle as popup parent then the dialog is not made visible when the main form is made visible. But, as I have explained before, if the application handle is the popup parent then the system won't guarantee that the dialog is always in front of the main form. 

     

    I think I've said this a few times before, but I do believe that it's important to understand what popup parent does, and why it is important. My advice to you is to do some research on what popup parent actually is and why it is important to set it, with particular focus on modal dialogs. 


  9. 18 hours ago, McScotty said:

    Yes sure.  Example 1 is the one with the issue on the taskbar, run the code and click on button then OK dialog.  hover mouse over taskbar and then the thumbnail image and you will see the closed (hidden) dialog is now visible, but will disappear again if you click on the thumbnail.

     

    Example 2 is the same code, but the dialog has been modified to override the create process by adding Params.WndParent:=application.Handle;  Run the code as above and voila, no dialog is shown in the taskbar.

    Example1.zip

    Example2.zip

     

    20 hours ago, McScotty said:

    My understanding of the PopUpParent is that I can use it or I can use CreateParams and set the WndParent myself which results as the same thing.

     

    If I set the PopUpParent to the main form it appears correctly, but still suffers from the showing the dialog in the thumbnail preview.

     

    However if I use CreateParams and set 

     

    Params.WndParent:=application.Mainform.Handle;

     

    This does not suffer from the issue with the thumbnails.  Why is it behaving differently?

     

    There seems to be some confusion.

     

    You asked about why setting PopupParent to be the main form resulted in different behaviour from setting WndParent to the main form handle in CreateParams.

     

    However, the two example projects you provided did not differ in that way.  In those projects the only difference is that one of them sets WndParent to be the application handle.  And you'd expect different behaviour in that case.


  10. On 10/26/2019 at 8:34 AM, Stefan Glienke said:

    You only ever have to worry about dropping the TRttiContext when you unload modules such as dll and bpl during your application livetime from whom you needed rtti because then the type information from those modules is not removed and might still hang around possibly causing some issues.

    You don't need to worry about even that because the dynamic memory associated with RTTI is ref counted and the refs will go to zero when the module is unloaded. 


  11. You don't want to make the application window the popup parent. Then your dialog can appear behind the main form. You want the main form to be the popup parent. Which you can do in CreateParams, or by setting PopupParent.

     

    It's important that you understand what popup parent aka Window owner in Windows terminology means. At the moment you seem to be trying stuff without understanding it. 

     

    I think I already explained that destroying the window is the key to getting the behaviour you want. I gave you two options for doing that. 

    • Like 2
×