C++ 创建全局键盘挂钩

C++ 创建全局键盘挂钩,c++,winapi,dll,C++,Winapi,Dll,我正在尝试创建一个全局键盘挂钩,用于读取我正在创建的热键程序的击键,我遇到了一些问题。首先,每当我激活挂钩时,键盘就会变得迟钝。屏幕上出现的每个字符之间几乎有整整一秒的延迟。第二个问题是,我在DLL回调函数中编写的任何代码都不会执行 这是我的密码: DLL cpp文件 #include<Windows.h> #include "keyDLL.h" using namespace std; LRESULT CALLBACK HookProcedure(int code, WPARA

我正在尝试创建一个全局键盘挂钩,用于读取我正在创建的热键程序的击键,我遇到了一些问题。首先,每当我激活挂钩时,键盘就会变得迟钝。屏幕上出现的每个字符之间几乎有整整一秒的延迟。第二个问题是,我在DLL回调函数中编写的任何代码都不会执行

这是我的密码:

DLL cpp文件

#include<Windows.h>
#include "keyDLL.h"

using namespace std;

LRESULT CALLBACK HookProcedure(int code, WPARAM wParam, LPARAM lParam)
{
    return CallNextHookEx(0, code, wParam, lParam);
}
钩子CPP文件

#include<Windows.h>
#include<iostream>
using namespace std;

