显示/隐藏弹出窗口后防止生成 WM_MOUSEMOVE

Posted

技术标签:

【中文标题】显示/隐藏弹出窗口后防止生成 WM_MOUSEMOVE【英文标题】:Prevent generation of WM_MOUSEMOVE after popup window is shown/hidden 【发布时间】:2017-10-19 11:28:18 【问题描述】:

我遇到了一个烦人的问题。当鼠标指针位于我的主窗口上并显示拥有的弹出窗口(参见下面的示例)或使其不可见时,即使鼠标没有移动,每次都会生成 WM_MOUSEMOVE 消息。由于几个原因,在我的情况下它不能被容忍。

    hWnd = CreateWindowEx(0, wcx.lpszClassName, L"Demo", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, 0, hInstance, nullptr);
    HWND hWndPopupTest = CreateWindowEx(WS_EX_NOACTIVATE | WS_EX_TOPMOST, L"Static", L"DemoPopup", WS_POPUP | WS_VISIBLE, 10, 10, 100, 100, hWnd, 0, hInstance, nullptr);
    ShowWindow(hWnd, SW_SHOW);
    ShowWindow(hWndPopup, SW_SHOWNOACTIVATE);
    Sleep(1000);
    ShowWindow(hWndPopup, SW_HIDE);

调用ReleaseCapture 时会发生相同的行为。这是可以禁用的功能吗?这是一个已知的“问题”还是有解决方法?

编辑:肮脏的解决方法

在(主)窗口过程中,我们可以测试鼠标位置自上次WM_MOUSEMOVE 以来是否发生了变化。如果位置没有改变,那一定是因为显示/隐藏了弹出窗口或释放了某个窗口捕获。

【问题讨论】:

无法禁用。实际上很重要,它确保光标形状正确。你必须解决它。 这种行为是否记录在某处? Why do I get spurious WM_MOUSEMOVE messages?、Sure, I can get spurious WM_MOUSEMOVE messages, but why do they keep streaming in? 和 Why do I get a spurious WM_MOUSEMOVE message whenever Resource Manager is running?。 【参考方案1】:

根据此处提供的信息(谢谢@IInspectable),我的一般解决方案是通过使用GetMouseMovePointsEx 查看鼠标位置历史记录来检测给定点是否为真实点。如果没有找到点,则表示没有发生有效的移动。

    POINT CurrentPointGET_X_LPARAM(lParam), GET_Y_LPARAM(lParam);
    MapWindowPoints(hWnd, nullptr, &CurrentPoint, 1);
    MOUSEMOVEPOINT mmpi = 
        CurrentPoint.x, CurrentPoint.y, GetTickCount(), 0
    ;
    MOUSEMOVEPOINT mmpo = 0;
    if (GetMouseMovePointsEx(sizeof(mmpi), &mmpi, &mmpo, 1, GMMP_USE_DISPLAY_POINTS) > 0) 
        MyInstance->HandleMouseMove(POINTGET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), wParam);
     else 
        // No mouse point found in history, so couldn't be a valid point
    

【讨论】:

以上是关于显示/隐藏弹出窗口后防止生成 WM_MOUSEMOVE的主要内容,如果未能解决你的问题,请参考以下文章

达到固定宽度后防止在表格单元格上输入?

使用maven运行测试后防止数据被删除

在用户注销后防止浏览器的后退按钮显示安全数据的最简单方法是啥?

点击链接后防止 UIWebView 滚动

添加换行符后防止 chrome 中的 textarea 滚动行为

双击后防止文本选择