转:https://www.cnblogs.com/qyit/archive/2011/11/21/2257687.html

一个手柄/键盘映射程序,无外乎就四部分:一、界面;二、接收;三、处理;四、输出。

界面就不多说了。

接收,就是接收手柄的输出。这部分有多种方法,比如windows API和DirectX,这里我们选前者。

处理,就是将接收到的数据映射为输出数据。

输出,就是向操作系统发送假的键盘事件,从而完成映射过程。

接收部分:

那么,我们先来进行知识的准备。为了完成接收部分,我们需要了解和手柄相关的windows API。其中常用的较重要的函数如下:

joyGetDevCaps                  查询指定的游戏杆设备以确定其性能joyGetNumDevs                  返回系统支持的游戏杆设备的数量joyGetPos                       查询指定的游戏杆设备的位置和活动性joyGetPosEx                    查询一个游戏杆设备的位置和它的按扭状态joyGetThreshold                查询指定的游戏杆设备的当前移动阈值joyReleaseCapture              释放由JoySetCapture函数设置的在指定游戏杆设备上的捕获joySetCapture                  发送一个游戏杆消息到指定的窗口joySetThreshold                设置指定的游戏杆设备的移动阈值

要使用这几个API,需要连接winmm.lib,包含mmsystem.h头文件。

如果仅制作基本的映射功能,那么我们并不需要用到全部的函数。主要使用的是这个:

MMRESULT joyGetPosEx(UINT uJoyID, LPJOYINFOEX pji) 

这个函数可以主动取得游戏杆信息。

参数uJoyID是指手柄的ID,对于单手柄编程,填写JOYSTICKID1即可。

参数pji是一个指向JOYINFOEX型结构体的指针。JOYINFOEX的定义如下:

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;

它包含了指定手柄当前的状态信息。我们主要用到的是其中的dwFlags,dwXpos,dwYpos以及dwButtons。这四个成员依次表示:获取状态,十字键X轴当前状态,十字键Y轴当前状态,功能键当前状态。

我们在使用joyGetPosEx获得手柄状态前,先要把dwFlags设置为JOY_RETURNALL,即返回全部按键状态,这样才能同时获得十字键和功能键的信息。

dwXpos和dwYpos的值分别代表了X轴和Y轴当前的状态。对于使用windows默认的自带手柄驱动的,按键情况和对应值如下:

注意:如果安装了手柄驱动盘,值会随驱动不同而改变,请自行测定

而dwButtons的每一位对应手柄的一个功能键状态,0表示抬起状态,1表示按下状态。(注意,是状态,不是动作)对应关系是从低位到高位对应功能键1至手柄功能键最高数。

joyGetPosEx函数的返回值可能是以下几种:

/* 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 */

根据它,我们可以判断电脑当前否有手柄连接。

输出部分:

键盘模拟部们,我们只需要使用一个很简单的函数keyevent

void keybd_event(BYTE bVk,BYTE bScan,DWORD dwFlags,DWORD dwExtralnfo);

参数:   

bVk:定义一个虚拟键码。键码值必须在1~254之间。   

bScan:定义该键的硬件扫描码。   

dwFlags:定义函数操作的名个方面的一个标志位集。应用程序可使用如下一些预定义常数的组合设置标志位。   

KEYEVENTF_EXETENDEDKEY:若指定该值,则扫描码前一个值为OXEO(224)的前缀字节。   

KEYEVENTF_KEYUP:若指定该值,该键将被释放;若未指定该值,该键交被接下。 (其实就是一个是0一个是2,0表示键按下,1表示键弹起) 

dwExtralnfo:定义与击键相关的附加的32位值。

表面上看着好像很点乱,其实没那么复杂。

给一个使用实例:

#define KEY 要模拟的键的ASCII码
keybd_event(KEY,MapVirtualKey(KEY, 0),0,0);

注意,这里使用MapVirtualKey()函数是有必要的。对于很多游戏,单纯的使用keybd_event(KEY,0,0,0)的模式是不能被正确识别的,

换句话说,游戏程序会把那些伪造的键盘信息过滤掉或根本不接受。但使用MapVirtualKey()后,大部分游戏就会识别到我们发送的键盘信息了。

简单demo

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<Windows.h>//添加joystick操作api的支持库
#include<MMSystem.h>
#pragma comment(lib, "Winmm.lib")int main(int argc, char* argv[])
{JOYINFO joyinfo;    //定义joystick信息结构体JOYINFOEX joyinfoex;//定义joystick信息结构体joyinfoex.dwSize = sizeof(JOYINFOEX);joyinfoex.dwFlags = JOY_RETURNALL;while(1){//读取手柄信息
        UINT joyNums;joyNums = joyGetNumDevs();//        printf("当前手柄数量:%d \n",joyNums);if (joyNums>=1){MMRESULT joyreturn = joyGetPosEx(JOYSTICKID1, &joyinfoex);if(joyreturn == JOYERR_NOERROR){printf("当前X坐标:%d \n", joyinfoex.dwXpos);printf("当前Y坐标:%d \n", joyinfoex.dwYpos);printf("当前Z坐标:%d \n", joyinfoex.dwZpos);printf("视点控制的当前位置:%d \n", joyinfoex.dwPOV);printf("32个操纵杆按钮的当前状态:%d \n", joyinfoex.dwButtons);printf("按下的当前按钮编号:%d\n ", joyinfoex.dwButtonNumber);;printf("\n");}else{switch(joyreturn) {case JOYERR_PARMS :printf("bad parameters\n");break;case JOYERR_NOCANDO :printf("request not completed\n");break;case JOYERR_UNPLUGGED :printf("joystick is unplugged\n");break;default:printf("未知错误\n");break;}}}if(kbhit()) break;Sleep(300);}return 0;
}

