【WPF】 关于在WPF应用中使用Joystick
上个完成的项目中涉及到在WPF应用中获取到游戏摇杆的数据。本文主要针对如何在WPF应用中使用游戏摇杆做一系列介绍,以及在使用过程中可能用得到的一些小提示。
先交代一下我所使用的环境:
OS: Windows 7 Ultimate。
.NET Framework 4.0。
IDE:Visual Studio 2010.
开发语言:XAML + C#;
SDK: DirectX SDK;
要在WPF应用中使用JoyStick, 我的思路是:获取外设—>捕获外设事件—>事件处理。我也是按照这个思路去MSDN上进行资料查阅的,在WPF中没有很具体的解决方案,
但是在CodeProject中找到了一篇比较不错的文章。
“Interfacing with a Joystick using C#”
http://www.codeproject.com/Articles/16704/Interfacing-with-a-Joystick-using-C
文章作者非常详尽的介绍了如何在C#开发中与Joystick交互的方式,并且把一些常用的方法进行了封装,这样我们只需要在项目中引入相应的DLL,就可以方便的和外设进行打交道了。
要使用作者的方法,必须先去下载DirectX SDK。 大概500多M,安装完成后我们需要在项目中引入相应的引用以及using相应的命名空间。在一切准备妥当以后,我们开始第一步,获取外设。
获取外设
获取外设比较简单,因为有DirectX SDK 一起之前Code Project上作者封装的方法,我们只需要在Load方法中使用下面的代码就可以获取到与设备当前相连的的设备。
// grab the joystick jst = new JoystickInterface.Joystick(this.Handle); string[] sticks = jst.FindJoysticks(); jst.AcquireJoystick(sticks[0]);
这时候第一个问题来了,原作者是基于WinFrom进行的开发,WinForm中的窗口是可以通过"this.Handle"的方式获取到窗口句柄的,在WPF中是不可以这么做的,为了解决这个问题,我们需要知道如何在WPF中获取窗口句柄。以前没做过,继续查。最终在StackOverflow上找到方法。
using System.Windows.Interop; new WindowInteropHelper(this).Handle;
于是上面的代码被改写成
// grab the joystick jst = new JoystickInterface.Joystick(new WindowInteropHelper(this).Handle); string[] sticks = jst.FindJoysticks(); jst.AcquireJoystick(sticks[0]);
这样,我们就完成了在WPF中获取Joystick的第一步,获得外设。
获取外设事件
获取外设的事件并没有采用事件侦听的方式,而是采取了DispatcherTimer去轮询的方式获取外设的按钮或者轴当前的状态,我设置的频率是1秒10次,这种速度在普通的开发中应该是绰绰有余的,但是如果要开发需求是对响应时间要求比较高的场合,那显然这种方式是不合理的,如果有人有更好的开发方法,请务必留言,谢谢。
timer的写法:
// get status jst.UpdateStatus(); // update the axes positions foreach (Control ax in flpAxes.Controls) { if (ax is Axis) { switch (((Axis)ax).AxisId) { case 1: ((Axis)ax).AxisPos = jst.AxisA; break; case 2: ((Axis)ax).AxisPos = jst.AxisB; break; case 3: ((Axis)ax).AxisPos = jst.AxisC; break; case 4: ((Axis)ax).AxisPos = jst.AxisD; break; case 5: ((Axis)ax).AxisPos = jst.AxisE; break; case 6: ((Axis)ax).AxisPos = jst.AxisF; break; } }
思路很简单,每隔一个短暂的时间去查询外设的状态,并且把每个轴的数据保存在变量里面,这样我们的程序就可以进行相应的动作了。
上面基本就是WPF应用中获取Joystick的基本方法,比较简略,但是能用。
P.S 下面是两个在使用的时候可能会遇到的问题,这里也一并交代一下。
一个是使用Joystick.dll的时候,启动调试会报一个“正试图在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。”的异常,点击继续其实应用还是可以正常调试的,造成这种现象的原因是因为应用中使用的DirectX SDK是基于.NET 2.0版本开发的,在全新的.NET 4.0环境下很多东西改掉了所以才出这个警告,我们可以通过选择调试-异常-Managed Debug Assisants中勾掉LoaderLock来忽略这个警告。
第二个问题则比较重要,因为我们使用的DirectX SDK是.NET 2.0开发的,所以会出现在4.0下会出现不兼容的情况(微软你赢了),具体表现为开始调试以后应用卡在Load事件之后就不再执行,为了能兼容,我们需要在App.config中添加如下的语句(没有App.config? 请在项目中添加新建项)来完成对老版本dll的兼容。
<startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup>
大体就是这样,写的比较凌乱,谢谢观赏。