SetWindowsHookEx冻结我的键盘和鼠标,以及其他奇怪的事情发生

时间:2015-10-13 20:12:48

标签: delphi winapi

我在Delphi中编写笑话程序(发出奇怪的声音,用户使用鼠标或键盘),使用全局挂钩捕获鼠标和键盘事件。
这是负责处理这个钩子的功能:

procedure MKHOOK(code: Integer;wp: wParam;lp: lParam); stdcall;
var
hh: HHOOK;
begin
  PlaySound('fart.wav');
  CallNextHookEx(hh,code,wp,lp);
end;

当Form创建时,Hook开始:

procedure TForm6.FormCreate(Sender: TObject);
begin
   MH := SetWindowsHookEx(WH_MOUSE_LL,@MKHOOK,hInstance,0);
   KH := SetWindowsHookEx(WH_KEYBOARD_LL,@MKHOOK,hInstance,0);
end;

MH和KH是HHOOK的类型 程序结束时删除钩子:

procedure TForm6.FormDestroy(Sender: TObject);
begin
   UnhookWindowsHookEx(MH);
   UnhookWindowsHookEx(KH);
end;

问题开始,当我尝试运行它时会发生奇怪的事情:

  • 鼠标和键盘停止工作,我必须使用ctrl + alt + del来恢复它
  • 程序执行后,当我停止(ctrl,alt,tab)
  • 时,某些键无法正常工作
  • 某些键会改变他们的行为,例如,当我使用箭头键时,他们会转动我的屏幕视图。

这段代码有什么问题?为什么它不起作用?抱歉我的英文;)

1 个答案:

答案 0 :(得分:6)

这里有一些问题。最明显的是:

  • PlaySound的调用过于昂贵,无法挂钩。如果每次执行钩子时调用PlaySound,它都会使系统陷入困境。
  • 您的挂钩签名错误。它们需要是返回LRESULT的函数。在两种情况下,文档中描述了所需的返回值,如下所示:如果nCode小于零,则挂钩过程必须返回CallNextHookEx返回的值。
  • 您不进行任何错误检查。始终检查API调用是否有错误。每个API调用的文档中都讨论了错误处理。

CallNextHookEx的第一个参数会被忽略,因此您也可以通过0。在我看来,使用单独的钩子程序更清晰。

钩子函数必须如下所示:

function MouseHook(code: Integer; wp: wParam; lp: lParam): LRESULT; stdcall;
begin
  Result := CallNextHookEx(0, code, wp, lp);
end;

function KeyboardHook(code: Integer; wp: wParam; lp: lParam): LRESULT; stdcall;
begin
  Result := CallNextHookEx(0, code, wp, lp);
end;

显然,这些钩子还没有做任何事情,但是在我们尝试跑步之前先走吧。

像这样安装钩子:

MH := SetWindowsHookEx(WH_MOUSE_LL, @MouseHook, hInstance, 0);
if MH = 0 then
  // handle error
KH := SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHook, hInstance, 0);
if KH = 0 then
  // handle error

我认为很清楚您没有详细阅读文档。这些API使用起来很棘手。您需要精确编码。我建议您再次仔细阅读文档。