The only thing that leaves me wondering is whether PostMessage() works differently on some systems or is there something else..
.
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).
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
function Driver4Calc(p: pointer): ptrint;
var
ldata: TSData;
i,res: ptruint;
begin
ldata:= PSData(p)^;
...
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)
...
System.New(p);
p^.sdHandleMain := Handle;
p^.sdHandlePrg := frmProgress.Handle;
p^.sdCaption := GetStr(0);
...
BeginThread(Driver4Calc,p);
...
procedure Tform_artistflo.LmThreadFinished(var aMsg: TLMessage);
begin
PostMessage(frmProgress.Handle,LM_ThreadHidePrg,0,aMsg.lParam);
PostMessage(frmProgress.Handle,LM_ThreadClosePrg,0,aMsg.lParam);
end;
procedure TfrmProgress.LmThreadClosePrg(var aMsg: TLMessage);
begin
Dispose( PSData(aMsg.lParam) );
end;
I hope I didn't get the idea wrong and it can be useful.