крючки и нити, блокировка мыши - PullRequest
1 голос
/ 24 января 2012
#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);`

программа будет работать правильно, без блокировки мыши. Может ли каждый объяснить причину этого.

1 Ответ

5 голосов
/ 24 января 2012

Поток, который вызывает SetWindowsHookEx (), чтобы установить низкоуровневый хук мыши должен прокачать цикл сообщений. Требуется, чтобы Windows могла вызвать зарегистрированный обратный вызов и уведомить вас о сообщении мыши. В чем ваша проблема, поток, который вы начали, устанавливает ловушку, но не качает цикл сообщений.

Windows имеет защиту от неправильного поведения программ, таких как эта, она автоматически уничтожает ловушку, когда приходится ждать слишком долго, чтобы выполнить обратный вызов. Но ваш поток спит в течение 2 секунд, недостаточно долго, чтобы вызвать тайм-аут. Затем вы вызываете UnhookWindowsHookEx (), который разблокирует Windows. Но немедленно зацепите снова.

Нет никакого смысла вызывать SetWindowsHookEx () в этом потоке. Просто удалите его, и хук, который вы установили в главном потоке, будет работать как обычно. Трудно понять смысл этой темы вообще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...