XNA-键盘文本输入好的,基本上我希望能够检索键盘文本。就像在文本字段中输入文本之类的。我只是在为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的虚拟键代码转换为char。我收到我的短信了!(我现在只是用Debug.Write打印)但是有一些问题。好像我有大写锁定但没有响应式shift键。(当然不是,它每个键只有一个虚拟键码,所以只有翻译它有一个输出)并且它增加了开销,因为它将自己附加到WindowsHook列表并且没有我想要的那么快,但由于Debug.Write,可能会更慢。有没有其他人在不必求助于屏幕键盘的情况下解决了这个问题?或者有人有进一步的想法让我尝试吗?提前致谢。Jimmy提出的问题也许我不明白这个问题,但为什么不能使用XNAKeyboard和KeyboardState类?我的评论:这是因为虽然您可以读取键状态,但您无权访问键入的文本以及用户输入文本的方式。所以让我进一步澄清。我想实现能够读取用户的文本输入,就好像他们在Windows的文本框中输入一样。Keyboard和KeyboardState类获取所有键的状态,但我必须将每个键和组合映射到它的字符表示。当用户不使用与我专门使用符号相同的键盘语言时,这会失败(我的双引号是shift+2,美国键盘在返回键附近有它们的位置)。似乎我的窗口挂钩是可行的方法,只是我没有得到WM_CHAR的原因是因为XNA消息泵没有执行翻译消息。每当我收到WM_KEYDOWN消息时添加TranslateMessage意味着我收到WM_CHAR消息,然后我使用它在我的MessageHuff类中发出字符类型事件,我的KeyboardBuffer类已订阅,然后将其缓存到文本缓冲区中:D(还是StringBuilder,但结果是一样的)所以我想怎么干就怎么干。非常感谢Jimmy提供了非常有用的链接。也许我无法理解这个问题,但是为什么你不能使用XNAKeyboard和KeyboardState类?使用System.Collections.Generic;使用System.Linq;使用系统文本;使用System.Runtime.InteropServices;使用系统诊断;使用System.Reflection;/*作者:Sekhat**许可证:公共领域。**用法:**从此类继承,并覆盖派生类中的WndProc函数,*在其中处理Windows消息。**要开始接收消息,请创建您的派生类的一个实例,传入您要侦听消息的窗口的*窗口句柄。**在XNA中:这将是Game.Window.Handle属性*在WinformsForm.Handle属性中*/namespaceWindowsHookExample{publicabstractclassWindowsHook:IDisposable{IntPtrhHook;IntPtrhWnd;//存储在这里以阻止它被垃圾收集Win32.WndProcDelegatewndProcDelegate;publicWindowsHook(IntPtrhWnd){this.hWnd=hWnd;wndProc委托=WndProcHook;创建钩子();}~WindowsHook(){处置(假);}privatevoidCreateHook(){uintthreadId=Win32.GetWindowThreadProcessId(hWnd,IntPtr.Zero);hHook=Win32.SetWindowsHookEx(Win32.HookType.WH_CALLWNDPROC,wndProcDelegate,IntPtr.Zero,threadId);}privateintWndProcHook(intnCode,IntPtrwParam,refWin32.MessagelParam){if(nCode>=0){Win32.TranslateMessage(reflParam);//你可能想删除这一行,如果你发现你没有得到正确的消息。这是为了在按下某个键时正确调用WM_CHAR。WndProc(reflParam);}返回Win32.CallNextHookEx(hHook,nCode,wParam,reflParam);}protectedabstractvoidWndProc(refWin32.Message消息);#regionInteropStuff//我对P/Invoke.net说声谢谢。//包含我需要处理的所有Win32函数protectedstaticclassWin32{publicenumHookType:int{WH_JOURNALRECORD=0,WH_JOURNALPLAYBACK=1,WH_KEYBOARD=2,WH_GETMESSAGE=3,WH_CALLWNDPROC=4,WH_CBT=5,WH_SYSMSGFILTER=6,WH_MOUSE=7,WH_HARDWARE=8,WH_DEBUG=9,WH_SHELL=10,WH_FOREGROUNDIDLE=11,WH_CALLWNDPROCRET=12,WH_1KEYBOARD_LL=公共}结构消息{publicIntPtrlparam;公共IntPtrwparam;公共uint消息;公共IntPtrhWnd;}//////定义传递给windows钩子的windowsproc委托///publicdelegateintWndProcDelegate(intnCode,IntPtrwParam,refMessagem);[DllImport("user32.dll",SetLastError=true,CharSet=CharSet.Auto)]publicstaticexternIntPtrSetWindowsHookEx(HookTypehook,WndProcDelegatecallback,IntPtrhMod,uintdwThreadId);[DllImport("user32.dll",SetLastError=true,CharSet=CharSet.Auto)]publicstaticexternboolUnhookWindowsHookEx(IntPtrhhk);[DllImport("user32.dll",SetLastError=true,CharSet=CharSet.Auto)]publicstaticexternintCallNextHookEx(IntPtrhhk,intnCode,IntPtrwParam,refMess年龄m);[DllImport("coredll.dll",SetLastError=true)]publicstaticexternIntPtrGetModuleHandle(stringmodule);[DllImport("user32.dll",EntryPoint="TranslateMessage")]publicexternstaticboolTranslateMessage(refMessagem);[DllImport("user32.dll")]publicexternstaticuintGetWindowThreadProcessId(IntPtrwindow,IntPtrmodule);}#endregion#regionIDisposable成员publicvoidDispose(){Dispose(true);}privatevoidDispose(booldisposing){if(disposing){//在此处释放托管资源}//在此处释放非托管资源if(hHook!=IntPtr.Zero){Win32.UnhookWindowsHookEx(hHook);我使用了gamedev.netpost的这个解决方案,它很棒:)这是一个简单的方法,IMO,带有空格、back、AZ,然后是特殊字符!、@、#、$、%、%、^,&,*,(,)(注意,您需要导入System.Linq)以下是字段:Keys[]keys;布尔[]IskeyUp;string[]SC={")","!","@","#","$","%","^","&","*","("};//特殊字符构造函数:keys=newKeys[38];Keys[]tempkeys;tempkeys=Enum.GetValues(typeof(Keys)).Cast().ToArray();intj=0;for(inti=0;i26&&i最后,更新方法:stringresult="";publicoverridevoidUpdate(GameTimegameTime){KeyboardStatestate=Keyboard.GetState();inti=0;foreach(Keyskeyinkeys){if(state.IsKeyDown(key)){if(IskeyUp[i]){if(key==Keys.Back&&result!="")result=result.Remove(result.Length-1);if(key==Keys.Space)结果+="";if(i>1&&i11&&i希望对你有所帮助。我个人认为它比钩子更容易使用,这也使得修改特殊结果(如洗牌)变得容易。此页面是关于谷歌搜索结果关于xna中的WM_CHAR拦截,所以我在这里留下一些警告。也许它对其他人有用(如果他们能理解我的英语=)))。我尝试使用Sekhat的windowshook代码,但似乎应该将WH_GETMESSAGE传递给SetWindowsHookEx而不是Win32.HookType.WH_CALLWNDPROC(仅使用WH_GETMESSAGE代码,lparaw将指向Win32.Message)。还有一些重复的消息(wparam0)。(看这里-http://msdn.microsoft.com/en-us/library/ms644981%28v=VS.85%29.aspx关于WPARAM中的PM_NOREMOVE/PM_REMOVE)当我添加这样的东西时if(nCode>=0&&wParam==1){Win32.TranslateMessage(reflParam);WndProc(reflParam);}wm_keypresswm_char重复停止(我认为1是PM_NOREMOVE或PM_REMOVE)。PSnuclex变体现在显示404页面,但可以使用webarchive查看。nuclex变体有效,但是会导致mouseWheelhandlingbreakfromnativeXNAMouseState(onXNA3.1)handling=(以上就是C#学习教程的全部内容:XNA-Keyboardtextinputsharing,如果对大家有用需要的话了解更多C#学习教程,希望大家多加关注---本文采集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除。如有转载请注明出处:
