【发布时间】:2014-10-21 18:11:43
【问题描述】:
主题:将某些键替换为另一个键值。
例如如果我按 P 应该是 F24。
当我尝试从 .ini 文件中加载键值时,钩子不再是全局的。仅当 winapi 表单处于焦点时才有效。
我的 DLL 代码:
extern "C" __declspec(dllexport) LRESULT CALLBACK KeyboardHook(int, WPARAM, LPARAM);
extern "C" __declspec(dllexport) void loadSettings(LPSTR);
bool shouldUpdateKey = false;
int ArcherKey;
LRESULT CALLBACK KeyboardHook(int code, WPARAM wParam, LPARAM lParam)
{
if ((lParam >> 20))
{
if (wParam == ArcherKey)
{
shouldUpdateKey = shouldUpdateKey ? false : true;
if (shouldUpdateKey)
{
MessageBox(NULL, L"ArcherKey", L"", MB_OK);
keybd_event(0x87, 45, 1, 0); //press F24
return 1;
}
}
}
return CallNextHookEx(NULL, code, wParam, lParam);
}
LPSTR GetValueFromINI(LPSTR FileName, LPSTR Section, LPSTR Key)
{
char *key;
key = (char *)malloc(256);
GetPrivateProfileStringA(Section, Key, NULL, key, 256, FileName);
return key;
free(key);
}
void loadSettings(LPSTR FileName)
{
ArcherKey = atoi(GetValueFromINI(FileName, "HotKey", "Archer key"));
}
我使用 shouldUpdateKey 来避免 x2 回调(按下和按下按键时)调用。我也尝试添加这个语句 if (lParam >>31) ^ 1,但是这个语句总是错误的。
.exe代码:
LRESULT(*pKeybHook)(int, WPARAM, LPARAM);
HHOOK hhookMsg;
void(*loadSettings)(LPSTR);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
/* default code */
HMODULE dll = LoadLibrary(_T("MainHookDLL.dll"));
if (dll)
{
pKeybHook = (LRESULT(*)(int, WPARAM, LPARAM)) GetProcAddress(dll, "_KeyboardHook@12");
loadSettings = (void(*)(LPSTR)) GetProcAddress(dll, "loadSettings");
loadSettings("C:\\Settings.ini");
hhookMsg = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)(pKeybHook), dll, 0);
}
/* defult code */
UnhookWindowsHookEx(hhookMsg); // unhook
FreeLibrary(dll);
return (int) msg.wParam;
}
Settings.ini 结构:
[HotKey]
Archer key=80
所以我的问题: 如果尝试从文件加载设置,则挂钩仅在活动的 winapi 窗口中有效。它显示 MessageBox\etc,但仅以活动的 winapi 形式显示。 如果将 wParam == ArcherKey 替换为 wParam == 80,它将在所有应用程序中全局工作。 我调试我的应用程序,从 .ini 文件加载后,我的 ArcherKey = 80。所以我真的不明白我到底犯了什么错误。
【问题讨论】: