SETWINDOWSHOOKEX不调用我的回调? well我尝试了不同的解决方案,但这只是行不通的。 我调用setWindowShookexa,然后在按下键时,未显示消息框。该怎么办? 这是我的代码(这是DLL

问题描述 投票:0回答:2
这是我的代码(这是一个由程序加载的DLL加载的DLL):

#include <Windows.h> HINSTANCE gl_hThisInstance = NULL; HHOOK hHook = NULL; LRESULT CALLBACK KeyHit(int code,WPARAM wParam,LPARAM lParam); BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: gl_hThisInstance = (HINSTANCE)hModule; hHook = SetWindowsHookExA( WH_KEYBOARD, KeyHit, //(HWND)gl_hThisInstance//not working 0,//not working //(DWORD)gl_hThisInstance//not working //GetCurrentThreadId()//even not working with this 0//not working ); break; } return TRUE; } LRESULT CALLBACK KeyHit(int code,WPARAM wParam,LPARAM lParam) { MessageBox(0,"PRESSED","PRESSED",0); return CallNextHookEx(hHook,code,wParam,lParam); }

我以前遇到了问题。并不是一个问题,但是我不应该这样做的方式。 首先,您应该有2个来自DLL,
SetHook
c++ winapi hook keyboard-hook
2个回答
1
投票
的导出功能。

SetHook

函数将从那里调用
SetWindowsHookEx()
。如果您尝试从线程或DLL的线程或
SetWindowsHookEx()
中调用
DLLMain
,则该函数不会返回任何错误,但是将永远不会调用回调函数。有时我花了我弄清楚。

这里是我要捕获的工作代码,您可以从这里引用。
我从dll的工作导出了sethook()函数。

WH_GETMESSAGE

bool __declspec(dllexport) __stdcall SetHook(DWORD myWnd) { mySavedHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, infoContainer.DllHModule, myWnd); int errorID = GetLastError(); if (errorID != 0) { MessageBoxA(NULL, "Failed to implement hook", "Failed", 0); MessageBoxA(NULL, to_string(errorID).c_str(), "Error ID", 0); return false; } else { return true; } }

:DLL的实例,这是

infoContainer.DllHModule
的第一个参数。

DllMain()

是我的线程ID(不处理ID) - 从

myWnd:
获取。要实现全局钩,请使用0为
GetWindowThreadProcessId(window_handle, NULL)

.

这是我的回调函数。
myWnd
回调函数必须具有
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode >= 0) { LPMSG msg = (LPMSG)lParam; if (msg->message == WM_CALLFUNCTION) { MessageBoxA(NULL, "Receive WM_CALLFUNTION", "Good news", 0); } } //Doesn't matter, just call this function and return it. return CallNextHookEx(_hook, nCode, wParam, lParam); }
关键字可以工作。

从外部应用程序,从dll调用
CALLBACK
,然后将线程ID用作其参数。

我知道这是超级旧的,但是我前几天我自己遇到了这个问题,正如其他答案所建议的那样,您无法从dllmain函数或其他线程中调用
SetHook()

,但这是因为DLL主函数在其自己的线程中运行,与主线程分开。 这是相关的,因为显然,当您打电话

SetWindowsHookEx()
时,一旦您wed the the the the the ture the ture the Ever ture the Ever ture the the the the the the the,然后由于某种原因而自动解开(我找不到Internet上任何地方都记录下来的线程)

因此,如果您从目标过程的主要一个线程(假设您可以做到)以外的任何线程调用

SetWindowsHookEx()

,那么总是有可能在主过程本身到期之前撤消钩子。
在这种情况下,一旦dllmain函数返回,它将终止线程并因此删除钩子。
为了修复此问题,我从一个新线程中调用钩子,然后我无限期地悬挂该线程,这应该意味着只有在过程本身关闭时才删除钩子。

问题的固定版本可能看起来像这样的东西

0
投票

作为一个奖励,我实际上读了这一点,我将另一个小函数汇总在一起,以获取该过程的

A
窗口的线程ID(不是主要的窗口,如果是主要的)为了获得

HHOOK hHook = NULL; LRESULT CALLBACK KeyHit(int code, WPARAM wParam, LPARAM lParam){ // replace with whatever logic you want to run in the target process when keyboard event is called cout << "keyboard event detected.\n"; return CallNextHookEx(hHook, code, wParam, lParam); } void ThreadHookEvents() { DWORD thread_id = 0; // set this to the thread id of your main/hwnd thread HHOOK hHook = SetWindowsHookExA(WH_KEYBOARD, (HOOKPROC)KeyHit, 0, thread_id); // then pause the thread so the hook never expires SuspendThread(GetCurrentThread()); } BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){ switch (ul_reason_for_call){ case DLL_PROCESS_ATTACH: CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)ThreadHookEvents, 0, 0, 0); break; } return TRUE; }

thread_id
    
	

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.