Delphi 了解如何使用Windows挂钩
我正在尝试使用SetWindowsHookEx在某些过程中钩住鼠标。我在用Delphi7。 代码(DLL): 所以。SetWindowsHookEx返回1428错误:无法设置没有模块句柄的非本地钩子。 但正如我所知,如果我不需要使用dll hmodule。。。 我知道它将如何工作: 每个鼠标事件都将使用WM_数据(wParam是事件数据,lParam是ProcessId)传递到我的应用程序(窗口类是'ichookapplication')Delphi 了解如何使用Windows挂钩,delphi,winapi,hook,setwindowshookex,Delphi,Winapi,Hook,Setwindowshookex,我正在尝试使用SetWindowsHookEx在某些过程中钩住鼠标。我在用Delphi7。 代码(DLL): 所以。SetWindowsHookEx返回1428错误:无法设置没有模块句柄的非本地钩子。 但正如我所知,如果我不需要使用dll hmodule。。。 我知道它将如何工作: 每个鼠标事件都将使用WM_数据(wParam是事件数据,lParam是ProcessId)传递到我的应用程序(窗口类是'ichookapplication') 谢谢 WH_鼠标是一个全局钩子。DLL将被注入钩住的进程
谢谢
WH_鼠标是一个全局钩子。DLL将被注入钩住的进程中。您确实需要提供一个模块句柄。与错误代码相关的名称非常清楚,error\u HOOK\u NEEDS\u HMOD
。提供模块句柄并不困难。通过HInstance
如果您不想注射,那么您需要使用WH\u MOUSE\u ll
而不是WH\u MOUSE
谢谢!Im修改HookThreadId并将Dll模块句柄传递给CallNextHookEx。代码运行良好。除非您确实有令人信服的理由挂接单个进程,否则通常应使用而不是SetWindowsHookEx()
来接收鼠标和键盘输入。顺便提一下,WH_MOUSE
回调通常在安装它的线程的上下文中运行,因此在回调中调用GetCurrentProcessId()
将返回应用程序的进程ID,而不是挂接的应用程序的进程ID。
function MouseProc(code: integer; wParam: WPARAM; lParam: LPARAM)
: LongInt; stdcall;
var
AppWnd: HWND;
begin
Result := 0;
if (code < 0) then
Result := CallNextHookEx(HookHandle, code, wParam, lParam)
else begin
AppWnd := FindWindowW('ichookapplication', nil);
SendMessage(AppWnd, MW_MOUSEHOOKED, wParam, GetCurrentProcessId);
Result := CallNextHookEx(HookHandle, code, wParam, lParam);
end;
end;
procedure HookThreadId(theadId: Cardinal) export; stdcall;
var
e: DWORD;
begin
HookHandle := SetWindowsHookEx(WH_MOUSE, @MouseProc, 0, theadId);
if (HookHandle = 0) then
begin
e := GetLastError;
MessageBox(0, 'error', PAnsiChar(IntToStr(e)), MB_OK);
end;
end;
//loading code
if (dll = 0) then
begin
dll := LoadLibrary('mhook.dll');
@Hook := nil;
@SetThreadHook := nil;
end;
if (dll > HINSTANCE_ERROR) then
begin
pH := GetProcAddress(dll, 'Hook');
@Hook := pH;
pSth := GetProcAddress(dll, 'HookThreadId');
@SetThreadHook := pSth;
end;
// attach code
h := FindWindow(nil, 'Form1');
terminalProc := GetWindowThreadProcessId(h, nil);
if (terminalProc = 0) then
begin
ShowMessage(IntToStr(GetLastError));
Exit;
end;
SetThreadHook(terminalProc);