对游戏手柄进行操作,大概有两种方式:采用系统API或者使用DirectInput操作游戏手柄设备。采用系统API是一种最简单的方式,因为系统已帮我们封装好了所有细节,我们只要在程序中定时取得游戏手柄设备的状态就可以了(轮循)。
操作游戏手柄(杆)的API有以下几个:
函数名称 | 函数说明 |
joyGetNumDevs | 获取当前系统支持的游戏设备数量 |
joyGetDevCaps | 查询获取指定的游戏杆设备以确定其性能 |
joySetCapture | 向系统申请捕获某个游戏设备并定时将该设备的状态值通过消息发送到某个窗口 |
joyReleaseCapture | 释放对某个游戏设备的捕获 |
joyGetPos | 获取游戏设备的坐标位置和按钮状态 |
joyGetPosEx | 获取游戏设备的坐标位置和按钮状态 |
joyGetThreshold | 查询指定的游戏杆设备的当前移动阈值 |
joySetThreshold | 设置指定的游戏杆设备的移动阈值 |
其中,根据调用不同的方法又可分为两种方式。
1)被动方式:
调用joySetCapture方法,向系统申请对某个游戏手柄的捕捉,如果成功申请,系统将会定时将此游戏手柄的状态信息通过消息方式通知到我们的某个窗口上。
2)主动方式:
即是根据我们自己的需要,按需调用joyGetPos或joyGetPosEx方法查询获取某个游戏手柄的当前状态。
我这几天试着用被动方式进行读遥控器,算是失败吧,只能读取XY两个轴的,下面我介绍一下这几天的学习结果。
因为GUAN`LI四通控只有摇杆,所以程序里只用到了LParam参数 ,此参数存储的是游戏手柄的坐标参数,并且此参数的高16位存储的是Y坐标值,低16位存储的是X坐标值。
我这两天一直试图寻找输出 ZW两个轴的坐标值 ,但是没有成功,我得出的结论是 joystick的被动方式无法输出 ZW的坐标值,要 是有知道的希望可以告诉我,不胜感激!
下面介绍一下我的程序,这是截图
软件是有VS2008写的,这是一个示例程序,采集每个摇杆的数值输入到软件,在lable控件中以“+”来动态显示,当然只是为了直观,实际有用的是输出的数值。
程序来源于网络, 因为我是在他源码上做的修改,程序略显冗余。程序这里涉及了C# Graphics 、C# IMessageFilter接口、C# IDisposable接口、C# Message 消息、以及事件和委托等,看懂程序需要一定的C#基础 。
这里我来介绍程序的执行的一个大体过程,有助于理解程序。程序定义了一个事件Click;把joystick_Click注册给了这个事,这个方法是用于显示这一部分的;利用 public bool Register(IntPtr hWnd, int joystickId) 这个方法进行摇杆的注册,和消息的注册; bool IMessageFilter.PreFilterMessage(ref Message m) 这个方法用于处理消息,程序本身也是一直在这里循环,等待消息->处理消息。处理消息也就是调用 Joystick_Clik这个方法用于显示 结果。
这里我再说说我试着找其它消息号的方法,代码如下 :
if (m.Msg != API.MM_JOY1MOVE) ) //我这里是用来查找其它消息号用的,没找到 { Joystick_GL.Form1.msg_id = m.Msg; GetZWStateFromLParam(m.LParam.ToInt32()); }
这里 API.MM_JOY1MOVE 是对应 XY轴的 消息ID ,我用if ()语句给过滤掉。LParam 是坐标参数。通过晃动摇杆观察 Z W的坐标值,这里数值变化太快,可以用Thread.sleep()进行定时即可。
发现无效的ID值 添加if()中。我最终得出的结论就是 joystick的被动方式无法输出 ZW的坐标值,下面我看看被动的方式是否可以 。
这里是我修改的代码:https://files.cnblogs.com/dreamfactory/Joystick_GL.rar
程序参考博客:http://www.cnblogs.com/kingthy/archive/2009/03/25/1421838.html