我现在所知道的获取游戏杆输入的方法有4种,第4种才是我要说的正题。

1.用DDK通过USB接口直接访问游戏杆

2.通过汇编访问游戏杆

据说在NT下不能这么用了

3.用Direct Input

也许会很方便,但我对之不感兴趣也不了解,这里只是提一下。不过这个方法似乎比其他的都完善些,以后有空再研究。

4.用Windows API

在DDK的文档中,查到几个关于joystick的API,在winmm.dll中(受我查到的第一份资料误导,我还以为只能用DDK来做,早知道就去查MSDN了)。要使用这几个API,VC下编程时,需要连接winmm.lib,包含mmsystem.h头文件;Delphi下编程时需在uses子句中加上mmsystem单元。这几个API的作用:

joyGetDevCaps                  查询指定的游戏杆设备以确定其性能

joyGetNumDevs                  返回系统支持的游戏杆设备的数量

joyGetPos                       查询指定的游戏杆设备的位置和活动性

joyGetPosEx                    查询一个游戏杆设备的位置和它的按扭状态

joyGetThreshold                查询指定的游戏杆设备的当前移动阈值

joyReleaseCapture              释放由JoySetCapture函数设置的在指定游戏杆设备上的捕获

joySetCapture                  发送一个游戏杆消息到指定的窗口

joySetThreshold                设置指定的游戏杆设备的移动阈值

用这些API访问游戏杆,主要有两种方式:消息和轮询。

消息:

使用joySetCapture函数,使指定的窗口接受游戏杆的消息。

JoySetCapture定义:

MMRESULT joySetCapture(HWND hwnd, UINT uJoyID, UINT uPeriod,BOOL fChanged);

[1] hwnd -----父窗口句柄。

[2] uJoyID ----指定游戏杆,它可以是JOYSTICKID1或JOYSTICKID2,即第一、第二个游戏杆。

[3] uPeriod ----每隔给定的轮询间隔就给应用程序发送有关游戏杆的信息。这个参数是以毫秒为单位的轮询间隔时间。

[4]  fChanged ----改变位置标识,可设为false。

返回值:

/* joystick error return values */

#define JOYERR_NOERROR  (0)                /* no error */

#define JOYERR_PARMS    (JOYERR_BASE+5)  /* bad parameters */

#define JOYERR_NOCANDO  (JOYERR_BASE+6)  /*request not completed */

#define JOYERR_UNPLUGGED (JOYERR_BASE+7) /*joystick is unplugged */

然后就可以通过接受游戏杆消息来响应游戏杆了。

游戏杆消息:

#define MM_JOY1MOVE         0x 3A 0           /* joystick */

#define MM_JOY2MOVE         0x 3A 1

#define MM_JOY1ZMOVE        0x 3A 2

#define MM_JOY2ZMOVE        0x 3A 3

#define MM_JOY1BUTTONDOWN  0x3B5

#define MM_JOY2BUTTONDOWN  0x3B6

#define MM_JOY1BUTTONUP     0x3B7

#define MM_JOY2BUTTONUP     0x3B8

要释放游戏杆的捕获时,使用joyReleaseCapture函数。它只有一个参数,就是游戏杆的标识JOYSTICKID1或JOYSTICKID2。

注意:

1.我们一般喜欢在游戏的大循环中自己轮询输入信息,而不是监视消息队列。实际上,接受消息的方式比下面要讲到的直接轮询的效率低一些,对游戏杆的反应有明显的延迟。

2.我用两个手柄来测试,一个北通,一个酷豹。酷豹总是被识别为JOYSTICKID1,而北通总是被识别为JOYSTICKID2。然后我改用两个完全相同的北通手柄来测试,则其中 一个被识别为JOYSTICKID2,另一个不被识别,而JOYSTICKID1则被认为未插入。这个问题我现在还不知道原因和解决方法。另一个问题:倘若我只插入酷豹手柄,或者插入一个北通和一个酷豹,则窗口可以正确接收手柄消息。但是只插入一个北通的话,可以正确检测到手柄的存在,但是接受不到手柄的消息。莫非还缺少了什么步骤?还望高人指点。

轮询:

  主要是利用joyGetPosEx函数主动取得游戏杆信息。这样我们就可以在游戏循环中对手柄状态进行轮询。joyGetPosEx定义如下:

MMRESULT joyGetPosEx(UINT uJoyID, LPJOYINFOEX pji);

