Once a thread has a THREADINFO structure associated with it, the threrad also has its very own set of message queues. If a single process creates three threads and all these threads call CreateWindow, there will be three message queue sets. Messages are placed in a thread's posted-message queue by calling the PostMessage function:
When a threrad calls this function, the system determines which thread created the window identified by the hwnd parameter. The system then allocates a block of memory, stores the message parameters in this block of memory, and appends the block of memory to the appropriate thread's posted-message queue. In addition, the function sets the QS_POSTMESSAGE wake bit. PostMessage returns immediately after posting the message - the calling thread has no idea wheither the posted message was processed by the specified window's procedure. In fact, it is possible that the specified window will never receive the posted message. This couldl happen if the thread that created the specified window were somehow to terminate before processing all of the messages in its queue.
A message can also be placed in a thread's posted-message queue by calling PostTreadMessage:
The desired thread is identified by the first parameter, dwThreadId. When this message is placed in the queue, the hwnd member in the MSG structure will be set to NULL. This function is usually called when an application performs some special processing in its main message loop.
The main message loop for the thread is written so that, after GetMessage or PeekMessage retrieves a message, the code checks for an hwnd of NULL and can examine the msg member of the MSG structure to perform the special processing. If the thread determines that the message is not destined for a window, DispatchMessage is not called, and the message loop iterates to retrieve the next message.
*note* You can determine which thread created a window by calling GetWindowThreadProcessID:
This function returns the system-wide unique ID of the thread that created the window identified by the hwnd parameter. You can also get the system-wide unique ID of the process that owns this thread by passing the address of a DWORD for the pdwProcessId parameter. Usually, we do not need the process ID and simply pass NULL to for this parameter.

