我试图在C中进行全局键盘挂钩并遇到麻烦。
我的目的是当我键入F2
键或Ctrl
键时,会打印一些行以检查它是否有效,如果我按下q
键,将停止挂钩。
为了测试整个代码,我在某些部分使用了printf
。
我不知道如何解决这个问题,但我真的想解决它。
.cpp代码:
#include "stdio.h"
#include "conio.h"
#include "windows.h"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop"
typedef void(*PFN_HOOKSTART)();
typedef void(*PFN_HOOKSTOP)();
void main() {
HMODULE hDll = NULL;
PFN_HOOKSTART HookStart = NULL;
PFN_HOOKSTOP HookStop = NULL;
char ch = 0;
// load Dll
hDll = LoadLibrary(L"HookTest.dll");
if (hDll == NULL) {
printf("load fail \n");
return;
}
else {
printf("load success \n");
}
HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);
HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);
HookStart();
printf("press 'q' to quit!\n");
// if user push 'q' key, HookStop
while (1) {
if (_getch() == 'q') {
break;
}
printf("Test Typing \n");
}
HookStop();
FreeLibrary(hDll);
}
.dll代码:
#include <stdio.h>
#include <windows.h>
#pragma data_seg(".kbdata")
HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
HWND g_hWnd = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.kbdata,RWS")
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
g_hInstance = hinstDLL;
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" {
LRESULT __declspec(dllexport) CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
printf("Test 1 --- KeyboardProc sucess \n");
if (nCode >= 0) {
printf("Test 2 --- \n");
if (wParam == VK_F2) {
printf("F2 Key Typed ");
}
else if (wParam == VK_CONTROL) {
printf("Ctrl Key Typed ");
}
else {
printf("Other Key Typed");
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
}
extern "C" __declspec(dllexport) void HookStart() {
g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
printf("Test 3 --- HookStart Call \n");
}
extern "C" __declspec(dllexport) void HookStop() {
printf("Test 4 --- HookStop Call \n");
if (g_hHook) {
UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
}