Recent

Author Topic: [SOLVED] progress dialog with blocked message queue  (Read 1715 times)

Phoenix

  • Full Member
  • ***
  • Posts: 135
Re: [SOLVED] progress dialog with blocked message queue
« Reply #15 on: December 08, 2025, 10:21:09 pm »
I can confirm that the idea seems to work, with just a few changes to your implementation  ;).

The only thing that leaves me wondering is whether PostMessage() works differently on some systems or is there something else..  :o.

cdbc

  • Hero Member
  • *****
  • Posts: 2571
    • http://www.cdbc.dk
Re: [SOLVED] progress dialog with blocked message queue
« Reply #16 on: December 09, 2025, 11:18:05 am »
Hi Phoenix
Cool  8-) Glad you got my half-baked project to abide  8)
Your version works as advertised here on PCLinuxOS - KDE6 - QT6 - FPC release - Lazarus release.
You can ofc. create an ordinary 'TThread' descendant, with all its Bells & Whistles, instead of my raw /old-school/ approach -- It was quicker --
In that case remember to loose the "EndThread(0);" call in the thread-func, 'cause it'll screw things up, due to 'TThread' being 'joined' at the end internally.
This was more about the 'Comms' anyway...  ;D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Phoenix

  • Full Member
  • ***
  • Posts: 135
Re: [SOLVED] progress dialog with blocked message queue
« Reply #17 on: December 09, 2025, 12:32:03 pm »
Hi Benny, thank you very much  :D

Xenno

  • New Member
  • *
  • Posts: 49
    • BS Programs
Re: [SOLVED] progress dialog with blocked message queue
« Reply #18 on: December 09, 2025, 02:05:56 pm »
This is plainly not true, at least on Windows. It blocks the thread it is running in, usually the main thread completely, not only GUI elements.

I've attached a project to demonstrate the behavior I mentioned.

The project has two forms. Form 1 contains a running Timer and a counter display. When Form 2 is shown using ShowModal, the timer on Form 1 continues to run, and the counter updates in the background.

This suggests that Form 1 is not completely blocked.

I apologize for the necessary clarification, @Phoenix.
Lazarus 4.0, Windows 10, https://www.youtube.com/@bsprograms

Phoenix

  • Full Member
  • ***
  • Posts: 135
Re: [SOLVED] progress dialog with blocked message queue
« Reply #19 on: December 09, 2025, 04:48:37 pm »
I apologize for the necessary clarification, @Phoenix.

Even if the problem is solved, any additional information enriches the forum, so it's always welcome; no need to apologize  :). Thanks.

Phoenix

  • Full Member
  • ***
  • Posts: 135
Re: [SOLVED] progress dialog with blocked message queue
« Reply #20 on: December 10, 2025, 09:30:21 am »
The only thing that leaves me wondering is whether PostMessage() works differently on some systems or is there something else..  :o.

Using Sleep() cured the symptom, not the cause.

I moved the test code to the real application, and when I wanted to add a string field to TSData, I ran into a memory leak that I initially found absurd (even using UniqueString() failed).
To resolve this and avoid having to use Sleep() in TfrmMain.btnCalcClick(), the @lrec pointer shouldn't be passed. Instead, it should be created with GetMem() or New (in my case) and then freed with FreeMem() or Dispose (in my case) when you're finished using it (just use the last message sent to the dialog, or better yet, add a specific one at the end).

Quote
procedure TfrmMain.btnCalcClick(Sender: TObject);
var lrec: TSData;
begin             
  lrec.sdHandleMain:= Handle;
  lrec.sdHandlePrg:= frmProgress.Handle;
  lrec.sdI:= 3;
  if (Sender as TButton).Tag = 0 then
   lrec.sdN:= 10*1000*1000
  else
   lrec.sdN:= 10*1000;
  fRunning:= true;
  BeginThread(@Driver4Calc,@lrec); <----
  PostMessage(frmProgress.Handle,LM_ThreadShowPrg,1,1);
  btnCalc.Enabled:= false;
  btnCalc1.Enabled:= false;
  btnClose.Enabled:= false;
