C#对游戏手柄的编程开发-API篇(1)
对游戏手柄进行操作大概有两种方式采用系统API或者使用DirectInput操作游戏手柄设备。也许还有其它方式但我的知识范围有限其它方式就不得而知了采用系统API是一种最简单的方式因为系统已帮我们封装好了所有细节我们只要在程序中定时取得游戏手柄设备的状态就可以了轮循。操作游戏手柄杆的API有以下几个函数名称函数说明joyGetNumDevs获取当前系统支持的游戏设备数量joyGetDevCaps查询获取指定的游戏杆设备以确定其性能joySetCapture向系统申请捕获某个游戏设备并定时将该设备的状态值通过消息发送到某个窗口joyReleaseCapture释放对某个游戏设备的捕获joyGetPos获取游戏设备的坐标位置和按钮状态joyGetPosEx获取游戏设备的坐标位置和按钮状态joyGetThreshold查询指定的游戏杆设备的当前移动阈值joySetThreshold设置指定的游戏杆设备的移动阈值其中根据调用不同的方法又可分为两种方式。1被动方式调用joySetCapture方法向系统申请对某个游戏手柄的捕捉如果成功申请系统将会定时将此游戏手柄的状态信息通过消息方式通知到我们的某个窗口上。2主动方式即是根据我们自己的需要按需调用joyGetPos或joyGetPosEx方法查询获取某个游戏手柄的当前状态。而在本篇中我们要讲解的只是“被动方式”。joySetCapture方法的C#定义原型如下///summary///向系统申请捕获某个游戏杆并定时将该设备的状态值通过消息发送到某个窗口////summary///param namehWnd窗口句柄/param///param nameuJoyID指定游戏杆(0-15)它可以是JOYSTICKID1或JOYSTICKID2/param///param nameuPeriod每隔给定的轮询间隔就给应用程序发送有关游戏杆的信息。这个参数是以毫妙为单位的轮询频率。/param///param namefChanged是否允许程序当操纵杆移动一定的距离后才接受消息/param///returns/returns[DllImport(winmm.dll)]publicstaticexternintjoySetCapture(IntPtr hWnd,intuJoyID,intuPeriod,boolfChanged);当我们调用此方法向系统申请捕获某个游戏手柄后如果成功则返回JOYERR_NOERROR(值为0)否则返回其它值的话表示申请失败。并且在不再需要捕获游戏手柄时要记得调用joyReleaseCapture方法释放捕捉。如果申请成功系统将会定时根据uPeriod的值决定时间的长短将游戏手柄的状态以消息包形式发送到hWnd对应的窗口界面。所以我们必须要在程序中处理对应的消息如重写WndProc方法进行处理。并且根据不同的uJoyID值系统发送的消息号又会有所不同如对于JOYSTICKID1系统将会分别发送以下消息包消息号说明MM_JOY1MOVE当手柄的位置已变动或按了某些按钮时将会发送此消息包。MM_JOY1BUTTONDOWN当手柄的ABCD四个按钮中的一个或多个正被按下时将会发送此消息包。MM_JOY1BUTTONUP当手柄的ABCD四个按钮中的一个或多个正被弹起时将会发送此消息包。而对于JOYSTICKID2系统发出的消息包分别为MM_JOY2MOVE、MM_JOY2BUTTONDOWN、MM_JOY2BUTTONUP并且要注意不管你有没有按游戏手柄上的按钮系统也会定时发送MM_JOYXMOVE消息怎样判断按了哪些键在消息包中游戏手柄的状态信息按钮状态分别存储在消息包中的WParam与LParam参数。1)WParam参数对于游戏手柄来说WParam存储的是除了上下左右四个方向键之外的所有按钮中当前被按下的按钮值它的值是一个复合值。如它的值为JOY_BUTTON1 | JOY_BUTTON2时就表明按下的按键是1号和2号按钮。注意对于MM_JOYXBUTTONDOWN与MM_JOYXBUTTONUP两个消息用于判断的按钮值是不同于MM_JOYXMOVE的按钮值2)LParam参数此参数存储的是游戏手柄的坐标参数并且此参数的高16位存储的是Y坐标值低16位存储的是X坐标值。而对于游戏手柄来说判断上下左右四个方向键有没有被按下就是通过此参数进行判断的。如果当四个方向键都没有被按下时表示当前游戏手柄处于中心坐标中也就是XY坐标都是在中心点位置上而当某些方向键被按下时XY坐标将根据所按的键向对应方向偏移。如当按了向右键则X坐标向右偏移Y坐标保持在中心点位置而如果按了右、上两个方向键同时按下则X坐标向右偏移Y坐标向上偏移。所以我们可以根据LParam参数取得XY坐标的值然后再根据其中心点来判断。参考代码如下///summary///获取X,Y轴的状态////summary///param namelParam/param///param namebuttons/paramprivatevoidGetXYButtonsStateFromLParam(intlParam,refJoystickButtons buttons){//处理X,Y轴intxlParam0x0000FFFF;//低16位存储X轴坐标inty(int)((lParam0xFFFF0000)16);//高16位存储Y轴坐标(不直接移位是为避免0xFFFFFF时的情况)intm0x7EFF;//中心点的值if(xm){buttons|JoystickButtons.Right;}elseif(xm){buttons|JoystickButtons.Left;}if(ym){buttons|JoystickButtons.Down;}elseif(ym){buttons|JoystickButtons.UP;}}好了对游戏手柄的“被动方式”编程就讲解完成了剩下的就是要怎么利用游戏手柄来实现模拟键盘或鼠标的操作了……