Scrolling the Window Under the Mouse

帅比萌擦擦* 提交于 2019-11-30 22:45:13

Apparently we can address this issue at the heart of the program. Look at your code for the message loop, which should be in your WinMain method:

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

Here, we just need to say that if the message is a WM_MOUSEWHEEL message, that we want to pass it to the window under the mouse, and not the focus window:

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);
    }
}

And now, the window under your mouse will always get scroll messages, and not the focused window.

Handle the WM_MOUSEWHEEL message in both the parent and in child windows that should receive the message.

Do something like this in your WM_MOUSEWHEEL handler for your child window:

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

Then in the WM_MOUSEWHEEL handler for your parent window you do:

    POINT mouse;

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

    SendMessage(hwnd, message, wParam, lParam);

This way, if the child window has focus, the other window that actually has the mouse pointer hovering over it will receive the WM_MOUSEWHEEL message.

I found out that it is much simpler to override the PreTranslateMessage function in you app class.

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

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

    return CWinApp::PreTranslateMessage(pMsg);
}

Hope that it will help someone.

Just a modification of the previous answer. Mouse coordinates embedded in the message should be used instead of the current ones, they may differ if the message processing is delayed.

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);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!