C++ 钩子和线,鼠标阻塞

C++ 钩子和线,鼠标阻塞,c++,multithreading,winapi,C++,Multithreading,Winapi,程序将正常工作,无需鼠标“阻塞”。每个人都能解释一下原因。调用SetWindowsHookEx来设置低级鼠标挂钩的线程必须泵送一个消息循环。必需,以便Windows可以调用您注册的回调,以便它可以通知您鼠标消息。这就是你的问题所在,你启动的线程设置了一个钩子,但没有产生一个消息循环 Windows具有防止此类错误程序的保护功能,当它必须等待太长时间才能进行回调时,它会自动销毁钩子。但是你的线程睡眠2秒,不足以触发超时。然后调用UnhookWindowsHookEx来解除窗口的阻塞。但立即再次上钩

程序将正常工作,无需鼠标“阻塞”。每个人都能解释一下原因。

调用SetWindowsHookEx来设置低级鼠标挂钩的线程必须泵送一个消息循环。必需,以便Windows可以调用您注册的回调,以便它可以通知您鼠标消息。这就是你的问题所在,你启动的线程设置了一个钩子,但没有产生一个消息循环

Windows具有防止此类错误程序的保护功能,当它必须等待太长时间才能进行回调时,它会自动销毁钩子。但是你的线程睡眠2秒,不足以触发超时。然后调用UnhookWindowsHookEx来解除窗口的阻塞。但立即再次上钩


在该线程中调用SetWindowsHookEx没有任何意义。只要拆下它,你在主线程中设置的钩子就会正常运行。通常很难看出该线程的意义。顺便说一句,调用SetWindowsHookEx设置低级鼠标挂钩的线程必须泵送消息循环。必需,以便Windows可以调用您注册的回调,以便它可以通知您鼠标消息。这就是你的问题所在,你启动的线程设置了一个钩子,但没有产生一个消息循环

Windows具有防止此类错误程序的保护功能,当它必须等待太长时间才能进行回调时,它会自动销毁钩子。但是你的线程睡眠2秒,不足以触发超时。然后调用UnhookWindowsHookEx来解除窗口的阻塞。但立即再次上钩

在该线程中调用SetWindowsHookEx没有任何意义。只要拆下它,你在主线程中设置的钩子就会正常运行。顺便说一句,很难看出这条线的意义

#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);
}
UnhookWindowsHookEx(MouseHook);
MouseHook=SetWindowsHookEx(WH_MOUSE_LL,reinterpret_cast<HOOKPROC>(LowLevelMouseProc),(HINSTANCE)GetWindowLong(MainHwnd,GWL_HINSTANCE),NULL);`