How can I implement a message loop within a thread using OTL? Application.ProcessMessages; is what i used so far but it isn\'t very safe to use it.
Thanks
You can build a loop that is similar to the one in Application.Run.
You can call PeekMessage
, which checks if a message is available. PeekMessage checks the message queue of the current thread, so if you use it in your thread, it checks the message queue of the thread (to which you can post messages using PostThreadMessage).
Instead of PeekMessage, you can also use GetMessage
, which waits until a message is received. GetMessage
returns 0 returns false
. *)
when it gets a WM_QUIT
message, which is also the signal to terminate the message loop. It is risky to call GetMessage again after that, since it may not receive another message and it may prevent your application from closing down properly, since it is blocking.
Application.ProcessMessages indeed isn't very safe, because it does a lot of extras that is specific to the main thread. For one, it triggers Application.OnIdle as soon as the message queue is empty, which would mean that it calls that (problem 1) when the thread message queue is empty and (problem 2) in the context of the thread, not allowing any VCL interaction in the event.
*) About the return value of GetMessage: I noticed Delphi implements GetMessage as returning a LongBool. However the actual return value is an integer. It returns 0 in case of WM_QUIT, -1 in case of an error and non-zero in other cases. Microsoft states:
Because the return value can be nonzero, zero, or -1, avoid code like this:
while (GetMessage( lpMsg, hWnd, 0, 0)) ...
Unfortunately, you would have to import GetMessage under a different alias to use it correctly.