【问题标题】:SetWindowsHookEx() WM_KEYBOARD_LL not coming through with full screen RDCSetWindowsHookEx() WM_KEYBOARD_LL 没有通过全屏 RDC
【发布时间】:2013-01-30 03:19:16
【问题描述】:

我正在尝试做一个像 Skype 这样的客场计时器风格的东西。如果用户“离开”了一段时间,我会触发一些东西。我一直在将 SetWindowsHookEx() 与 WM_KEYBOARD_LL 一起使用,效果很好。直到您打开 RDC 连接并使其全屏显示。然后我永远不会得到键盘事件。

有人遇到过这个吗?或者知道实现这一目标的更好方法?我实际上已经测试了 Skype,并且使用全屏 RDC,如果我输入 RDC,它将正确地从 Away 转到 Online。

谢谢

编辑:在 Raymond Chen 发表评论后,我做了一些测试,他是对的。不敢相信,经过一番搜索,我从未找到过这种方法。它还解决了我遇到的 WPF 应用程序未触发 LL_Mouse/KEYBOARD 事件的问题。

再次感谢。基于此更新我接受的答案。如果您需要做 LL_MOUSE/KWYBOARD,另一个答案仍然很好。

【问题讨论】:

    标签: winapi setwindowshookex


    【解决方案1】:

    看看GetLastInputInfo()。尝试定期调用它。

    【讨论】:

      【解决方案2】:

      是的。您不会在远程桌面中按下按键。我遇到了这个问题,我找到的唯一解决方案是:

      使用 FindWindow API 始终查找 RDP 窗口,如果您检测到已创建全屏 RDP 窗口,您应该这样做:

      a) 解开所有挂钩。 b) 重置所有钩子。

      因此,创建一个调用 SetWindowHookEx API 的函数,并将其称为 SetHook 和另一个作为 UnHook 函数。然后在发现用户进入远程桌面时重新调用它们。

      现在您甚至可以在远程桌面连接中按下按键。

      我找到了我的旧代码,我做了这样的事情:

      创建了一个 1 秒的计时器。 那么

      std::string tmp;
      HWND hParent = ::FindWindow(TEXT("TSHELLHWND"), NULL);
      GetWindowString(hParent, tmp);
      
      ix = za.find(" - Remote Desktop");
      
      if (hParent != NULL && ix != string::npos)
      RestartHook();
      

      您还应该在重新启动钩子时设置一个全局变量,否则它将一直重新启动钩子。当窗口关闭时,您可以重置该全局变量。

      【讨论】:

      • 好的,谢谢。那确实奏效了。虽然我也发现了一种稍微不同的方式。我使用带有 SetWinEventHook() 的 EVENT_SYSTEM_FOREGROUND 事件来获取窗口变化的通知,然后使用 OpenInputDesktop() 来查看桌面是否已更改
      • 太棒了,这也是个好技巧。正如我所说,那是我非常古老的代码,那天我自己发现了这种方式,我厌倦了在整个互联网上搜索它,但没有找到解决方案。它可以追溯到 2006 年左右。但很高兴它仍然有效并解决了您的问题。
      • 是的,最大的提示是您必须重置桌面更改的挂钩。我没有发现任何其他东西告诉我!再次感谢。
      • 这仅在 两个 应用程序使用此技巧之前有效。然后他们最终为了成为“第一”而互相争斗。如另一个答案所述,正确的解决方案是 GetLastInputInfo。
      • 该 API 不会返回按下的键,并且最终也会像每 100 毫秒一样调用该 API 以捕获用户的输入,这会耗尽进程内存,这不是一个好主意
      猜你喜欢
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多