2012-01-24 2 views
1
#include <windows.h> 
#include <process.h> 

HWND MainHwnd; 
HHOOK MouseHook; 
LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam); 
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) 
{ 
    static wchar_t szAppName[]=L"hooks"; 
    HWND hwnd; 
    MSG msg; 
    WNDCLASSEX wndclass; 

    wndclass.cbSize=sizeof(wndclass); 
    wndclass.style=CS_HREDRAW|CS_VREDRAW; 
    wndclass.lpfnWndProc=WndProc; 
    wndclass.cbClsExtra=0; 
    wndclass.cbWndExtra=0; 
    wndclass.hInstance=hInstance; 
    wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); 
    wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); 
    wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); 
    wndclass.lpszMenuName=NULL; 
    wndclass.lpszClassName=szAppName; 
    wndclass.hIconSm=LoadIcon(NULL,IDI_APPLICATION); 

    RegisterClassEx(&wndclass); 

    MainHwnd=hwnd=CreateWindow(szAppName,L"hooks",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 
     CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL); 
    ShowWindow(hwnd,SW_MAXIMIZE); 
    UpdateWindow(hwnd); 

    while(GetMessage(&msg,NULL,0,0)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
    return msg.wParam; 
} 
LRESULT CALLBACK LowLevelMouseProc(int nCode,WPARAM wParam,LPARAM lParam) 
{ 
    if (nCode==HC_ACTION) 
     ((LPMSLLHOOKSTRUCT)lParam)->flags=0; 
    return CallNextHookEx(NULL,nCode,wParam,lParam); 
} 
void thread(void *param) 
{ 
    for (int i=0;i<3;i++) 
    { 
     UnhookWindowsHookEx(MouseHook); 
     MouseHook=SetWindowsHookEx(WH_MOUSE_LL,reinterpret_cast<HOOKPROC>(LowLevelMouseProc),(HINSTANCE)GetWindowLong(MainHwnd,GWL_HINSTANCE),NULL); 
     for (int j=0;j<100;j++) 
     { 
       mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MOVE, (j)*(65535.0/500),(j)*(65535.0/500),0,0); 
       Sleep(10); 
     } 
     Sleep(2000); 
    } 
} 
LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam) 
{ 
    HDC hdc; 
    PAINTSTRUCT ps; 
    switch(iMsg) 
    { 
    case WM_CREATE: 
     { 
      MouseHook=SetWindowsHookEx(WH_MOUSE_LL,reinterpret_cast<HOOKPROC>(LowLevelMouseProc),(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL); 
      _beginthread(thread,0,0); 
      return 0; 
     } 
    case WM_PAINT: 
     { 
      hdc=BeginPaint(hwnd,&ps); 
      EndPaint(hwnd,&ps); 
      return 0; 
     } 
    case WM_DESTROY: 
     UnhookWindowsHookEx(MouseHook); 
     PostQuitMessage(0); 
     return 0; 
    } 
    return DefWindowProc(hwnd,iMsg,wParam,lParam); 
} 

나는 스레드를 _beginthread과 함께 생성합니다. 이 스레드는 마우스 움직임을 시뮬레이트하고 Sleep(2000)으로 전화하십시오. 스레드에서 움직임을 시뮬레이션 한 후 마우스를 움직일 수 없습니다. 내가 마우스없이 바로 작동합니다 void thread(void *param)훅 및 스레드, 마우스 블로킹

UnhookWindowsHookEx(MouseHook); 
MouseHook=SetWindowsHookEx(WH_MOUSE_LL,reinterpret_cast<HOOKPROC>(LowLevelMouseProc),(HINSTANCE)GetWindowLong(MainHwnd,GWL_HINSTANCE),NULL);` 

프로그램이 선을 언급하지만 '차단'. 모두가 그 이유를 설명 할 수 있습니까?

답변

5

저수준 마우스 훅을 설정하기 위해 SetWindowsHookEx()를 호출하는 스레드 은 메시지 루프를 펌프해야합니다. Windows가 등록한 콜백을 호출하여 마우스 메시지를 사용자에게 알릴 수 있도록하는 데 필요합니다. 문제는 하나, 시작한 스레드는 후크를 설정하지만 메시지 루프는 펌프되지 않습니다.

Windows는 이와 같은 잘못 작동하는 프로그램에 대한 보호 기능을 가지고 있기 때문에 콜백을하기에는 너무 오래 기다려야 할 때 자동으로 훅을 파괴합니다. 하지만 스레드가 2 초 동안 잠자기 상태가되어 제한 시간을 초과 할 수 없습니다. 그런 다음 UnhookWindowsHookEx()를 호출하여 Windows를 차단 해제합니다. 그러나 즉시 다시 연결하십시오.

그 스레드에서 SetWindowsHookEx()를 호출 할 필요가 없습니다. 그냥 제거하고 주 스레드에서 설정 한 후크가 정상적으로 실행됩니다. 그 스레드의 요점은 일반적으로 btw로보기가 어렵습니다.

관련 문제