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