概述
而目前在Windows下编程控制游戏杆比较主流的技术是
DirectInput
,而我这里重要是采集游戏杆的二维数据,不需要复杂的控制功能,直接就采用Win API
游戏杆相关的函数都封装在 Winmm.dll
中。相应的头文件是 Mmsystem.h
, 链接时需要链接 Winmm.lib
。
//添加joystick操作api的支持库
#include<MMSystem.h>
#pragma comment(lib, "Winmm.lib")
编程步骤:
- 捕获游戏操纵杆
- 处理
Windows
发给程序窗口的消息 - 将捕获的操纵杆资源释放
一、捕获游戏操纵杆
默认情况下,WINDOWS
系统是不监控游戏手柄的,所以需要调用joySetCapture
函数通知相应的系统服务将游戏手柄的状态改变以消息的形式传给我们的应用程序。
MMRESULT joySetCapture(
HWND hwnd, //处理窗口以接收操纵杆消息。
UINT uJoyID, //要捕获的操纵杆的标识符。uJoyID 的有效值范围从零 (JOYSTICKID1) 到 15。
UINT uPeriod, //轮询频率,以毫秒为单位。它指定给应用程序发送有关操纵杆的间隔时间
BOOL fChanged//更改位置标志。将此参数指定为TRUE以仅在位置变化的值大于操纵杆移动阈值时发送消息。否则,将以uPeriod 中指定的轮询频率发送消息。
);
代码实现:重载WM_CREATE
消息
int CJoystickDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
int result = joySetCapture(CDialog::m_hWnd, JOYSTICKID1, 0, FALSE);
switch (result)
{
case JOYERR_NOCANDO:
{
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(_T("不能捕获游戏杆"), NULL, MB_OK | MB_ICONEXCLAMATION);
return -1;
}
break;
case JOYERR_UNPLUGGED:
{
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(_T("游戏杆未与系统连接"), NULL, MB_OK | MB_ICONEXCLAMATION);
return -1;
}
break;
case JOYERR_PARMS:
{
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(_T("无效的操纵杆 ID 或 hwnd 为NULL"), NULL, MB_OK | MB_ICONEXCLAMATION);
return -1;
}
break;
default:
break;
}
return 0;
}
二、处理Windows发给程序窗口的消息
一旦在窗口创建完成,即开始捕获游戏杆消息,就可以处理Windows
发给程序窗口的消息。
而Windows
会把所有的操纵杆消息发送给窗口。
- 当操纵杆的方向钮按被按下时,产生的是
MM_JOY1MOVE
消息 - 当功能按钮被按下时,产生
MM_JOY1BUTTONDOWN
消息 - 当功能按钮被按下时,产生
MM_JOY1BUTTONUP
消息
在程序中分别响应并处理这三个消息。
由于这三条消息不是标准的Windows消息,我们需要自定义和处理消息。自定义消息的步骤:
- 声明消息
- 在类声明中声明消息映射
- 类声明中定义消息处理函数
- 实现消息映射
- 实现消息处理函数
为了捕获游戏杆消息我们编写WindowProc
来处理:
在WindowProc
过程中用MM_JOY1BUTTONDOWN
, MM_JOY1BUTTONUP
, MM_JOY1MOVE
传递游戏杆设备消息。
WindoweProc
的参数message
保存接收到的消息,wParam
保存游戏杆按钮状态信息,参数iParam 的高十六位保存y坐标(0~ 65535),低十六位保存x坐标(0~65535)。
位置(0,0)表示游戏杆位置的左上角,位置(65535,65535)表示游戏杆位置的右下角。
扩展:WindowProc函数是一个应用程序定义的函数处理消息的发送到一个窗口。指向的类型定义了一个指向这个回调函数。WindowProc是一个占位符为应用程序定义的函数名。
LRESULT CJoystickDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case MM_JOY1BUTTONDOWN:
if (wParam & JOY_BUTTON1)
{
MessageBeep(MB_ICONQUESTION);
MessageBox(_T("按键1按下"));
}
if (wParam & JOY_BUTTON2)
{
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(_T("按键2按下"));
}
break;
case MM_JOY1BUTTONUP:
if (wParam & JOY_BUTTON1)
{
MessageBox(_T("按键1释放"));
}
else if (wParam & JOY_BUTTON2)
{
MessageBox(_T("按键2释放"));
}
else
{
MessageBox(_T("按键1释放"));
MessageBox(_T("按键2释放"));
}
break;
case MM_JOY1MOVE: //游戏杆移动
{
WORD xPos, yPos;
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);
//进行数据处理
}
break;
}
return CDialog::WindowProc(message, wParam, lParam);
}
三、释放捕获的操纵杆
要释放操纵杆的捕获时,使用joyReleaseCapture
函数。它只有一个参数,就是操纵杆的标识JOYSTICKID1
或JOYSTICKID2
。
MMRESULT joyReleaseCapture(UINT uJoyID);
代码实现:
void CJoystickDlg::OnDestroy()
{
CDialog::OnDestroy();
//释放操纵杆
joyReleaseCapture(JOYSTICKID1);
joyReleaseCapture(JOYSTICKID2);
}
最后
以上就是长情香烟为你收集整理的使用Win下API编写操纵杆应用程序的全部内容,希望文章能够帮你解决使用Win下API编写操纵杆应用程序所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复