【问题标题】:Delphi block Keyboard & MouseDelphi 块键盘和鼠标
【发布时间】:2016-06-22 07:14:57
【问题描述】:

如何分别屏蔽键盘和鼠标?我尝试了 BlockInput,它在 Windows 10 中不起作用,还尝试如下:

function KBHookHandler(ACode: Integer; WParam: WParam; LParam: LParam)
  : LResult; stdcall;
begin
  if ACode < 0 then
    // Immediately pass the event to next hook
    Result := CallNextHookEx(Hook, ACode, WParam, LParam)
  else
    // by setting Result to values other than 0 means we drop/erase the event
    Result := 1;
end;

function DisableKeyboard : boolean;
begin
  if Hook = 0 then
    // install the hook
    // Hook := SetWindowsHookEx(WH_KEYBOARD, @KBHookHandler, HINSTANCE, 0);
    Hook := SetWindowsHookEx(WH_KEYBOARD, @KBHookHandler, 0, 0);
  Result := Hook <> 0;
end;

我的要求是在 Windows 7、Windows 8 和 Windows 10 中分别屏蔽键盘和鼠标。

【问题讨论】:

  • 显示minimal reproducible example。解释运行此代码的上下文。解释你期望发生的事情。解释发生了什么。告诉我们您进行了哪些调试以及透露了哪些信息。
  • 使用 BlockInput 没有发生任何事情,使用代码也没有发生任何事情。它必须禁用键盘才能不写或不使用键盘做任何事情。
  • 你没有解决我评论中的任何问题。哦,好吧。
  • 再一次,你在我的评论中没有解决一个问题。我放弃了。
  • 明显的问题 - 此代码是在应用程序还是 DLL 中?这(部分)是大卫所说的最小、完整和可验证的例子——你必须展示一个完整的上下文——我们可以自己编译来看看你的意思。

标签: delphi keyboard mouse vcl


【解决方案1】:

你在 Embarcadero 的 Delphi NativeAPI forum 上发布了同样的问题,所以我会给你和我在那里发布的相同的答案。

阻止鼠标和键盘分开的唯一方法是使用单独的键盘和鼠标钩子。

BlockInput() 在 Windows 10 上工作。但它会阻止所有输入,你不能选择性地使用它。

当挂钩除您自己之外的其他进程时,您的挂钩必须在 DLL 中,并且您必须将 DLL 的 hinstance 传递给 SetWindowsHookEx() 的第三个参数:

如果 hMod 参数为 NULL 并且 dwThreadId 参数为零或指定由另一个进程创建的线程的标识符,则可能会发生错误。

通过为hMod 指定0,回调将只在调用进程中起作用,因为这是唯一可以访问回调的进程。当您将dwThreadId 参数设置为0 以全局挂钩多个线程时,hMod 必须指向可以注入其他进程的DLL。

此外,您可能需要单独的 32 位和 64 位 DLL 才能分别正确地挂接 32 位和 64 位进程。但是一定要确保安装钩子的线程有一个消息循环:

这个钩子可以在安装它的线程的上下文中被调用。通过向安装钩子的线程发送消息来进行调用。因此,安装钩子的线程必须有一个消息循环。

因为钩子在应用程序的上下文中运行,它们必须与应用程序的“位数”相匹配。如果 32 位应用程序在 64 位 Windows 上安装全局挂钩,则 32 位挂钩将被注入到每个 32 位进程中(通常的安全边界适用)。在 64 位进程中,线程仍被标记为“已挂钩”。但是,由于 32 位应用程序必须运行钩子代码,系统会在钩子应用程序的上下文中执行钩子;具体来说,在调用 SetWindowsHookEx 的线程上。这意味着挂钩应用程序必须继续发送消息,否则可能会阻止 64 位进程的正常运行。

如果 64 位应用程序在 64 位 Windows 上安装全局挂钩,则 64 位挂钩会注入到每个 64 位进程中,而所有 32 位进程都使用挂钩应用程序的回调。

要在 64 位 Windows 安装的桌面上挂钩所有应用程序,请安装一个 32 位全局挂钩和一个 64 位全局挂钩,每个挂钩都来自相应的进程,并确保在挂钩应用程序中不断发送消息到避免阻碍正常运作。如果您已经有一个 32 位全局挂钩应用程序并且它不需要在每个应用程序的上下文中运行,您可能不需要创建 64 位版本。 {quote}

您无法锁定整个系统的原因是因为您一开始就没有正确连接整个系统。

【讨论】:

  • 我确实制作了一个如下的 DLL,但它仍然只适用于我的应用程序而不是整个系统:function KBHookHandler(ACode: Integer; WParam: WParam; LParam: LParam) : LResult;标准调用; begin if ACode 0;结束;
  • @shariful 您仅将挂钩安装到调用线程中,而不是全局安装。 SetWindowsHookEx() 的最后一个参数必须为 0 才能用于全局挂钩。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 2019-02-13
  • 1970-01-01
  • 1970-01-01
  • 2014-05-19
相关资源
最近更新 更多