end;

Probably when running on Windows the var lrec is removed from the stack before the method on the thread creates its copy

Code: Pascal  [Select][+][-]
  1. function Driver4Calc(p: pointer): ptrint;
  2. var
  3.   ldata: TSData;
  4.   i,res: ptruint;
  5. begin
  6.   ldata:= PSData(p)^;
  7.   ...
  8.  

which I assume is in turn the source of the memory leak identified

now in my source i am using something like this and it works without mandatory sleep (For my use I changed the parameters in the messages but in practice even Driver4Calc() only uses pointers now)

Code: Pascal  [Select][+][-]
  1.  ...
  2.  System.New(p);
  3.  p^.sdHandleMain  := Handle;
  4.  p^.sdHandlePrg   := frmProgress.Handle;
  5.  p^.sdCaption     := GetStr(0);
  6.  ...
  7.  BeginThread(Driver4Calc,p);
  8.  ...
  9.  
  10.  procedure Tform_artistflo.LmThreadFinished(var aMsg: TLMessage);
  11.  begin
  12.   PostMessage(frmProgress.Handle,LM_ThreadHidePrg,0,aMsg.lParam);
  13.  
  14.   PostMessage(frmProgress.Handle,LM_ThreadClosePrg,0,aMsg.lParam);
  15.  end;
  16.  
  17.  procedure TfrmProgress.LmThreadClosePrg(var aMsg: TLMessage);
  18.  begin
  19.   Dispose( PSData(aMsg.lParam) );
  20.  end;
  21.  

I hope I didn't get the idea wrong and it can be useful.

Thaddy

  • Hero Member
  • *****
  • Posts: 18703
  • To Europe: simply sell USA bonds: dollar collapses
Re: [SOLVED] progress dialog with blocked message queue
« Reply #21 on: December 10, 2025, 10:19:34 am »
The only thing that leaves me wondering is whether PostMessage() works differently on some systems or is there something else..  :o.
PostMessage is fire and forget, no guaranteed delivery. SendMessage should block until received, tries guaranteed delivery.
Progress thingies should only use Post, not send: it is not critical to any processing, accuracy should really not matter: it is an indication, not a real world representation.

The two patterns are usually always implemented in this way, but there can of course be exceptions to the rule or mistakes in implementation or even impossible to implement both.
« Last Edit: December 10, 2025, 10:28:24 am by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

Phoenix

  • Full Member
  • ***
  • Posts: 135
Re: [SOLVED] progress dialog with blocked message queue
« Reply #22 on: December 10, 2025, 10:35:32 am »
The only thing that leaves me wondering is whether PostMessage() works differently on some systems or is there something else..  :o.
PostMessage is fire and forget, no guaranteed delivery. SendMessage should block until received, tries guaranteed delivery.
Progress thingies should only use Post, not send: it is not critical to any processing, accuracy should really not matter: it is an indication, not a real world representation.

The two patterns are usually always implemented in this way, but there can of course be exceptions to the rule or mistakes in implementation or even impossible to implement both.

So in LmThreadFinished() I absolutely have to use SendMessage() since the Hide and Dispose must be executed, and I also have to make sure the message appears.
Very interesting to know, thanks a lot, thaddy  :)!

cdbc

  • Hero Member
  • *****
  • Posts: 2571
    • http://www.cdbc.dk
Re: [SOLVED] progress dialog with blocked message queue
« Reply #23 on: December 10, 2025, 11:02:16 am »
Hi
Whooopsiiiie, Sorry mate, my bad -- I forgot to tell you about 'Post-' vs 'SendMessage'  :-[
Good thing we've got Thaddy, explained clear and to the point, thanks mate =^
...and yup, to start a thread, takes 0..2 msecs, I should have thought of that  :(
Buhuuuu... I must be getting old  ;D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Phoenix

  • Full Member
  • ***
  • Posts: 135
Re: [SOLVED] progress dialog with blocked message queue
« Reply #24 on: December 10, 2025, 11:14:23 am »
usually if there are no bugs that is a problem  :D :D

 

TinyPortal © 2005-2018