滚动鼠标下的窗口

如果你看看Visual Studio 2012,你会注意到,如果你使用鼠标滚轮,鼠标下的窗口将滚动,而不是焦点窗口。 也就是说,如果您在代码编辑器中有光标,并将鼠标移动到“解决scheme资源pipe理器”窗口并滚动,解决scheme资源pipe理器将滚动,而不是代码编辑器。 WM_MOUSEWHEEL消息,但是,只被发送到聚焦的窗口,所以在这种情况下,代码编辑器。 我们怎样才能实现我们的程序,使得WM_MOUSEWHEEL消息在鼠标下滚动,这是直观的,而不是聚焦的窗口?

显然,我们可以在计划的核心部分解决这个问题。 看看你的代码中的消息循环,这应该在你的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); } } 

而现在,鼠标下的窗口总是会滚动消息,而不是聚焦的窗口。

在应接收消息的父窗口和子窗口中处理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消息。

我发现在你的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); } 

希望它能帮助别人。