让我们假设点击一个普通的WS_OVERLAPPEDWINDOW窗口的标题栏,然后点击几个鼠标拖动和一个按钮释放。
从间谍获得的消息摘要:
WM_SYSCOMMAND(SC_MOVE)
WM_MOUSEMOVE(*)
WM_CAPTURECHANGED
WM_ENTERSIZEMOVE
WM_MOUSEMOVE(*)
。 。
WM_MOUSEMOVE(*)
WM_LBUTTONUP(*)
WM_CAPTURECHANGED
WM_EXITSIZEMOVE
WM_SYSCOMMAND(返回)
我正在尝试用(*)来理解这些消息。从那以后,它们对我没有意义:
1)鼠标移动和按钮释放不在窗口客户区。因此,我应该有WM_NCMOUSEMOVE和WM_NCLBUTTONUP,而不是WM_MOUSEMOVE和WM_LBUTTONUP。
2)如果我在这些消息(WM_MOUSEMOVE和WM_LBUTTONUP)上休息,在我的窗口过程中,我不会在拖动窗口的标题栏时拦截这些消息!!!
答案 0 :(得分:0)
1)鼠标移动和按钮释放不在窗口客户区。因此,我应该有WM_NCMOUSEMOVE和WM_NCLBUTTONUP,而不是WM_MOUSEMOVE和WM_LBUTTONUP。
我不确定这个,但我可以猜测:也许系统总是发送WM_MOUSEMOVE
,并且在此过程中某处转换为WM_NCMOUSEMOVE
(取决于{{的结果) 1}})。
在拖动操作期间,您的应用程序无论如何都无法看到这些消息(正如您所注意到的那样),因此进行转换毫无意义。
2)如果我在这些消息(WM_MOUSEMOVE和WM_LBUTTONUP)上休息,在我的窗口过程中,我不会在拖动窗口的标题栏时拦截这些消息!!!
回想一下WM_NCHITTEST
和朋友已发布,未发送。这意味着它们通常会流经您自己的消息循环,并通过WM_MOUSEMOVE
到达您的窗口过程。
当您开始拖动窗口时,应用程序会进入所谓的模态消息循环。在拖动完成之前,此循环不会返回,因此在此之前,您自己的消息循环将无法运行!在分别输入和退出模态循环时,DispatchMessage
和WM_ENTERSIZEMOVE
消息将被发送到窗口过程。
现在,可能是模态循环也会将消息调度到您的窗口过程;但是(至少WM_EXITSIZEMOVE
等)它没有。它不应该,因为模态循环本身正在处理这些消息 - 将它们传递给winproc可能会引起混淆。