C++ 游戏操纵杆编程
本文地址:http://tongxinmao.com/Article/Detail/id/499
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <mmsystem.h>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TMemo *Memo1;
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall JMButtonUpdate(TMessage &msg);
void __fastcall OnJoyDown(TMessage &msg);
void __fastcall OnJoyMove(TMessage &msg);
void TForm1::ShowDeviceInfo(void);
BEGIN_MESSAGE_MAP
// MESSAGE_HANDLER(MM_JOY1BUTTONDOWN,TMessage,JMButtonUpdate)
//MESSAGE_HANDLER(MM_JOY1BUTTONUP,TMessage,JMButtonUpdate)
MESSAGE_HANDLER(MM_JOY1BUTTONDOWN,TMessage,OnJoyDown)
MESSAGE_HANDLER(MM_JOY2BUTTONDOWN,TMessage,OnJoyDown)
MESSAGE_HANDLER(MM_JOY1MOVE,TMessage,OnJoyMove)
//MESSAGE_HANDLER(MM_JOY1ZMOVE,TMessage,OnJoyMove)
MESSAGE_HANDLER(MM_JOY2MOVE,TMessage,OnJoyMove)
//MESSAGE_HANDLER(MM_JOY2ZMOVE,TMessage,OnJoyMove)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
/*
#define MM_JOY1MOVE 0x3A0 //用以传递操纵杆当前状态的一些消息
#define MM_JOY2MOVE 0x3A1
#define MM_JOY1ZMOVE 0x3A2
#define MM_JOY2ZMOVE 0x3A3
#define MM_JOY1BUTTONDOWN 0x3B5
#define MM_JOY2BUTTONDOWN 0x3B6
#define MM_JOY1BUTTONUP 0x3B7
#define MM_JOY2BUTTONUP 0x3B8
#define JOY_BUTTON1 1<<0
#define JOY_BUTTON2 1<<1
#define JOY_BUTTON3 1<<2
#define JOY_BUTTON4 1<<3
#define JOY_BUTTON5 1<<4
#define JOY_BUTTON6 1<<5
#define JOY_BUTTON7 1<<6
#define JOY_BUTTON8 1<<7
#define JOY_BUTTON9 1<<8
#define JOY_BUTTON10 1<<9
#define JOY_BUTTON1CHG 0x0100
#define JOY_BUTTON2CHG 0x0200
#define JOY_BUTTON3CHG 0x0400
#define JOY_BUTTON4CHG 0x0800
*/
/* 游戏操纵杆错误返回值 */
#define JOYERR_BASE 160
#define JOYERR_NOERROR (0) /* 正常 */
#define JOYERR_ParmS (JOYERR_BASE+5) /* 参数错误 */
#define JOYERR_NOCANDO (JOYERR_BASE+6) /* 无法正常工作 */
#define JOYERR_UNPLUGGED (JOYERR_BASE+7) /* 操纵杆未连接 */
/* 操纵杆标识号 */
#define JOYSTICKID1 0
#define JOYSTICKID2 1
//http://www.voidcn.com/article/p-pmzwhkdy-bhp.html
int JoystickID = 0;
int DriverCount = 0;
bool Connected = false;
JOYCAPS JoyCaps;
void PrintMsg(String str)
{
Form1 ->Memo1->Lines->Add(str);
}
void __fastcall TForm1::JMButtonUpdate(TMessage &msg)
{
//当程序接收到JM_BUTTONDOWN和JM_BUTTONUP消息时,即某一按钮的状态发生改变时,都会调用本函数。
if (msg.WParam & JOY_BUTTON1) //判断按钮1是否被按下
PrintMsg("Button 1 = Pressed");
else
PrintMsg("Button 1 = Not Pressed");
}
void TForm1::ShowDeviceInfo(void)
{
joyGetDevCaps(JoystickID, &JoyCaps, sizeof(JOYCAPS));
PrintMsg( "Number of joysticks supported by driver = " +
IntToStr(DriverCount));
PrintMsg("Current Joystick ID = " +
IntToStr(JoystickID));
PrintMsg("Manufacturer ID = " +
IntToStr(JoyCaps.wMid));
PrintMsg("Product ID = " +
IntToStr(JoyCaps.wPid));
PrintMsg( "Number of buttons = " +
IntToStr(JoyCaps.wNumButtons));
// 设置当前窗口接收操纵杆信息。
if (Connected)
joySetCapture(Handle, JoystickID, 2 * JoyCaps.wPeriodMin, FALSE);
//计算操纵杆活动范围和屏幕范围的比率,在后面绘制操纵杆标志时会用到。
int XDivider = (JoyCaps.wXmax - JoyCaps.wXmin) / Width;
int YDivider = (JoyCaps.wYmax - JoyCaps.wYmin) / Height;
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
DriverCount = joyGetNumDevs();
Connected = false;
MMRESULT JoyResult;
JOYINFO JoyInfo;
//检查系统是否配置了游戏端口和驱动程序。
if (DriverCount != 0)
{
//仍需调用joyGetPos进行检测,如果返回JOYERR_NOERROR则表示操纵杆连接正常。
//测试第一个操纵杆。
JoyResult = joyGetPos(JOYSTICKID1, &JoyInfo);
if (JoyResult == JOYERR_NOERROR )
{
Connected = true;
JoystickID = JOYSTICKID1;
ShowDeviceInfo();
PrintMsg(JoystickID);
}
//如果发生INVALIDPARAM错误,则退出。
else if (JoyResult == MMSYSERR_INVALPARAM)
Application->MessageBox("An error occured while calling joyGetPos",
"Error", MB_OK);
// 如果第一个操纵杆为连接,则检查第二个操纵杆。
else if ((JoyResult = joyGetPos(JOYSTICKID2, &JoyInfo)) == JOYERR_NOERROR)
{
Connected = true;
JoystickID = JOYSTICKID2;
PrintMsg(JoystickID);
}
}
}
//对于游戏手柄来说WParam存储的是除了上下左右四个方向键之外的所有按钮中当前被按下的按钮值,它的值是一个复合值。如它的值为JOY_BUTTON1 | JOY_BUTTON2时,就表明按下的按键是1号和2号按钮。
//---------------------------------------------------------------------------
void __fastcall TForm1::OnJoyDown(TMessage &Message)
{
if (Message.WParam & JOY_BUTTON1)
{
//模拟鼠标左键按下
//mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
PrintMsg("JOY_BUTTON1");
}
if (Message.WParam & JOY_BUTTON2)
{
//模拟鼠标右键按下
//mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
PrintMsg("JOY_BUTTON2");
}
if (Message.WParam & JOY_BUTTON3)
{
//模拟鼠标左键抬起
// mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
PrintMsg("JOY_BUTTON3");
}
if (Message.WParam & JOY_BUTTON4)
{
//模拟鼠标右键抬起
// mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
PrintMsg("JOY_BUTTON4");
}
if (Message.WParam & JOY_BUTTON5)
{
//模拟鼠标右键抬起
// mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
PrintMsg("JOY_BUTTON5");
}
if (Message.WParam & JOY_BUTTON6)
{
//模拟鼠标右键抬起
// mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
PrintMsg("JOY_BUTTON6");
}
if (Message.WParam & JOY_BUTTON7)
{
//模拟鼠标右键抬起
// mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
PrintMsg("JOY_BUTTON7");
}
if (Message.WParam & JOY_BUTTON8)
{
//模拟鼠标右键抬起
// mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
PrintMsg("JOY_BUTTON8");
}
if (Message.WParam & JOY_BUTTON9)
{
//模拟鼠标右键抬起
// mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
PrintMsg("JOY_BUTTON9");
}
if (Message.WParam & JOY_BUTTON10)
{
//模拟鼠标右键抬起
// mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
PrintMsg("JOY_BUTTON10");
}
//继续传递消息
TForm::Dispatch(&Message);
}
//不管你有没有按游戏手柄上的按钮,系统也会定时发送MM_JOYXMOVE消息
//自定义的MM_JOY1MOVE消息响应函数OnJoyDown
void __fastcall TForm1::OnJoyMove(TMessage &Message)
{
int x, y;
POINT pt;
//取得鼠标当前坐标
GetCursorPos(&pt);
//此参数存储的是游戏手柄的坐标参数,并且此参数的高16位存储的是Y坐标值,低16位存储的是X坐标值。
x = LOWORD(Message.LParam);
y = HIWORD(Message.LParam) ;
int m = 0x7EFF; //32511
// x= Message.LParam & 0x0000FFFF;
// y = (int)((Message.LParam & 0xFFFF0000) >> 16); //高16位存储Y轴坐标(不直接移位是为避免0xFFFFFF时的情况)
// PrintMsg(x);
// PrintMsg(y);
if (x != 32767)
{
if (x > 32767)
{
PrintMsg("向右");
pt.x += 10;
}
else
{
PrintMsg("向左");
pt.x -= 10;
}
}
if (y != 32766)
{
if (y > 32766)
{
PrintMsg("向下");
pt.y += 10;
}
else
{
PrintMsg("向上");
pt.y -= 10;
}
}
//设置鼠标坐标
//SetCursorPos(pt.x,pt.y);
//继续传递消息
TForm::Dispatch(&Message);
}
上一篇:MQTT获取客户端IP地址
下一篇:4G 蓝牙BLE网关