1

我正在为游戏的附加组件开发一个界面。我不能使用游戏 API(有几个原因,包括代码必须与游戏无关),我需要从用户那里获取键盘输入,所以我决定使用键盘挂钩 (WH_KEYBOARD) 来处理用户满足特定条件时输入。
问题是,虽然我可以正确接收和处理输入,但当我的钩子返回 TRUE 而不是CallNextHookEx时,系统似乎需要花费大量时间(远超过 800 毫秒)才能让事情按预期进行,这是不可接受的,因为它甚至不允许流畅的打字体验。
我必须实现的是阻止按键消息到达 WndProc,所以问题是:我可以做些什么来实现我的目标,而不会对游戏性能造成太大影响,以至于结果将是不可接受的?
编辑:由于特定要求(使用反作弊的游戏,尽管它与作弊无关,但可能会对我的代码造成问题)对活动的 wndproc 进行子类化不是一种选择。

4

4 回答 4

2
  1. 首先,您需要通过挂钩或任何其他方式将您的 DLL 注入目标进程。

  2. 找到感兴趣的窗口句柄。

  3. 调用GetWindowLongPtr(wnd, GWLP_WNDPROC)获取该窗口的当前窗口过程,并保存。

  4. 通过调用 SetWindowLongPtr( wnd, GWLP_WNDPROC, &NewWndProc ) 对窗口进行子类化,其中 NewWndProc 是您的 DLL 实现的消息过程。

在 NewWndProc 中,您需要处理键盘消息(有十几个,在 MSDN 索引中键入“键盘输入”,我不能发布超过 1 个链接)。对于其余的 windows 消息,调用您在 (3) 中保存的原始窗口过程,并返回它返回的值。不要直接调用它,而是使用 CallWindowProc 。

这种方式不是很可靠,一些杀毒和反bot(例如“warden client”)软件可能不喜欢它,调试可能会很困难。

但是它应该工作。

于 2009-06-27T15:43:50.393 回答
0

键盘钩子不应该让事情变得那么慢。可能还有其他原因导致 800 毫秒延迟。如果你的钩子什么都不做并且只返回 TRUE,它仍然很慢吗?

于 2009-06-27T15:52:34.877 回答
0

如果您想阻止消息到达 WndProc,那么您需要使用SetWindowLong进行子类化,这样您将能够捕获所有消息并决定是否继续它们的路由。

于 2009-06-27T20:03:18.067 回答
0

尽管我不喜欢回答自己的问题,但我已经找到了延迟的原因。我测试过我的代码的游戏的消息泵是用一段时间(PeekMessage){GetMessage...}实现的,并且以某种方式删除键盘输入消息会导致GetMessage阻塞一段时间。使用 PostMessage 和 WM_NULL 有助于防止 GetMessage 阻塞。

于 2009-06-28T20:07:04.470 回答