【问题标题】:Prevent generation of WM_MOUSEMOVE after popup window is shown/hidden显示/隐藏弹出窗口后防止生成 WM_MOUSEMOVE
【发布时间】: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 以来是否发生了变化。如果位置没有改变,那一定是因为显示/隐藏了弹出窗口或释放了某个窗口捕获。

【问题讨论】:

标签: winapi mouseevent popupwindow user32 hwnd


【解决方案1】:

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

    POINT CurrentPoint{GET_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(POINT{GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}, wParam);
    } else {
        // No mouse point found in history, so couldn't be a valid point
    }

【讨论】:

    猜你喜欢
    • 2014-08-24
    • 2020-06-12
    • 2012-09-30
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 2020-08-16
    相关资源
    最近更新 更多