[1] uJoyID ----指定游戏杆,它可以是JOYSTICKID1或JOYSTICKID2,即第一、第二个游戏杆。

[2] pji ---- 函数通过这个参数返回游戏杆的信息。参数的类型定义如下:

typedef struct joyinfoex_tag {

DWORD dwSize;     /* size of structure */

DWORD dwFlags;       /* flags to indicate what to return */

DWORD dwXpos;                /* x position */

DWORD dwYpos;                /* y position */

DWORD dwZpos;                /* z position */

DWORD dwRpos;     /* rudder/4th axis position */

DWORD dwUpos;     /* 5th axis position */

DWORD dwVpos;     /* 6th axis position */

DWORD dwButtons;             /* button states */

DWORD dwButtonNumber;        /* current button number pressed */

DWORD dwPOV;                 /* point of view state */

DWORD dwReserved1;

DWORD dwReserved2;

} JOYINFOEX, *PJOYINFOEX, NEAR *NPJOYINFOEX, FAR *LPJOYINFOEX;

使用此函数前要先通过设置pji->dwFlags的值来指定要返回的值,否则很可能会得不到想要的信息,我因为没注意这点而郁闷了很久。dwFlags的值可用下列预定义常数来设置:

#define JOY_RETURNX    0x 00000001l

#define JOY_RETURNY    0x 00000002l

#define JOY_RETURNZ    0x 00000004l

#define JOY_RETURNR    0x 00000008l

#define JOY_RETURNU    0x 00000010l    /* axis 5 */

#define JOY_RETURNV    0x 00000020l    /* axis 6 */

#define JOY_RETURNPOV     0x 00000040l

#define JOY_RETURNBUTTONS 0x 00000080l

#define JOY_RETURNRAWDATA 0x 00000100l

#define JOY_RETURNPOVCTS  0x 00000200l

#define JOY_RETURNCENTERED 0x 00000400l

#define JOY_USEDEADZONE       0x 00000800l

#define JOY_RETURNALL  (JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | /

JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | /

JOY_RETURNPOV | JOY_RETURNBUTTONS)

函数返回值与joySetCapture函数相同。

JOYINFOEX结构中我最常用到的是dwXpos, dwYpos, dwButtons。

dwButtons从低位到高位每一位分别对应手柄上的功能键1至32。以我现在用的手柄,只用到前10位。每一位有一个对应的常数:

/* constants used with JOYINFO and JOYINFOEX structures and MM_JOY* messages */

#define JOY_BUTTON1         0x0001

#define JOY_BUTTON2         0x0002

#define JOY_BUTTON3         0x0004

#define JOY_BUTTON4         0x0008

#define JOY_BUTTON1CHG      0x0100

#define JOY_BUTTON2CHG      0x0200

#define JOY_BUTTON3CHG      0x0400

#define JOY_BUTTON4CHG      0x0800

/* constants used with JOYINFOEX */

#define JOY_BUTTON5         0x 00000010l

#define JOY_BUTTON6         0x 00000020l

……

#define JOY_BUTTON31        0x 40000000l

#define JOY_BUTTON32        0x 80000000l

dwXpos, dwYpos用于测试方向键(未完)

注意:

1.同样存在不能同时接受两个北通手柄的问题。

其他几个API的作用就不细说了。但还有一个问题:用joyGetDevCaps函数获取手柄的Product Name时,得到的都是”Microsoft PC-游戏杆驱动程序”。而用DDK做的时候,取得的Product Name分别是:“USB Joystick”(北通)和“Generic   USB  Joystick”(酷豹)。用Direct Input还可以获得更详细的信息。

[2] uJoyID ----指定游戏杆,它可以是JOYSTICKID1或JOYSTICKID2,即第一、第二个游戏杆。#define MM_JOY1MOVE 0x3A0 /* joystick */[1] uJoyID ----指定游戏杆,它可以是JOYSTICKID1或JOYSTICKID2,即第一、第二个游戏杆。#define JOY_RETURNALL (JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | /JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | /JOY_RETURNPOV | JOY_RETURNBUTTONS)

