2014-06-07 5 views
0

모든 마우스 이동 이벤트를 연결하려고하지만 모든 메시지를 수신하지 않습니다. 당신이 DLL의 시스템 전체 훅을 필요WinAPI - 훅 마우스 이동이 작동하지 않습니다.

#include <Windows.h> 
#include <windowsx.h> 
#include <iostream> 

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) 
{ 
    if (wParam != WM_MOUSEMOVE) 
    { 
     return CallNextHookEx(NULL, nCode, wParam, lParam); 
    } 

    std::cout << GET_X_LPARAM(lParam) << std::endl; 
    return 0; 
} 

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (uMsg) 
    { 
    case WM_DESTROY: 
     PostQuitMessage(0); 
     return 0; 

    case WM_MOUSEMOVE: 
     int xPos = GET_X_LPARAM(lParam); 
     int yPos = GET_Y_LPARAM(lParam); 
     std::cout << xPos << " - " << yPos << std::endl; 
     return 0; 
    } 

    return DefWindowProc(hwnd, uMsg, wParam, lParam); 
} 

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) 
{ 
    AllocConsole(); 

    HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hInstance, NULL); 

    MSG msg; 

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

    return 0; 
} 
+0

교체, 훅 프로 시저 (DLL로드 가능한 모듈에 있어야합니다). 'MouseHookProc'는 메시지를 모두 걸러 내고 싶지 않으면 항상 ** CallNextHookEx를 호출해야합니다. 후자의 경우, 훅 프로 시저는 0이 아닌 값을 리턴해야합니다. 요구 사항을 충족시키지 못하면 시스템의 다른 고리가 끊어집니다. ['LowLevelMouseProc'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986.aspx)를 철저히 읽으십시오. 방금 말한 모든 내용이 나와 있습니다. – IInspectable

+0

@IInspectable asker가 낮은 레벨의 후크를 사용 중입니다. –

+0

@David 좋은 지적입니다. 하위 수준 훅의 경우 훅 프로 시저가 DLL에 있어야 할 필요는 없습니다. 나머지 요구 사항은 여전히 ​​유지되고'MouseHookProc'을 고쳐야합니다. – IInspectable

답변

3
std::cout << GET_X_LPARAM(lParam) << std::endl; 

후크가 잘 작동, 당신은 당신이 콘솔이없는 프로그램을 빌드 할 때 제대로 표준 출력을 초기화 할 수있는 CRT의 능력을 오버 레이팅된다. 후크 콜백 코드는 일반적으로 올바르지 않습니다.

Visual Studio의 경우 출력 창이 나타나면 디버거에 텍스트가 표시됩니다.

이렇게하는 또 다른 방법은 콘솔 모드 앱을 간단하게 빌드하여 콘솔을 바로 가져오고 stdout이 작동하도록하는 것입니다. WinMain()을 main()으로 변경하십시오.

또는 stdout을 다시 열어 원하는 것을 선택하십시오. 이처럼 : @HansPassant 같은

AllocConsole(); 
    freopen("CONOUT$", "wb", stdout); 
1

당신이 (당신의 NULL 마지막 매개 변수가 있음을 의미한다) 모든 프로세스에 대해 마우스 이벤트를 캡처하려는 경우 : 이것은 전체 코드입니다.

나는 내 웹 사이트에 예제가있다 here.

+0

정확하지 않습니다. 저수준 마우스 훅은 결코 DLL을 사용하지 않습니다. –

+0

아, 저 레벨이라고 생각하지 않았어요. –

0

예 유 콘솔가 업데이트 될 때마다 새로 고침하지 않는 한 std::cout 일을 표시하는 효율적인 방법이 아닙니다 언급했다.

내가 코드 사용도 필요하기 때문에, 전체 프로그램을 리메이크 한 : 블록의 기본 Win32에서 템플릿 및 글로벌 후크를 들어 MouseHookProc :

#include <windows.h> 
#include <windowsx.h> 
#include <iostream> 
#include <sstream> 

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); 
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam); 

char szClassName[ ] = "CodeBlocksWindowsApp"; 
HWND Label1, Label2; //adding 2 static controls to display things 

int WINAPI WinMain (HINSTANCE hThisInstance, 
       HINSTANCE hPrevInstance, 
       LPSTR lpszArgument, 
       int nCmdShow) 
{ 
// adding hook 
HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hThisInstance, NULL); 

HWND hwnd; 
MSG messages; 
WNDCLASSEX wincl; 
wincl.hInstance = hThisInstance; 
wincl.lpszClassName = szClassName; 
wincl.lpfnWndProc = WindowProcedure; 
wincl.style = CS_DBLCLKS; 
wincl.cbSize = sizeof (WNDCLASSEX); 
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); 
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); 
wincl.hCursor = LoadCursor (NULL, IDC_ARROW); 
wincl.lpszMenuName = NULL; 
wincl.cbClsExtra = 0; 
wincl.cbWndExtra = 0; 
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; 

if (!RegisterClassEx (&wincl)) 
    return 0; 

hwnd = CreateWindowEx (0, szClassName, "Code::Blocks Template Windows App", 
     WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, 
     HWND_DESKTOP, NULL, hThisInstance, NULL); 

ShowWindow (hwnd, nCmdShow); 

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

return messages.wParam; 
} 


LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
switch (message) 
{ 
    case WM_CREATE: 
     //creating those 2 static controls 
     Label1 = CreateWindow("STATIC", "Label1", WS_VISIBLE | WS_CHILD, 10,10,60,18, hwnd, NULL, NULL, NULL); 
     Label2 = CreateWindow("STATIC", "Label2", WS_VISIBLE | WS_CHILD, 70,10,60,18, hwnd, NULL, NULL, NULL); 
    break; 
    //adding mousemove event 
    case WM_MOUSEMOVE: { 
     int xPos = GET_X_LPARAM(lParam); 
     int yPos = GET_Y_LPARAM(lParam); 
     //std::cout << xPos << " - " << yPos << std::endl; 
     TCHAR Coords[20]; 
     wsprintf(Coords, "%i, %i", xPos, yPos); 
     SetWindowText(Label1, Coords); 
    return 0; } 

    case WM_DESTROY: 
     PostQuitMessage (0); 
     break; 
    default: 
     return DefWindowProc (hwnd, message, wParam, lParam); 
} 
return 0; 
} 

//replacing MouseHookProc 
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) { 
    if (nCode >= 0 && wParam == WM_MOUSEMOVE) { 
     MSLLHOOKSTRUCT* mh = (MSLLHOOKSTRUCT*)lParam; 
     std::stringstream ss; 
     ss << mh->pt.x << ", " << mh->pt.y << std::endl; 
     //OutputDebugStringA(ss.str().c_str()); 
     SetWindowText(Label2, ss.str().c_str()); 
    } 
    return CallNextHookEx(NULL, nCode, wParam, lParam); 
} 
관련 문제