当用户单击控件上的鼠标按钮时,消息如何进入该控件?

Man*_*ish 0 winapi

我是WINAPI的初学者,一直在努力了解Windows消息系统.

虽然我已经了解到WinMain中的GetMessage函数接收到发送给程序的所有消息,但是我无法理解API如何向控件(例如按钮)发送消息,表明用户已经点击了该消息?我经历了大量的页面,无法找到确切的消息序列,从应用程序线程的消息队列开始直到按钮控件.

我希望这个问题不是太"愚蠢",值得回答.相信我,我已经经历了大量的网页,包括MSDN,我无处可寻找一个直截了当的答案.我真的很感谢有人指着我正确的方向.

Ros*_*dge 7

当发生鼠标事件时,Windows将搜索桌面上的所有窗口以查找当前位于光标下的窗口.如果光标下有多个重叠的窗口,它会选择最顶层的窗口.子窗口通常位于其父窗口的顶部,因此此搜索优先于其父窗口上的子窗口.Windows然后将鼠标事件消息发布到它找到的窗口的消息队列中.

创建窗口的程序应该在创建窗口的线程中运行某种消息循环.此循环通常会调用GetMessage将消息逐个拉出队列.这些消息依次传递给DispatchMessage消息,查看消息应该发送到哪个窗口.然后通过调用其窗口过程将消息传递给窗口.

因此,当您单击按钮控件时,鼠标事件将被分派到控件的Windows过程.控件的父窗口不会被通知,至少不会直接通知.该按钮将生成一些消息,其中一些消息发送给自己,一些消息发送给它的父节点.值得注意的是,它会发送一条WM_COMMAND消息让其父母知道它被点击了.

单击顶级对话框中的按钮时发生的特定消息序列如下:

  • WM_LBUTTONDOWN:当鼠标单击它时,由Windows发布到按钮.
    • BM_SETSTATE:通过按钮发送,告诉自己在推动状态下绘制自己.这使子类控件有机会进行自己的绘制.
      • WM_CTLCOLORBTN:通过按钮发送到其父级,以找出应该绘制的画笔,然后忽略它.但是,此消息允许父级在绘制之前更改消息的文本.
  • WM_LBUTTONUP:释放鼠标按钮时由Windows发布到按钮.
    • BM_SETSTATE:通过按钮发送,告诉自己在未按下状态下绘制自己.
      • WM_CTLCOLORBTN:像以前一样发送和忽略
    • WM_CAPTURECHANGED:由Windows发送到按钮,告诉它不再捕获鼠标.当按钮接收到鼠标按钮消息时,按钮捕获鼠标,因此即使指针不再位于按钮上,也会通知按钮被释放.
    • WM_COMMAND:发送给父级以通知它已单击按钮.

缩进表示响应消息而发送消息的位置.发布的消息在被分派到处理它们的窗口过程之前通过消息队列.已发送的消息将直接发送到处理它们的Windows过程,而无需通过队列.