我是WINAPI的初学者,一直在努力了解Windows消息传递系统。
虽然我已经了解到WinMain中的GetMessage函数接收到发送给程序的所有消息,但我无法理解API如何向控件(例如按钮)发送消息,表明用户已单击该消息?我已经浏览了大量的页面,并且无法找到确切的消息序列,从应用程序线程的消息队列开始直到按钮控件。
我希望问题不是太多"愚蠢"值得回答。相信我,我已经经历了大量的网页,包括MSDN,我无处可寻找一个直截了当的答案。我真的很感谢有人指着我正确的方向。
答案 0 :(得分:7)
当发生鼠标事件时,Windows搜索桌面上的所有窗口以查找当前在光标下的窗口。如果光标下有多个重叠的窗口,它会选择最顶层的窗口。子窗口通常位于其父窗口的顶部,因此此搜索优先于其父窗口上的子窗口。 Windows然后将鼠标事件消息发布到它找到的窗口的消息队列中。
创建窗口的程序应该在创建窗口的线程中运行某种消息循环。此循环通常会调用GetMessage
逐个将消息拉出队列。这些消息依次传递给DispatchMessage
,WM_COMMAND
查看消息,找出应该发送到哪个窗口。然后它通过调用窗口过程将消息传递给窗口。
因此,当您单击按钮控件时,鼠标事件将被分派到控件的Windows过程。控件的父窗口未通知,至少不直接通知。该按钮将生成一些消息,其中一些消息发送给自己,一些消息发送给它的父节点。值得注意的是,它会发送一条WM_LBUTTONDOWN
消息,让其父母知道它已被点击。
单击顶级对话框中的按钮时发生的特定消息序列如下:
BM_SETSTATE
:当鼠标点击鼠标时,Windows将其发布到按钮上。
WM_CTLCOLORBTN
:通过按钮发送,告诉自己在推送状态下绘制自己。这使子类控件有机会进行自己的绘制。
WM_LBUTTONUP
:通过按钮发送到其父级,以找出应该绘制的画笔,然后忽略它。但是,此消息允许父级在绘制消息之前更改消息的文本。BM_SETSTATE
:释放鼠标按钮时由Windows发布到按钮。
WM_CTLCOLORBTN
:通过按钮发送,告诉自己在未按下状态下绘制自己。
WM_CAPTURECHANGED
:之前已发送并被忽略WM_COMMAND
:由Windows发送到按钮,告诉它不再捕获鼠标。当按钮接收到鼠标按钮消息时,按钮捕获了鼠标,因此即使指针不再位于按钮上,也会通知按钮被释放。缩进表示响应消息而发送消息的位置。发布的消息在被分派到处理它们的窗口过程之前通过消息队列。已发送的消息将直接发送到处理它们的Windows过程,而无需通过队列。