创建全局键盘钩子
Creating Global Keyboard Hook
我正在尝试创建一个全局键盘钩子,用于读取我正在创建的热键程序的击键,但我 运行 遇到了一些问题。首先是,每当我激活挂钩时,键盘就会变得迟钝。屏幕上出现的每个字符之间几乎有整整一秒的延迟。第二个问题是我在 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);
}
DLL 头文件
#include "windows.h"
extern "C" __declspec(dllexport) LRESULT CALLBACK HookProcedure(int code, WPARAM wParam, LPARAM 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");
}
这个版本的代码只是一个超级简单的简化版本,只设置了键盘钩子。为了找出导致问题的原因,我取出了所有其他代码。根据我对钩子的理解(显然不是那么多),这段代码应该钩住键盘但不对击键做任何事情。我不明白为什么它会减慢我的键盘速度。我使用 dumpbin 来确保 DLL 导出函数没有名称重整。我是 运行ning windows 8 64 位,我的 DLL 和我的 exe 文件都编译为 64 位。当我计算出地址和 dllHandle 变量时,我得到了内存地址,所以我知道至少部分代码在工作。如有任何帮助,我们将不胜感激。
另一种方法是下面的代码:
#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;
}
我正在尝试创建一个全局键盘钩子,用于读取我正在创建的热键程序的击键,但我 运行 遇到了一些问题。首先是,每当我激活挂钩时,键盘就会变得迟钝。屏幕上出现的每个字符之间几乎有整整一秒的延迟。第二个问题是我在 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);
}
DLL 头文件
#include "windows.h"
extern "C" __declspec(dllexport) LRESULT CALLBACK HookProcedure(int code, WPARAM wParam, LPARAM 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");
}
这个版本的代码只是一个超级简单的简化版本,只设置了键盘钩子。为了找出导致问题的原因,我取出了所有其他代码。根据我对钩子的理解(显然不是那么多),这段代码应该钩住键盘但不对击键做任何事情。我不明白为什么它会减慢我的键盘速度。我使用 dumpbin 来确保 DLL 导出函数没有名称重整。我是 运行ning windows 8 64 位,我的 DLL 和我的 exe 文件都编译为 64 位。当我计算出地址和 dllHandle 变量时,我得到了内存地址,所以我知道至少部分代码在工作。如有任何帮助,我们将不胜感激。
另一种方法是下面的代码:
#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;
}