滚动鼠标下的窗口

时间:2013-11-28 01:06:12

标签: c++ windows winapi mouseevent messages

如果您查看Visual Studio 2012,您会注意到如果使用鼠标滚轮,鼠标下方的窗口将滚动,而不是聚焦窗口。也就是说,如果您将光标放在代码编辑器中,并将鼠标移到“解决方案资源管理器”窗口并滚动,则解决方案资源管理器将滚动,而不是代码编辑器。但是,WM_MOUSEWHEEL消息只会被发送到焦点窗口,因此在这种情况下,代码编辑器。我们如何实现我们的程序,以便WM_MOUSEWHEEL消息滚动鼠标下的窗口,这是直观的,而不是聚焦窗口?

4 个答案:

答案 0 :(得分:6)

显然,我们可以在该计划的核心问题上解决这个问题。查看消息循环的代码,该代码应该在WinMain方法中:

while (GetMessage (&msg, NULL, 0, 0) > 0)
{
    TranslateMessage (&msg);
    DispatchMessage (&msg);
}

在这里,我们只需要说明如果消息是WM_MOUSEWHEEL消息,我们要将它传递给鼠标下的窗口,而不是焦点窗口:

POINT mouse;

while (GetMessage (&msg, NULL, 0, 0) > 0)
{
    //Any other message.
    if (msg.message != WM_MOUSEWHEEL)
    {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    }
    //Send the message to the window over which the mouse is hovering.
    else
    {
        GetCursorPos (&mouse);
        msg.hwnd = WindowFromPoint (mouse);
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    }
}

现在,鼠标下的窗口将始终显示滚动消息,而不是聚焦窗口。

答案 1 :(得分:2)

在应该接收消息的父窗口和子窗口中处理WM_MOUSEWHEEL消息。

在子窗口的WM_MOUSEWHEEL处理程序中执行以下操作:

    POINT mouse;
    GetCursorPos(&mouse);
    if (WindowFromPoint(mouse) != windowHandle)
    {
        // Sends the WM_MOUSEWHEEL message to your parent window
        return DefWindowProc(windowHandle, message, wParam, lParam);
    }

然后在父窗口的WM_MOUSEWHEEL处理程序中执行:

    POINT mouse;

    GetCursorPos(&mouse);
    HWND hwnd = WindowFromPoint(mouse);

    SendMessage(hwnd, message, wParam, lParam);

这样,如果子窗口具有焦点,则实际上鼠标指针悬停在其上的另一个窗口将收到WM_MOUSEWHEEL消息。

答案 2 :(得分:2)

我发现在你的app类中覆盖PreTranslateMessage函数要简单得多。

BOOL MyApp::PreTranslateMessage(MSG* pMsg)
{
    POINT mouse;
    CWnd* windowUnderMouse;

    if (pMsg->message == WM_MOUSEWHEEL)
    {
        GetCursorPos(&mouse);       
        pMsg->hwnd = WindowFromPoint(mouse);
    }

    return CWinApp::PreTranslateMessage(pMsg);
}

希望它能帮助别人。

答案 3 :(得分:0)

只是对先前答案的修改。 应该使用嵌入消息中的鼠标坐标代替当前的鼠标坐标,如果延迟消息处理,它们可能会有所不同。

BOOL CMyApp::PreTranslateMessage (MSG* pMsg)
{
    if (pMsg -> message == WM_MOUSEWHEEL)
        pMsg -> hwnd = WindowFromPoint (CPoint (GET_X_LPARAM (pMsg -> lParam), GET_Y_LPARAM (pMsg -> lParam)));

    return CWinAppEx::PreTranslateMessage (pMsg);
}