参考学习博客:http://www.cnblogs.com/kingthy/archive/2009/03/28/1424055.html
看了这一篇博客,直接用了上文的例子,发送数据的确会遇到发送n多消息这个问题,所以想方法解决一下,顺便记录一下。
主动方式:按自己的需要去获取游戏手柄的状态信息。
需要用到如下的API函数 joyGetPos和joyGetPosEx,因为joyGetPos只能获取到1、2、3、4按钮的状态,所以使用joyGetPosEx函数
MMRESULT joyGetPosEx( UINT uJoyID, LPJOYINFOEX pji );
uJoyID
要查询的操纵杆的标识。有效值uJoyID范围从零(JOYSTICKID1)15。
PJI
指针到一个joyInfoEx结构包含扩展的位置信息和导航键的按键状态。你必须设置的dwSize和dwFlags中成员或joyGetPosEx,否则将失败。从返回的信息joyGetPosEx取决于你在指定的标志dwFlags中。
joyInfoEx结构体如下
typedef struct joyinfoex_tag { DWORD dwSize; DWORD dwFlags; DWORD dwXpos; DWORD dwYpos; DWORD dwZpos; DWORD dwRpos; DWORD dwUpos; DWORD dwVpos; DWORD dwButtons; DWORD dwButtonNumber; DWORD dwPOV; DWORD dwReserved1; DWORD dwReserved2; } JOYINFOEX;
换成C#中的代码可以写成如下:
[StructLayout(LayoutKind.Sequential)] //顺序布局 public struct JOYINFOEX { /// <summary> /// Size, in bytes, of this structure.//大小,以字节为单位 /// </summary> public int dwSize; /// <summary> /// Flags indicating the valid information returned in this structure. Members that do not contain valid information are set to zero.标志,指示在该结构返回的有效信息。构件不包含有效信息被设定为零 /// </summary> public int dwFlags; /// <summary> /// Current X-coordinate. /// </summary> public int dwXpos;//X坐标 /// <summary> /// Current Y-coordinate. /// </summary> public int dwYpos; /// <summary> /// Current Z-coordinate. /// </summary> public int dwZpos; /// <summary> /// Current position of the rudder or fourth joystick axis. /// </summary> public int dwRpos; /// <summary> /// Current fifth axis position. /// </summary> public int dwUpos; /// <summary> /// Current sixth axis position. /// </summary> public int dwVpos; /// <summary> /// Current state of the 32 joystick buttons. The value of this member can be set to any combination of JOY_BUTTONn flags, where n is a value in the range of 1 through 32 corresponding to the button that is pressed.当前32个按钮的状态 /// </summary> public int dwButtons; /// <summary> /// Current button number that is pressed. //当前那些按钮被按下 /// </summary> public int dwButtonNumber; /// <summary> /// Current position of the point-of-view control. Values for this member are in the range 0 through 35,900. These values represent the angle, in degrees, of each view multiplied by 100. /// </summary> public int dwPOV; /// <summary> /// Reserved; do not use. /// </summary> public int dwReserved1; /// <summary> /// Reserved; do not use. /// </summary> public int dwReserved2; }
如果我们要使用joyGetPosEx来获取游戏设备的状态,我们必须先初始化JOYINFOEX结构实例,并要设置dwSize的值。也即是JOYINFOEX结构体所占用的内存空间大小(其值可通过Marshal.SizeOf求得)。而如果要取得游戏设备的其它参数,则还必须要设置dwFlags参数的值!dwFlag标志的值有如下一些;
我们设置为JOY_RETURNBUTTONS
示例代码:
JoystickAPI.JOYINFOEX infoEx = new JoystickAPI.JOYINFOEX(); infoEx.dwSize = Marshal.SizeOf(typeof(JoystickAPI.JOYINFOEX)); infoEx.dwFlags = (int)JoystickAPI.JOY_RETURNBUTTONS; int result = JoystickAPI.joyGetPosEx(this.Id, ref infoEx);
如果joyGetPosEx函数获取手柄状态数据成功,则返回JOYERR_NOERROR(值为0),否则返回其它值的话表示获取失败。
当数据获取成功后,对应的游戏手柄的状态数据都已存储在JOYINFOEX结构实例中了。如要判断是否按下了方向键,则可判断dwXPos与dwYPos的值;而判断是否按了其它按钮,则可判断dwButtons的值。
因为“主动方式”的“时效性”只有一次,所以为了能够随时监视到游戏手柄的按键事件,就必须进行“轮循”获取,当监视到游戏手柄有按键发生时就进行事件通知(噫?好像“被动方式”?嗯,其实当我们向系统申请捕捉某个游戏手柄时,系统最后也是在帮我们进行“轮循”操作!)。而实现“轮循”的方式则可以有多种方式,比如采用独立的线程进行一个死循环;或者采用Timer进行定时执行。
还是会遇到那个发送多个数据的问题,以后解决重复状态的问题。
这篇文章参考了网上的其他大神的文章,里面很少自己写的,旨在记录学习过程,希望能帮到你们,一起探讨