【问题标题】:Understanding how to use Windows Hooks了解如何使用 Windows 挂钩
【发布时间】:2014-03-03 20:24:24
【问题描述】:

我试图在某些过程中使用 SetWindowsHookEx 来挂钩鼠标。我正在使用德尔福 7。 代码(DLL):

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;

MW_MOUSEHOOKED 是 WM_USER + 101;

应用:

//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);

所以。 SetWindowsHookEx 返回 1428 错误:无法在没有模块句柄的情况下设置非本地挂钩。 但据我所知,如果我不需要使用 dll hmodule... 我希望它如何工作: 每个鼠标事件都会使用 WM_DATA(wParam 是事件数据,lParam 是 ProcessId)传递给我的应用程序(窗口类是 'ichookapplication')

谢谢!

【问题讨论】:

  • 除非你真的有令人信服的理由来挂钩单个进程,否则通常应该使用Raw Input 而不是SetWindowsHookEx() 来接收鼠标和键盘输入。顺便说一句,WH_MOUSE 回调通常在安装它的线程的上下文中运行,因此在回调中调用 GetCurrentProcessId() 将返回应用的进程 ID,而不是被挂钩的应用的进程 ID。

标签: delphi winapi hook setwindowshookex


【解决方案1】:

WH_MOUSE 是一个全局钩子。 DLL 将被注入到钩子进程中。您确实需要提供模块句柄。与错误代码 1428 关联的名称非常清楚,ERROR_HOOK_NEEDS_HMOD。提供模块句柄并不难。通过HInstance.

如果您不想注入,则需要使用WH_MOUSE_LL 而不是WH_MOUSE

【讨论】:

  • 谢谢!我修改 HookThreadId 并将 Dll 模块句柄传递给 CallNextHookEx。代码运行良好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-29
  • 2011-06-28
  • 2015-10-18
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多