Manish
Manish

Reputation: 87

When a user clicks a mouse button on a control, how does the message get to that control?

I am a beginner with WINAPI and have been trying to understand the Windows messaging system.

While I have learnt that the GetMessage function in WinMain receives all messages sent to a program, I am unable to grasp as to how the API sends a message to a control (say a pushbutton) that it has been clicked by a user? I have gone through tons of pages and am not able to find the exact sequence of messages, starting from the application thread's message queue upto the pushbutton control.

I hope the question is not too "stupid" to merit an answer. Believe me, I have gone through tons of webpages, including MSDN and nowhere am I able to find a straightforward answer. I would really appreciate someone pointing me in the right direction.

Upvotes: 2

Views: 1913

Answers (1)

Ross Ridge
Ross Ridge

Reputation: 39591

When a mouse event occurs Windows searches all the windows on the desktop to find the window that's currently under the cursor. If multiple overlapping windows are under the cursor it picks the topmost window. Child windows are normally on top of their parent window, so this search prefers child windows over their parent window. Windows then posts a mouse event message to the message queue of the window it found.

The program that created the window should have some sort of message loop running in the thread that created the window. This loop normally calls GetMessage to pull messages out of the queue one by one. These messages are passed in turn to DispatchMessage which looks at the message find out which window it should be sent to. It then passes the message to the window by calling its window procedure.

So when you click on a push button control the mouse events are dispatched to the windows procedure for the control. The parent window of the control isn't notified, at least not directly. The button will generate a number of messages as result, some sent to itself, some to its parent. Notably it will send a WM_COMMAND message to let its parent know its been clicked.

The specific sequence of messages that happen when clicking on push button in a top level dialog box is something like:

  • WM_LBUTTONDOWN: Posted by Windows to the push button when the mouse is clicked over it.
    • BM_SETSTATE: Sent by the push button to tell itself to draw itself in the pushed state. This give subclassed controls an opportunity to do their own drawing.
      • WM_CTLCOLORBTN: Sent by the push button to its parent to find out what brush it should be drawn with, which it then ignores. This message does however allow the parent to change the text of the message before its drawn.
  • WM_LBUTTONUP: Posted by Windows to the push button when the mouse button is released.
    • BM_SETSTATE: Sent by the push button to tell itself to draw itself in the unpushed state.
      • WM_CTLCOLORBTN: Sent and ignored as previously
    • WM_CAPTURECHANGED: Sent by Windows to the push button telling it that it's no longer capturing the mouse. The push button captured the mouse when it received the mouse button down message so it would be notified of the button being released even if the pointer was no longer over the push button.
    • WM_COMMAND: Sent to the parent to notify it that the push button has been clicked.

Indentation indicates where messages have been sent in response to a message. Posted messages go through the message queue before being dispatched to the window procedure that handles them. Sent messages are sent directly to the windows procedure that process them without going through the queue.

Upvotes: 10

Related Questions