windowswinapimessage-queueevent-driven

How is Win32 event-driven programming implemented under the hood?


In a Win32 C++ application, we start a message loop that fetches messages from a queue, translates them and then dispatches them. Eventually, each message reaches our WndProc where the associated event can be handled.

I understand that part. What I don't understand is the in between goings-on. Specifically:

  1. Different kinds of OS interrupt handlers must be placing messages in the said 'message queue', but where within the process address space does this queue reside? How is it exposed to the interrupt handler code?
  2. What does it mean to 'translate' the message? What does the call to TranslateMessage() really do?
  3. Once dispatched by DispatchMessage(), what all places does the message swing by before reaching my WndProc (i.e. what does the OS do with it)?

If anyone knows the answers to the above, kindly satisfy my curiosity. Thanks.


Solution

  • The OS maintains a message queue, where it puts the events (e.g., from interrupts or other sources). It then sends the messages from that queue to all windows, depending on the message (e.g., it won't send key messages to a window that doesn't have focus).

    Applications can have their own queue to process messages. Those queues are created on request (only if needed).

    Translating a message is used to create messages that are not 'real' events. For example, the WM_CONTEXTMENU message is 'translated' from either a mouse right-click, or the context menu key, or shift-F10. The WM_CHAR is translated from WM_KEYDOWN messages. And of course many other messages are 'translated' that way.

    A message is posted to every window that should receive it. The OS decides depending on the type of message whether a window should receive that message or not. Most messages are waited for by the system, i.e., the message won't get posted to another window until it was processed by the window. This has a great impact for broadcast messages: if one window doesn't return when handling that message, the queue is blocked and other windows won't receive the message anymore.