From all these different types of messages, only posted messages go directly into the private message queue. Sent messages are queued separately and the sender sleeps until it gets a reply. A timer event is raised when one of the queue timers expire. Depending on the timer parameters DispatchMessage either calls the callback function or the window procedure. In the first case we lose correct message ordering, in the second case we have the infamous synchronous system message queue.
Every possible solution creates a different problem.
With a windowing system, events can go to many different windows. So far, no problem. Whenever an event happens, you put a message on the target window's message queue. Every process has a message queue. If the process queue fills up, the messages back up onto the system queue.