Windows下对游戏杆编程相关推荐

  1. JoyStick游戏杆编程实践

    概述 最近突然对如何编程读取游戏手柄输入比较感兴趣.所以上网找了找相关的资料,发现没有什么简单明了的教程,所以在此将收集到跟joystick游戏杆编程相关资料整理一下,方便大家参考使用. JoySti ...

  2. 游戏杆编程心得二:如何判断按钮的有效按下

    作者:朱金灿 来源:http://blog.csdn.net/clever101 在游戏杆编程中通过一般需要获取按钮状态来执行特定事件,比如实现按下按钮1一次,变量num递增100,但在调试系统时往往 ...

  3. 初级游戏外挂编程详解 windows运行原理+游戏辅助编程 游戏外挂编程

    @TOC初级游戏外挂编程详解 windows运行原理+游戏辅助编程 游戏外挂编程 [1]什么是windows API Windows API 中文翻译过来就是windows应用程序接口(Applica ...

  4. Windows Phone 7游戏高级编程:使用XNA Game Studio 4

    <Windows Phone 7游戏高级编程:使用XNA Game Studio 4> 基本信息 原书名:Professional Windows Phone 7 Game Develop ...

  5. Snmp在Windows下的实现----WinSNMP编程原理

    在Windows 下实现SNMP协议的编程,可以采用Winsock接口,在161,162端口通过udp传送信息.在Windows 2000中,Microsoft已经封装了SNMP协议的实现,提供了一套 ...

  6. Qt在Windows下的三种编程环境搭建

    未经验证,记录在此. 尊重作者,支持原创,如需转载,请附上原地址:http://blog.csdn.net/libaineu2004/article/details/17363165 从QT官网可以得 ...

  7. Windows下C语言网络编程快速入门

    C语言的学习,一般的方式是,先学C,然后是C++,最好还要有汇编语言和微机原理基础,然后才是Visual C++.这样的方式,对学习者来说,要花费很多时间和耐力.而在学校教学中,也没有时间深入学习Wi ...

  8. Linux与Windows下的socket网络编程对比

    阅读前请看一下:我是一个热衷于记录的人,每次写博客会反复研读,尽量不断提升博客质量.文章设置为仅粉丝可见,是因为写博客确实花了不少精力.希望互相进步谢谢!! 文章目录 阅读前请看一下:我是一个热衷于记 ...

  9. windows下如何进行linux编程,生产者-消费者问题编程简单实现--windows和linux下

    又是某课程的实验(感觉好烦啊啊...),这次终于不用编译内核了,但是但是,他让我们写多线程.好吧,那就写写写,但是等等..他要我们实现生产者-消费者同步问题,要用信号量解决同步问题..这几个都是什么鬼 ...

最新文章

  1. redis python zset
  2. 软件测试学java,软件测试学习Java的内存模型
  3. SQLite3-各个函数
  4. DataList自定义分页
  5. rbpf粒子滤波slam matlab程序_学习笔记(优达学城)- 车辆定位之粒子滤波器(整合版)...
  6. 原生JS实现简单的淘宝放大镜效果
  7. EBS 多组织访问设置
  8. html文本文档整人代码,一些bat恶搞代码
  9. 【微信支付接口调用】
  10. .NET Core 编程指南中文版 —— 7.4 迁移 - 从 DNX 迁移
  11. Java Itext+jfreehart 导入含有图形的word文档
  12. Docker 学习前置,网络IP地址以及交互
  13. 用预处理指令#define 声明一个常数,用以表明一年中有多少秒
  14. 【Unity】Asset Pipeline Version 2(Asset Database v2)内部细节
  15. DIY数控雕刻机,我的第一台数控雕刻机
  16. 【20保研】南京邮电大学关于举办2019 年江苏省研究生“大数据时代下的新型网络计算” 暑期学校的通知...
  17. 使用Hook拦截sendto函数解决虚拟局域网部分游戏联机找不到房间的问题——以文明6为例
  18. 虚函数和纯虚函数的使用
  19. hive中insert插入一条记录报错,跪求高人指点!!!
  20. 数据科学的起源与发展

热门文章

  1. 操作系统精讲(0) | 操作系统详细简介
  2. (java)水果类(增删改查)
  3. FineReport11-server-目录维护
  4. 日本推销之神原一平38种笑容
  5. JAVA 好用的文件备份代码
  6. STM32的DS18B20驱动
  7. u-boot之NAND启动与NOR启动的区别
  8. git 知:贮藏与清理
  9. ESP32C3 CORE+蓝牙收发+PIO
  10. lise什么意思中文翻译_法语助手|法汉-汉法词典 lise是什么意思_lise的中文解释和发音_lise的翻译_lise怎么读...