gpt4 book ai didi

C++ 键盘 Hook

转载 作者:行者123 更新时间:2023-11-28 06:37:55 32 4
gpt4 key购买 nike

主题:将某些键替换为另一个键值。

例如如果我按 P,它应该是 F24。

当我尝试从 .ini 文件加载键值时, Hook 不再是全局的。它仅在 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

所以我的问题:如果尝试从文件加载设置, Hook 仅在事件的 winapi 窗口中工作。它显示 MessageBox\etc,但仅以事件的 winapi 形式显示。如果将 wParam == ArcherKey 替换为 wParam == 80 它在全局范围内适用于所有应用程序。我调试我的应用程序,从 .ini 文件加载后我有 ArcherKey = 80。所以我真的不明白我实际上有什么错误。

最佳答案

据我所知,如果 Hook 是全局的,则包含 HOOKPROC 的 DLL 会加载到所有其他进程中。这意味着您在内存中有多个 DLL 实例。由于您是从应用程序中调用 loadSettings(..) 的,因此 ArcherKey 的值仅为该进程初始化。这会导致您观察到的行为。

要更改它,您应该将 DllMain(..) 函数修改为如下内容:

BOOL WINAPI DllMain(HINSTANCE hinstDLL,  // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{

switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
loadSettings("C:\\Settings.ini");
break;

case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;

case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;

case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}

return TRUE;
}

这会为正在安装 Hook 的所有进程初始化 ArcherKey 的值,因为 Windows 在加载 DLL 时会调用 DllMain。出于测试目的,您可以添加 MessageBeep(0);在调用 loadSettings(..) 之前验证代码部分是否已执行。

快速查看 SetWindowsHookEx(..) 的文档让我的恐惧成真:如果您正在编译 32 位 DLL,您将不能 Hook 64 位进程,反之亦然。为此,您必须使用不同名称的 HOOKPROC 实现 64 位版本的 dll。

关于C++ 键盘 Hook ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26493394/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com