It's not that the frame doesn't have a message queue — it's threads that have message queues, not windows — but that the frame doesn't yet have a window handle. The window handle is most likely only created when the frame is first shown, unless you post it a message, in which case the window is created on demand.
If you attempt to post a message to it, you probably have a statement like this: PostMessage(Frame2.Handle, ...)
.
Reading the Handle
property of a component will cause that component to create its window, if it doesn't already have a handle. When that happens in your secondary thread, then the frame's window is created belonging to that secondary thread. That can lead to any number of problems down the line. Like all VCL windows, the frame's window needs to belong to the main, VCL thread.
Even if you ensure that the frame's handle is created in the main thread before you direct messages to it (such as by calling HandleNeeded
in the main thread), there's still a chance that reading the frame's Handle
property will cause problems. This is because a VCL control might re-create its window. Then, once again, reading the Handle
property may trigger creation of the frame's window in the wrong thread.
The safe technique is for the frame to to call AllocateHWnd
to create a dedicated message-only window. Do that in the frame's constructor so it's guaranteed to happen in the main thread, and then post messages there. When you create the window, you'll provide a callback method that will be called any time that window receives a message. That callback method should belong to the frame control so that it has access to all the fields and methods of the frame it's associated with.