我有一个处理 WM_NCLBUTTONUP 消息的窗口,以便处理标题栏中自定义按钮的点击。当窗口最大化时,这非常有效,但当窗口未最大化时,WM_NCLBUTTONUP 消息永远不会到达!不过我确实收到了 WM_NCLBUTTONDOWN 消息。奇怪的是,如果我单击菜单栏的右侧,WM_NCLBUTTONUP 确实会到达,但沿着标题栏/窗口框架的任何位置,消息永远不会到达。
经过一段时间的调试,我发现如果我在 CMainFrame::OnNcLButtonDown() 上设置断点,单击标题栏,但按住鼠标按钮,让调试器在函数中中断,按 F5 继续调试,然后释放鼠标按钮 - 神奇地发送了 WM_NCLBUTTONUP!
我的问题有两个:(1)到底发生了什么? (2)我如何解决这个“问题”。
我还注意到互联网上还有其他几个人也有同样的问题(快速谷歌显示很多其他人也有同样的问题,但没有解决方案)。
Edit
感谢前两个回复,我尝试在NCLButtonDown中调用ReleaseCapture,但没有效果(实际上,它返回NULL,表明捕获不到位)。我只能假设基类(def window proc)功能可以设置捕获。我周一去调查一下...
我也遇到过同样的问题。问题确实是,左键单击窗口标题会开始拖动,从而导致鼠标捕获,从而阻止 WM_NCLBUTTONUP 到达。
解决方案是重写 WM_NCHITTEST:
LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
switch (nMsg)
{
...
case WM_NCHITTEST:
Point p(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam);
ScreenToClient(p);
if (myButtonRect.Contains(p))
{
return HTBORDER;
}
break;
}
return DefWindowProc(hWnd, nMsg, wParam, lParam);
}
因此,本质上,您通知 Windows 您的按钮占用的区域不是窗口标题的一部分,而是非客户区域 (HTBORDER) 的非特定部分。
脚注:如果您在期望 WM_NCLBUTTONDOWN 消息传入时调用了 SetCapture() 但尚未调用 ReleaseCapture(),则即使进行了上述更改,该消息也不会到达。这可能会令人恼火,因为在与此类自定义按钮交互期间捕获鼠标是正常的,这样如果鼠标离开窗口,您就可以取消单击/突出显示。但是,作为使用捕获的替代方法,您可以考虑使用短间隔(例如 100 毫秒)的 SetTimer()/KillTimer(),这不会导致 WM_NCLBUTTONUP 消息消失。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)