转载于:https://www.cnblogs.com/yangyuqing/p/10481630.html

基于Windows api手柄映射编程相关推荐

  1. c语言删除文件 Windows,基于Windows API实现遍历所有文件并删除的方法

    本文实例讲述了基于Windows API实现遍历所有文件并删除的方法.分享给大家供大家参考.具体分析如下: 最近一直在学windows API,弄了一些好玩的东西(有点恶作剧了,请大家谨慎使用)... ...

  2. 基于windows API的手柄/键盘映射编程(一)

    开发平台:VC6.0 基于MFC 玩游戏的时候,经常遇到想用手柄但游戏本身不支持的事儿.这样的情况下,我们就要使用软件,将手柄映射为键盘,以达到目的.网上有几款比较流行的优秀的此类软件,比如JoyTo ...

  3. messagebox 全部使用_「一」Windows API 零门槛编程指南——MessageBox

    本篇作为Windows API 系列文章的第一篇,将简要的讲解一下什么是Windows API,Windows API能做些什么,并且尽可能讲解一些新出现的专有名词:本系列博文几乎没有难啃的" ...

  4. 【一】Windows API 零门槛编程指南——MessageBox 基本使用及基础讲解

    本篇作为Windows API 系列文章的第一篇,将简要的讲解一下什么是Windows API,Windows API能做些什么,并且尽可能讲解一些新出现的专有名词:本系列博文几乎没有难啃的" ...

  5. C语言中pthread或Windows API在多线程编程中的基本应用

    文章目录 多线程概述 掌握多线程需要学习什么? 使用pthread.h实现多线程 使用Windows API实现多线程 使用threads.h实现多线程 参考资料 警告 由于我懒得写完,而且懂的也不是 ...

  6. 基于Windows API的VC++串口通信详解

    在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX控件,这种方法程序简单,但欠灵活.其二是调用Windows的API函数,这种 方法可以清楚地掌握串口通信的机制,并且自由灵活. ...

  7. 【二】Windows API 零门槛编程指南——CreateWindow 窗口创建 “万字长篇专业术语全解”

    本系列博文几乎没有难啃的"专业术语",尽量让读者能够看明白文章所述内容,是本系列博文的核心宗旨之一.(由于本人也是由于项目需要,所以才来查阅相关资料,文中出现的错误欢迎指出,共同进 ...

  8. windows API 串口编程参考

    *************************************************** 更多精彩,欢迎进入:http://shop115376623.taobao.com ****** ...

  9. VC串口通信(Windows API)

    本文转载自基于Windows API的VC++串口通信详解,以下附上大白的理解. 简介 在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX控件,这种方法程序简单,但欠灵活.其二 ...

最新文章

  1. Scrum敏捷研发管理平台-Leangoo看板
  2. 计算机网络-交换机配置
  3. sql格式化工具-SQL Pretty Printer
  4. 电子口岸客户端控件首次安装
  5. Spring学习的书-夏昕(2)
  6. 计算机审计中级题库,中级审计师用什么题库练习呢
  7. c语言 组合问题,排列组合问题 C语言
  8. 高德h5定位误差_高德地图定位JS API不准确问题
  9. 这个游戏的名字叫:哒哒哒哒哒哒
  10. linux操作系统原理与应用.第2版 陈莉君 pdf
  11. 中医病案管理、编码、质控、直报、统计系统--正在开发中
  12. [bat] cmd命令进入用户登录界面和屏幕保护程序
  13. 创建Mac的shell命令文件(xxx.sh)
  14. Linux服务器知识梳理
  15. python中求二维列表的最大最小值_python+numpy按行求一个二维数组的最大值方法
  16. Python 读书笔记(1)
  17. 视频流媒体服务器EasyNVR直播平台如何搭建幼儿园网络监控系统?
  18. 微软 Microsoft
  19. 个人中心滚动标题渐变颜色
  20. Python模拟自动存取款机的查询、存取款、修改密码等操作

热门文章

  1. 印能捷怎样安装在虚拟服务器,超详细Prinergy(印能捷)安装及设置教程
  2. 牌型种数 ----蓝桥杯(暴力方法)
  3. 计算机学院毕业典礼口号,毕业典礼创意标语口号
  4. 菜鸟小白初次下载Pr如何配置,以及普通文件、序列文件、psd文件的导入方法
  5. PR工程版本转换攻略,低版本PR打开高版本工程
  6. 哈夫曼编码(java版+详细代码)
  7. Kafka 命令之查看topic生产消费数据查看组的消费信息
  8. CANoe-读写Excel文件
  9. 【LSTM回归预测】基于灰狼算法优化长短时记忆GWO-LSTM时序时间序列数据预测(含前后对比)附Matlab代码
  10. 计算机属性无法查看无反应,Win7旗舰版右键查看计算机属性未反应的处理方法...