好的,基本上我想要能够检索键盘文本。就像输入文本到文本框或其他东西一样。我只为Windows编写我的游戏。
我忽略了使用Guide.BeginShowKeyboardInput,因为它破坏了自包含游戏的感觉,并且指南始终显示XBOX按钮,这对我来说似乎不正确。是最简单的方法,但我不喜欢它。
接下来,我尝试使用System.Windows.Forms.NativeWindow。我创建了一个从中继承的类,传递了Games窗口句柄,实现了WndProc函数以捕获WM_CHAR(或WM_KEYDOWN),尽管WndProc为其他消息调用,但WM_CHAR和WM_KEYDOWN从未调用过。所以我不得不放弃那个想法,而且,我还引用了整个Windows表单,这意味着不必要的内存占用膨胀。
所以我最后的想法是创建一个线程级别的低级键盘钩子。到目前为止,这是最成功的。我得到WM_KEYDOWN消息(还没有尝试WM_CHAR),使用Win32函数MapVirtualKey将虚拟键码转换为字符。然后我得到了我的文本!(我现在只是使用Debug.Write打印)
有几个问题。好像我开启了大写锁定,并且Shift键没有响应。 (当然不是,因为每个键只有一个虚拟键码,所以翻译它只有一个输出),并且它会添加开销,因为它附加到Windows挂钩列表并且不如我希望的那么快,但缓慢可能更多是由于Debug.Write。
还有其他人解决了这个问题而不必使用屏幕键盘吗?或者有没有其他想法让我尝试?
提前感谢。
Jimmy提出的问题
也许我没有理解问题,但为什么您不能使用XNA Keyboard和KeyboardState类?
我的评论:
这是因为尽管您可以读取按键状态,但无法按照用户输入文本的方式获取对其进行访问。
因此,让我进一步澄清。我想要实现能够从用户那里读取文本输入,就好像他们正在Windows中键入文本框一样。键盘和KeyboardState类获取所有键的状态,但我必须将每个键和组合映射到其字符表示形式。当用户不使用与我相同的键盘语言时,特别是在符号方面时,这种情况就会发生(我的双引号是Shift + 2,而美国键盘则在返回键附近)。
似乎我的窗口挂钩是正确的方法,只是我没有收到WM_CHAR的原因是XNA消息泵不会翻译消息。
每当我收到WM
所以我已经按照自己的想法使其全部工作。
非常感谢Jimmy提供的非常有信息量的线程链接。
接下来,我尝试使用System.Windows.Forms.NativeWindow。我创建了一个从中继承的类,传递了Games窗口句柄,实现了WndProc函数以捕获WM_CHAR(或WM_KEYDOWN),尽管WndProc为其他消息调用,但WM_CHAR和WM_KEYDOWN从未调用过。所以我不得不放弃那个想法,而且,我还引用了整个Windows表单,这意味着不必要的内存占用膨胀。
所以我最后的想法是创建一个线程级别的低级键盘钩子。到目前为止,这是最成功的。我得到WM_KEYDOWN消息(还没有尝试WM_CHAR),使用Win32函数MapVirtualKey将虚拟键码转换为字符。然后我得到了我的文本!(我现在只是使用Debug.Write打印)
有几个问题。好像我开启了大写锁定,并且Shift键没有响应。 (当然不是,因为每个键只有一个虚拟键码,所以翻译它只有一个输出),并且它会添加开销,因为它附加到Windows挂钩列表并且不如我希望的那么快,但缓慢可能更多是由于Debug.Write。
还有其他人解决了这个问题而不必使用屏幕键盘吗?或者有没有其他想法让我尝试?
提前感谢。
Jimmy提出的问题
也许我没有理解问题,但为什么您不能使用XNA Keyboard和KeyboardState类?
我的评论:
这是因为尽管您可以读取按键状态,但无法按照用户输入文本的方式获取对其进行访问。
因此,让我进一步澄清。我想要实现能够从用户那里读取文本输入,就好像他们正在Windows中键入文本框一样。键盘和KeyboardState类获取所有键的状态,但我必须将每个键和组合映射到其字符表示形式。当用户不使用与我相同的键盘语言时,特别是在符号方面时,这种情况就会发生(我的双引号是Shift + 2,而美国键盘则在返回键附近)。
似乎我的窗口挂钩是正确的方法,只是我没有收到WM_CHAR的原因是XNA消息泵不会翻译消息。
每当我收到WM
_
KEYDOWN消息时,添加TranslateMessage意味着我得到了我的WM_CHAR消息,然后我在我的MessageHook类中使用它来触发一个字符键入事件,我的KeyboardBuffer类已经订阅了该事件,然后将其缓冲到文本缓冲区:D(或StringBuilder,但结果是相同的)。所以我已经按照自己的想法使其全部工作。
非常感谢Jimmy提供的非常有信息量的线程链接。