【发布时间】:2014-02-05 12:03:46
【问题描述】:
我有一个被进程调用的 dll,现在我想在 dll 中实现输入检查,以对应用程序中出现的某些输入做出反应。
带有KeyboardProc 函数的SetWindowsHookEx() 似乎是一个可行的解决方案,所以我实现了它。
dll中的代码大致是这样的:
static HHOOK hhk = NULL;
LRESULT CALLBACK keyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
if(code == HC_ACTION && ((DWORD)lParam & 0x80000000) == 0) // if there is an incoming action and a key was pressed
{
switch(wParam)
{
case VK_SPACE:
printf("Space was pressed\n");
break;
}
}
return CallNextHookEx(hhk, code, wParam, lParam);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH)
{
if(AllocConsole()){
freopen("CONOUT$", "w", stdout); // redirect output to console for debugging
}
printf("Dll loaded, lastError = %i\n", GetLastError());
printf("lastError = %i\n", GetLastError());
// sidenote: for some reason the first GetLastError() returns 0 while the second one returns 6 (invalid handle)
hhk = SetWindowsHookEx(WH_KEYBOARD, keyboardProc, hModule, GetCurrentThreadId());
}
else if (ul_reason_for_call == DLL_PROCESS_DETACH)
{
printf("\nCleaning up...");
FreeConsole();
UnhookWindowsHookEx(hhk);
}
return TRUE;
}
但是,当我按任意键时,控制台窗口中什么也没有发生(或打印)。 keyboardProc 函数似乎在任何时候都无法访问。
当我将NULL 而不是GetCurrentThreadId() 传递给SetWindowsHookEx() 时,它确实 起作用。
但这会导致钩子在全局范围内工作,这意味着每当我在另一个应用程序中按下一个键时,就会弹出一个控制台窗口(因为再次调用了 dll)并且他在那里检查键输入。
显然这是不希望的,我想只使用最初调用 dll 的进程。
我已经检查了GetCurrentThreadId() 是否返回了一个有效的 ID,并且它似乎确实是最初调用 dll 的进程的主线程 ID(使用 Process Explorer 检查)。
所以现在我的问题是可能是什么问题,更重要的是,我该怎么做才能使它正常工作?
【问题讨论】:
-
程序默认调用 DLL。但是我没有程序的源代码,只有 DLL。如果线程 ID 正确,我已经多次使用 Process Explorer 检查过,并且还尝试使用此 sn-p -> codeproject.com/Questions/78801/… 通过进程 ID 加载它
-
你解决这个问题了吗?我遇到了完全相同的问题:(
-
很遗憾没有,任何建议仍然非常感谢(抱歉迟到的回复)。
-
我相信您应该在您的应用程序中包含一个消息循环才能使其正常工作。 while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg);调度消息(&msg); }