C++ 使用WH_GETMESSAGE和WH_键盘的全局钩子

C++ 使用WH_GETMESSAGE和WH_键盘的全局钩子,c++,winapi,hook,msdn,keyboard-hook,C++,Winapi,Hook,Msdn,Keyboard Hook,我尝试制作全局钩子,以便从键盘上捕捉数字,更改它,并传递它。例如:如果我在谷歌中输入“0”,软件会改变它,而插入“1”。为了学习钩子是如何工作的,我用WHU键盘把所有的键都插入到我的电脑里,它工作了。但是,现在我想全局更改密钥,为了做到这一点,我使用WH_GETMESSAGE。在这种情况下,钩子不是全局应用的,而是局部应用的(在测试窗口中)。为什么它会以这种方式工作,以及如何修复它 我的dll的代码: void testHook() { HINSTANCE hCurrentDll = G

我尝试制作全局钩子,以便从键盘上捕捉数字,更改它,并传递它。例如:如果我在谷歌中输入“0”,软件会改变它,而插入“1”。为了学习钩子是如何工作的,我用WHU键盘把所有的键都插入到我的电脑里,它工作了。但是,现在我想全局更改密钥,为了做到这一点,我使用WH_GETMESSAGE。在这种情况下,钩子不是全局应用的,而是局部应用的(在测试窗口中)。为什么它会以这种方式工作,以及如何修复它

我的dll的代码:

void testHook() {
    HINSTANCE hCurrentDll = GetModuleHandle("testDll.dll");
//    g_HookHandle = SetWindowsHookEx(WH_KEYBOARD, TestForHook, hCurrentDll, 0);

    g_HookHandle = SetWindowsHookEx(WH_GETMESSAGE, &TestForHook, hCurrentDll, 0);


    if(g_HookHandle == NULL)
        throw 1;
}

void untestHook() {
    if (!UnhookWindowsHookEx(g_HookHandle))
        throw 1;

    g_HookHandle = NULL;
}


extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            // attach to process
            // return FALSE to fail DLL load
            break;

        case DLL_PROCESS_DETACH:
            // detach from process
            break;

        case DLL_THREAD_ATTACH:
            // attach to thread
            break;

        case DLL_THREAD_DETACH:
            // detach from thread
            break;
    }
    return TRUE; // succesful
}

//LRESULT CALLBACK TestForHook(int code, WPARAM wParam, LPARAM lParam)
//{
//    if( code < 0 ) return CallNextHookEx( 0, code, wParam, lParam );
//
//    if( wParam == 0x30)
//    {
//        std::cout << wParam;
//        wParam = 0x31;
//        std::cout << wParam;
//        return CallNextHookEx( 0, code, wParam, lParam );
//    }
//
//    return CallNextHookEx( 0, code, wParam, lParam );
//}



LRESULT CALLBACK TestForHook(int code, WPARAM wParam, LPARAM lParam)
{
    MSG *lpmsg;
    if( code < 0 ) return CallNextHookEx( 0, code, wParam, lParam );


    lpmsg = (MSG *)lParam;
    std::cout << "dziala";
    if((lpmsg ->message) == 258 || (lpmsg ->message) == 257)
        {

            if((lpmsg -> wParam) == 48)
                lpmsg -> wParam = 57;
            std::cout << lpmsg -> wParam << "    " << lpmsg -> lParam << "    " << lpmsg->hwnd << std::endl;
        }




    return CallNextHookEx( 0, code, wParam, lParam );
}
void testHook(){
HINSTANCE hCurrentDll=GetModuleHandle(“testDll.dll”);
//g_HookHandle=setWindowshookx(WH_键盘,TestForHook,hCurrentDll,0);
g_HookHandle=setWindowshookx(WH_GETMESSAGE,&TestForHook,hCurrentDll,0);
if(g_HookHandle==NULL)
投掷1枚;
}
void untestHook(){
如果(!unhookwindowshookx(g_HookHandle))
投掷1枚;
g_HookHandle=NULL;
}
外部“C”DLL_EXPORT BOOL apient DllMain(HINSTANCE hinstDLL、DWORD FDFREASON、LPVOID lpvReserved)
{
开关(FDSON)
{
案例DLL\u进程\u附加:
//附加到进程
//返回FALSE以使DLL加载失败
打破
案例DLL\u进程\u分离:
//从进程中分离
打破
案例DLL\u线程\u连接:
//附在螺纹上
打破
案例DLL\u线程\u分离:
//从螺纹上拆下
打破
}
返回TRUE;//成功
}
//LRESULT回调TestForHook(int代码、WPARAM WPARAM、LPARAM LPARAM)
//{
//if(code<0)返回CallNextHookEx(0,code,wParam,lParam);
//
//if(wParam==0x30)
//    {
//标准::cout wParam)==48)
lpmsg->wParam=57;

std::cout wParam不要使用硬编码的幻数,而是使用它们的专有名称/常量:258->
WM\u CHAR
,257->
WM\u KEYUP
,48->
'0'
,57->
'9'
。另外,从DLL本身内部调用
SetWindowsHookEx()
时,不要使用
GetModuleHandle()
要获取DLL的模块句柄,请使用
DllMain()的第一个参数提供的句柄
相反,请将其保存到需要时使用的变量中。最后,不要跨越DLL边界抛出异常!您要问的问题到底是什么?我使用用于测试的神奇数字。我的问题是,为什么WH_GETMESSAGE不能在所有线程中工作?您不能为线程安装
WH_GETMESSAGE
挂钩它没有消息队列。如果要将
WH_GETMESSAGE
钩子插入另一个进程,则需要遵循以下操作:“如果dwThreadId参数为零或指定由其他进程创建的线程的标识符,则lpfn参数必须指向DLL中的钩子过程。”说真的,所有的代码::块用户都习惯于启用Unicode。非Ascii字符是真实的。
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{


    WNDCLASSEX wc;
    std::cout << kwadrat(5);

    wc.cbSize = sizeof( WNDCLASSEX );
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground =( HBRUSH )( COLOR_WINDOW + 1 );
    wc.lpszMenuName = NULL;
    wc.lpszClassName = NazwaKlasy;
    wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION );

    g_MyHook = NULL;

    if( !RegisterClassEx( & wc ) )
    {
        MB_ICONEXCLAMATION | MB_OK );
        return 1;
    }


    hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, NazwaKlasy, "Oto okienko", WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL );


         try{
                testHook();
            }
            catch(int e)
            {
                if (e == 1)
                    return 1;
            }

    if( hwnd == NULL )
    {
        return 1;
    }

    ShowWindow( hwnd, nCmdShow ); 
    UpdateWindow( hwnd );

    while( GetMessage( & Komunikat, NULL, 0, 0 ) )
    {
        TranslateMessage( & Komunikat );
        DispatchMessage( & Komunikat );
    }
    return Komunikat.wParam;
}

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
    case WM_CLOSE:
        DestroyWindow( hwnd );

            try{
                untestHook();
            }
            catch(int e)
            {
                if (e == 1)
                    return 1;
            }
        }


        break;

    case WM_DESTROY:

        if(GLOBAL){
        try{
            untestHook();
        }
        catch(int e)
        {
            if (e == 1)
                return 1;
        }


        break;

        default:
        return DefWindowProc( hwnd, msg, wParam, lParam );
    }

    return 0;
}