【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>

  大体就是这样,写的比较凌乱,谢谢观赏。

posted on 2013-11-17 17:31  令奇  阅读(831)  评论(0编辑  收藏  举报

导航