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

时间:2017-05-19 10:56:22

标签: winapi mouseevent popupwindow user32 hwnd

我遇到了一个恼人的问题。当鼠标指针位于我的主窗口上方并显示拥有的弹出窗口(参见下面的示例)或使其不可见时,即使鼠标尚未移动,每次都会生成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以来鼠标位置是否发生了变化。如果位置没有改变,那一定是因为显示/隐藏了弹出窗口或者释放了一些窗口捕获。

1 个答案:

答案 0 :(得分:0)

基于此处提供的信息(谢谢@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
    }