关于Winapi:拖动Windows标题栏进行间谍

Spying while dragging the windows title bar

我们假设单击普通的WS_OVERLAPPEDWINDOW窗口的标题栏,然后单击几下鼠标并释放按钮。

从Spy获得的消息摘要:

WM_SYSCOMMAND(SC_MOVE)

WM_MOUSEMOVE(*)

WM_CAPTURECHANGED

WM_ENTERSIZEMOVE

WM_MOUSEMOVE(*)



WM_MOUSEMOVE(*)

WM_LBUTTONUP(*)

WM_CAPTURECHANGED

WM_EXITSIZEMOVE

WM_SYSCOMMAND(返回)

我试图用(*)理解消息。因为:p

1)鼠标移动和按钮释放不在窗口客户区域中。因此,我应该拥有WM_NCMOUSEMOVE和WM_NCLBUTTONUP,而不是WM_MOUSEMOVE和WM_LBUTTONUP。

2)如果我在窗口过程中在这些消息(WM_MOUSEMOVE和WM_LBUTTONUP)上稍作休息,则在拖动窗口标题栏时不会拦截这些消息!


1) The mouse movements and the button release are NOT in the window client area. Therefore, instead of WM_MOUSEMOVE and WM_LBUTTONUP, I should have WM_NCMOUSEMOVE and WM_NCLBUTTONUP.

我不确定这一点,但是我可以猜到:也许系统总是发送WM_MOUSEMOVE,并且在此过程中某处将其转换为WM_NCMOUSEMOVE(取决于WM_NCHITTEST的结果)。铅>

在拖动操作期间,您的应用程序无论如何都不会看到这些消息(如您??所注意到的),因此进行转换毫无意义。

2) If I put a break, on those messages (WM_MOUSEMOVE and WM_LBUTTONUP), in my window procedure, I don't intercept theses mesages while dragging the window's title bar !!!

请记住,WM_MOUSEMOVE和朋友是发布而不是发送的。这意味着它们通常会流过您自己的消息循环,并通过DispatchMessage到达您的窗口过程。

开始拖动窗口时,应用程序进入所谓的模式消息循环。直到完成拖动操作,该循环才会返回,因此直到那时,您自己的消息循环才会运行! WM_ENTERSIZEMOVEWM_EXITSIZEMOVE消息分别在进入和退出模态循环时发送到窗口过程。

现在,可能是模态循环也向您的窗口过程发送了消息;但是(至少对于WM_MOUSEMOVE而言)不是。而且不应该这样,因为模态循环本身正在处理这些消息-将它们传递给winproc可能会引起混乱。