I am developing an application with multithreading (RAD Studio XE5). At the start of the application I create a single thread that will live as long as the main form does.
I am able to dispatch messages from the thread to any form that has been created in my application, however I can't find a way to do the opposite, sending a message from the main VCL thread to the worker thread.
When creating the main form I create the worker thread and copy the handle in a public variable:
serverThread := TMyThread.Create(True, ServerPort + 1);
serverThreadHandle := serverThread.Handle; // SAVE HANDLE
serverThread.Start;
then (from a different form FrmSender) I dispatch a message to the thread:
PostMessage(uMain.serverThreadHandle, UM_LOC_VCLMSG, UM_LOC_VCLMSG, Integer(PStrListVar));
This is the thread's Execute procedure:
procedure TMyThread.Execute;
var
(..)
vclMSG : TMsg;
str1, str2 : string;
(..)
begin
while not(Terminated) do
begin
Sleep(10);
if Assigned(FrmSender) then
if FrmSender.HandleAllocated then
if PeekMessage(vclMSG, FrmSender.Handle, 0, 0, PM_NOREMOVE) then
begin
if vclMSG.message = UM_LOC_VCLMSG then
begin
try
pStrListVar := pStrList(vclMSG.lParam);
str1 := pStrListVar^.Strings[0];
str2 := pStrListVar^.Strings[1];
finally
Dispose(pStrListVar);
end;
end;
end;
(.. do other stuff ..)
end;
end;
However PeekMessage() never returns true as if it was never receiving any message. I've tried changing the parameters to PeekMessage():
PeekMessage(vclMSG, 0, 0, 0, PM_NOREMOVE);
But with no results. Any ideas?
From MSDN PostMessage
function documentation:
Places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.
To post a message in the message queue associated with a thread, use the PostThreadMessage function.
Thus, you should use PostThreadMessage
:
Posts a message to the message queue of the specified thread. It returns without waiting for the thread to process the message.
Give special attention to the Remarks section. The recipient thread needs a message queue. Force the thread having one by following these steps:
WaitForSingleObject
function to wait for the event to be set to the
signaled state before calling PostThreadMessage
.In the thread to which the message will be posted, call PeekMessage
as shown here to force the system to create the message queue.
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE)
Set the event, to indicate that the thread is ready to receive posted messages.
Then, when using PeekMessage
, you pass a handle value of -1
to the function, as documented.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With