(08-07-2018, 03:10 AM)kbriggs Wrote: Uh oh. I have this defined in the public declarations section of my main form's class:
procedure SyncMessage(var Msg: TMessage); message WM_User + 2;
and then call it from a worker thread:
PostMessage(MainForm.Handle, WM_User + 2, Mask, 0);
Am I doing that wrong?
Not so much "wrong" as just "unsafe".
If the VCL happens to recreate the MainForm's HWND (and you have no control over when the VCL recreates its HWNDs - recreations happen more often than you might think) at the exact moment that you call PostMessage(), really bad things can happen. Not the least of which is that you can completely kill your UI.
An HWND has thread affinity, it functions correctly only in the thread that creates it. During a VCL control's window recreation, its HWND gets destroyed and set to 0. When the TWinControl.Handle property getter sees that, it allocates a new HWND before returning. So, if the main thread destroys the MainForm's HWND, and then the worker thread accesses the Handle property before the main thread has created a new HWND, the new HWND will be created in the context of a worker thread instead, making your MainForm window completely inoperable (worse, there is a race condition on the Handle property, so it is possible, even likely, that the main thread may have also created its own HWND, but the worker thread created an HWND too, leading to one of the two threads leaking resources, depending on which thread "won" the race).
The safer approach is to NEVER use the TWinControl.Handle properly across thread boundaries. Allocate your own HWND, such as with the RTL's AllocateHWnd() function, and then you can safely post messages to that HWND all you want.
(08-07-2018, 03:10 AM)kbriggs Wrote: Process Explorer showed the thread as "TMethodImplementationIntercept" with an 32-bit number on the end that changes each time.
Well, that is definitely NOT an Indy-created thread, so something else in your project is not shutting down correctly.
I've heard of the TMethodImplementationIntercept class, but am not aware of whether it creates a worker thread or not.

