2013-11-28 2 views
4

Visual Studio 2012를 살펴보면 마우스 휠을 사용하면 마우스 아래의 창이 스크롤되고 포커스가있는 창은 스크롤되지 않음을 알 수 있습니다. 즉, 커서를 코드 편집기에두고 솔루션 탐색기 창 위로 마우스를 이동하고 스크롤하면 솔루션 탐색기가 스크롤되고 코드 편집기는 스크롤되지 않습니다. 그러나 WM_MOUSEWHEEL 메시지는 포커스가있는 창으로 만 전송됩니다.이 경우 코드 편집기입니다. WM_MOUSEWHEEL 메시지가 마우스 밑의 윈도우를 스크롤하도록 프로그램을 구현하는 방법은 직관적이며 초점이 맞춰진 창이 아닙니까?마우스 아래 창 스크롤

답변

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

이제 마우스 아래 창의 창에는 포커스가있는 창이 아니라 스크롤 메시지가 표시됩니다.

+0

좋은 생각이지만, 불행히도'WM_MOUSEWHEEL'은 포커스가있는 창으로 직접 보내 지므로'GetMessage' 루프에 나타나지 않습니다. –

+0

흠, 그래도 작동하는 것 같습니다. 메시지가 SendMessage, SendMessageCallback, SendMessageTimeout, 또는 SendNotifyMessage (MSDN)에 의해 게시 된 경우 GetMessage는 Windows에 직접 메시지를 보내고 TranslateMessage 및 DispatchMessage, WM_MOUSEWHEEL 중 하나 인 다른 모든 메시지를 검색합니다. – GILGAMESH

+0

Windows 10에서 마우스 휠의 새로운 기본 동작을 멋지게 시뮬레이트합니다. – krlmlr

2

메시지를받을 부모 창과 자식 창에서 WM_MOUSEWHEEL 메시지를 처리하십시오. 당신의 자식 창에 대한 귀하의 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); 
    } 

당신이 할 :

POINT mouse; 

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

    SendMessage(hwnd, message, wParam, lParam); 

이 방법을, 자식 창 경우 실제로 마우스 커서를 가리키면 다른 창에 WM_MOUSEWHEEL 메시지가 수신됩니다.

+0

이 솔루션은 자체 메시지 펌프가없는 경우 (즉, DialogBoxParam을 사용하는 경우) 훨씬 쉽습니다. –

+0

@DavidGausmann : 이것은 거의 쉬운 일이 아닙니다. 이 작업을 수행하려면 모든 하위 컨트롤을 모두 하위 클래스에 추가해야합니다. 당신은 하나를 그리워하고 그것은 아주 미묘한 방법으로 끊어집니다. 당신은 선택의 여지가 많지는 않지만, 분명 쉽지는 않습니다. – IInspectable

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

누군가가 도움이되기를 바랍니다.

+0

이 솔루션을 게시 해 주셔서 감사합니다. 이전에 게시 된 솔루션보다 훨씬 간단합니다. – PIntag