HHOOK WINAPI SetWindowsHookEx(_In_  int idHook, _In_  HOOKPROC lpfn, _In_  HINSTANCE hMod, _In_  DWORD dwThreadId
static HINSTANCE dllHandle;
HOOKPROC address;
static HHOOK keyboard_hook;

int main()
{
    dllHandle = LoadLibrary(TEXT("keyDLL.dll"));
    address = (HOOKPROC)GetProcAddress(dllHandle, "HookProcedure");
    cout << address << endl << dllHandle << endl;
    keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, address, dllHandle, 0);

    system("pause");
}
#包括
#包括
使用名称空间std;
HHOOK WINAPI SetWindowsHookx(u In_uuuint idHook,u In_uuuuproc lpfn,u In_uuuhinstance hMod,u In_uuuorddwthreadid
静铰链;
HOOKPROC地址;
静态HHOOK键盘钩;
int main()
{
dllHandle=LoadLibrary(文本(“keyDLL.dll”);
地址=(HOOKPROC)GetProcAddress(dllHandle,“HookProcedure”);

cout另一种方法是以下代码:

#define _WIN32_WINNT 0x0400
#pragma comment( lib, "user32.lib" )

#include <iostream>
#include <windows.h>
#include <stdio.h>

HHOOK hKeyboardHook;

__declspec(dllexport) LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam)
{
    DWORD SHIFT_key=0;
    DWORD CTRL_key=0;
    DWORD ALT_key=0;


    if  ((nCode == HC_ACTION) &&   ((wParam == WM_SYSKEYDOWN) ||  (wParam == WM_KEYDOWN)))      
    {
        KBDLLHOOKSTRUCT hooked_key =    *((KBDLLHOOKSTRUCT*)lParam);
        DWORD dwMsg = 1;
        dwMsg += hooked_key.scanCode << 16;
        dwMsg += hooked_key.flags << 24;
        char lpszKeyName[1024] = {0};

        int i = GetKeyNameText(dwMsg,   (lpszKeyName+1),0xFF) + 1;

        int key = hooked_key.vkCode;

        SHIFT_key = GetAsyncKeyState(VK_SHIFT);
        CTRL_key = GetAsyncKeyState(VK_CONTROL);
        ALT_key = GetAsyncKeyState(VK_MENU);

            printf("Keycode = %c\n",key);

        if (key >= 'A' && key <= 'Z')   
        {

            if  (GetAsyncKeyState(VK_SHIFT)>= 0) key +=32;

            /*********************************************
            ***   Hotkey scope                         ***
            ***   do stuff here                        ***
            **********************************************/

            if (CTRL_key !=0 && key == 'y' )
            {
               MessageBox(NULL, "CTRL-y was pressed\nLaunch your app here", "H O T K E Y", MB_OK); 
               CTRL_key=0;

               //do stuff here




            }

            if (CTRL_key !=0 && key == 'q' )
            {
                MessageBox(NULL, "Shutting down", "H O T K E Y", MB_OK); 
               PostQuitMessage(0);
            }




            SHIFT_key = 0;
            CTRL_key = 0;
            ALT_key = 0;

        }

    }
    return CallNextHookEx(hKeyboardHook,    nCode,wParam,lParam);
}

void MessageLoop()
{
    MSG message;
    while (GetMessage(&message,NULL,0,0)) 
    {
        TranslateMessage( &message );
        DispatchMessage( &message );
    }
}

DWORD WINAPI my_HotKey(LPVOID lpParm)
{
    HINSTANCE hInstance = GetModuleHandle(NULL);
    if (!hInstance) hInstance = LoadLibrary((LPCSTR) lpParm); 
    if (!hInstance) return 1;

    hKeyboardHook = SetWindowsHookEx (  WH_KEYBOARD_LL, (HOOKPROC) KeyboardEvent,   hInstance,  NULL    );
    MessageLoop();
    UnhookWindowsHookEx(hKeyboardHook);
    return 0;
}

int main(int argc, char** argv)
{
    HANDLE hThread;
    DWORD dwThread;

    printf("CTRL-y  for  H O T K E Y  \n");
    printf("CTRL-q  to quit  \n");

    hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)   my_HotKey, (LPVOID) argv[0], NULL, &dwThread);

       /* uncomment to hide console window */
    //ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);

    if (hThread) return WaitForSingleObject(hThread,INFINITE);
    else return 1;

}
#定义_WIN32_WINNT 0x0400
#pragma注释(lib,“user32.lib”)
#包括
#包括
#包括
HHOOK-hKeyboardHook;
__declspec(dllexport)LRESULT回调键盘事件(int-nCode、WPARAM-WPARAM、LPARAM-LPARAM)
{
DWORD SHIFT_键=0;
DWORD CTRL_键=0;
DWORD ALT_键=0;
if((nCode==HC_ACTION)&&((wParam==WM_SYSKEYDOWN)| |(wParam==WM_KEYDOWN)))
{
KBDLLHOOKSTRUCT hooked_key=*((KBDLLHOOKSTRUCT*)LPRAM);
DWORD dwMsg=1;

dwMsg+=hooked_key.scanCode WH_KEYBOARD_LL hook需要一个消息循环,而不是一个DLL。它是“迟缓”的,因为如果您的程序不调用GetMessage(),Windows无法调用消息挂钩函数。可能是@Hans Passant的副本,所以如果我只使用WH_键盘而不是WH_键盘,效果会更好吗?或者这对全局钩子不起作用吗?我不完全清楚这两种钩子之间的所有区别。低级钩子需要一个消息循环。创建一个。你应该切换到WH_键盘,而不是使用
WH_键盘。
。这样更安全nd更有效。即使是这样说:“在应用程序需要使用低级钩子的大多数情况下,它应该监视原始输入。这是因为原始输入可以异步监视针对其他线程的鼠标和键盘消息,比低级钩子更有效。”。
#define _WIN32_WINNT 0x0400
#pragma comment( lib, "user32.lib" )

#include <iostream>
#include <windows.h>
#include <stdio.h>

HHOOK hKeyboardHook;

__declspec(dllexport) LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam)
{
    DWORD SHIFT_key=0;
    DWORD CTRL_key=0;
    DWORD ALT_key=0;


    if  ((nCode == HC_ACTION) &&   ((wParam == WM_SYSKEYDOWN) ||  (wParam == WM_KEYDOWN)))      
    {
        KBDLLHOOKSTRUCT hooked_key =    *((KBDLLHOOKSTRUCT*)lParam);
        DWORD dwMsg = 1;
        dwMsg += hooked_key.scanCode << 16;
        dwMsg += hooked_key.flags << 24;
        char lpszKeyName[1024] = {0};

        int i = GetKeyNameText(dwMsg,   (lpszKeyName+1),0xFF) + 1;

        int key = hooked_key.vkCode;

        SHIFT_key = GetAsyncKeyState(VK_SHIFT);
        CTRL_key = GetAsyncKeyState(VK_CONTROL);
        ALT_key = GetAsyncKeyState(VK_MENU);

            printf("Keycode = %c\n",key);

        if (key >= 'A' && key <= 'Z')   
        {

            if  (GetAsyncKeyState(VK_SHIFT)>= 0) key +=32;

            /*********************************************
            ***   Hotkey scope                         ***
            ***   do stuff here                        ***
            **********************************************/

            if (CTRL_key !=0 && key == 'y' )
            {
               MessageBox(NULL, "CTRL-y was pressed\nLaunch your app here", "H O T K E Y", MB_OK); 
               CTRL_key=0;

               //do stuff here




            }

            if (CTRL_key !=0 && key == 'q' )
            {
                MessageBox(NULL, "Shutting down", "H O T K E Y", MB_OK); 
               PostQuitMessage(0);
            }




            SHIFT_key = 0;
            CTRL_key = 0;
            ALT_key = 0;

        }

    }
    return CallNextHookEx(hKeyboardHook,    nCode,wParam,lParam);
}

void MessageLoop()
{
    MSG message;
    while (GetMessage(&message,NULL,0,0)) 
    {
        TranslateMessage( &message );
        DispatchMessage( &message );
    }
}

DWORD WINAPI my_HotKey(LPVOID lpParm)
{
    HINSTANCE hInstance = GetModuleHandle(NULL);
    if (!hInstance) hInstance = LoadLibrary((LPCSTR) lpParm); 
    if (!hInstance) return 1;

    hKeyboardHook = SetWindowsHookEx (  WH_KEYBOARD_LL, (HOOKPROC) KeyboardEvent,   hInstance,  NULL    );
    MessageLoop();
    UnhookWindowsHookEx(hKeyboardHook);
    return 0;
}

int main(int argc, char** argv)
{
    HANDLE hThread;
    DWORD dwThread;

    printf("CTRL-y  for  H O T K E Y  \n");
    printf("CTRL-q  to quit  \n");

    hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)   my_HotKey, (LPVOID) argv[0], NULL, &dwThread);

       /* uncomment to hide console window */
    //ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);

    if (hThread) return WaitForSingleObject(hThread,INFINITE);
    else return 1;

}