用VC50实现对游戏杆的编程.docx
《用VC50实现对游戏杆的编程.docx》由会员分享,可在线阅读,更多相关《用VC50实现对游戏杆的编程.docx(10页珍藏版)》请在冰豆网上搜索。
用VC50实现对游戏杆的编程
用VC5.0实现对游戏杆的编程
在WINDOWS95/98中有一个JoystickProperties(游戏杆属性)控制面板。
只要你拥
有一个支持Joystick连接口的声卡和一个游戏杆,你就能享受它提供的强大功能
。
在此介绍给大家如何用VisualC++来实现对游戏杆的编程,希望能对大家有所帮助。
一捕获与释放游戏杆
那么如何用VisualC++5.0来实现对游戏杆的编程呢?
首先必须能捕获游戏杆。
在
这里我们使用joySetCapture函数来实现这一点。
下面是joySetCapture函数的定
义及其每个参数的描述。
intjoySetCapture(HWNDhwnd,UNITuJoyID,UNITuPeriod,BoolfChanged);
[1]Hwnd-----父窗口句柄。
[2]uJoyID----指定游戏杆,它可以是JOYSTICKID1或JOYSTICKID2。
[3]uPeriod----每隔给定的轮询间隔就给应用程序发送有关游戏杆的信息。
这个参数
是以微妙为单位的轮询频率。
以下为捕获游戏杆消息的程序代码
intCJaystickDlg:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
intresult;
if(CDialog:
:
OnCreate(lpCreateStruct)==-1)
return-1;
result=joySetCapture(CDialog:
:
m_hWnd,JOYSTICKID1,0,FALSE);
if(result==JOYERR_NOCANDO){
MessageBeep(MB_ICONEXCLAMATION);
MessageBox("不能捕获游戏杆",NULL,MB_OK|MB_ICONEXCLAMATION);
return-1;
}
if(result==JOYERR_UNPLUGGED){
MessageBeep(MB_ICONEXCLAMATION);
MessageBox("游戏杆未与系统连接",NULL,MB_OK|MB_ICONEXCLAMATION);
return-1;
}
return0;
}
一旦开始捕获游戏杆消息,就可以检查从设备返回的消息。
为了捕获游戏杆消息我
们编写了一个WindowProc过程,程序清单如下:
LRESULTCJaystickDlg:
:
WindowProc(UINTmessage,WPARAMwParam,LPARAMlParam)
{
switch(message){
caseMM_JOY1BUTTONDOWN:
if(wParam&JOY_BUTTON1){
MessageBeep(MB_ICONQUESTION);
SetDlgItemText(IDC_BUTTON1,"Button1:
<<按钮按下>>");
}
if(wParam&JOY_BUTTON2){
MessageBeep(MB_ICONEXCLAMATION);
SetDlgItemText(IDC_BUTTON2,"Button2:
<<按钮按下>>");
}
break;
caseMM_JOY1BUTTONUP:
if(wParam&JOY_BUTTON1){
SetDlgItemText(IDC_BUTTON1,"Button1:
<<按钮按下>>");
SetDlgItemText(IDC_BUTTON2,"Button2:
");
}
elseif(wParam&JOY_BUTTON2){
SetDlgItemText(IDC_BUTTON2,"Button2:
<<按钮按下>>");
SetDlgItemText(IDC_BUTTON1,"Button1:
");
}
else{
SetDlgItemText(IDC_BUTTON1,"Button1:
");
SetDlgItemText(IDC_BUTTON2,"Button2:
");
}
break;
caseMM_JOY1MOVE:
WORDx,y;
POINTpt;
UpdateData(TRUE);
//获取当前屏幕光标位置
GetCursorPos(&pt);
//游戏杆在当前系统中的位置坐标范围从065535。
位置表示范围从0-31
if(!
m_Absolute){
x=LOWORD(lParam)/2048;
y=HIWORD(lParam)/2048;
//如果游戏杆在中心位置的左边,移动光标到左边。
反之亦然
if(x<=12)
pt.x=pt.x+x-15;
elseif(x>=20)
pt.x=pt.x+x-15;
//如果游戏杆在中心位置的下边,移动光标到下边。
反之亦然
if(y<=12)
pt.y=pt.y+y-15;
elseif(y>=20)
pt.y=pt.y+y-15;
}
else{
CDC*pDC=GetDC();
x=LOWORD(lParam);
y=HIWORD(lParam);
pt.x=(pDC->GetDeviceCaps(HORZRES)*x)/65536;
pt.y=(pDC->GetDeviceCaps(VERTRES)*y)/65536;
ReleaseDC(pDC);
}
/*Setthenewcursorposition.*/
SetCursorPos(pt.x,pt.y);
break;
}
returnCDialog:
:
WindowProc(message,wParam,lParam);
}
在WindowProc过程中用MM_JOY1BUTTONDOWN,MM_JOY1BUTTONUP,MM_JOY1MOVE传
递游戏杆设备消息。
WindoweProc的参数wParam保存游戏杆按钮状态信息,参数
iParam的高十六位保存y坐标(065535),低十六位保存x坐标(065535)。
位置(0,0)表示游戏杆位置的左上角,位置(65535,65535)表示游戏杆位
置的右下角。
用完游戏杆后要求确保释放。
用joyReleaseCapture函数来实现。
下面为该函数的定义:
MMRESULTjoyReleaseCapture(UNITuJoyID);
其中uJoyID是JOYSTICKID1与JOYSTICKID2中的一个。
以下程序清单展示了在应用
程序的DestroyWindow事件里游戏杆是如何释放的。
voidCJaystickDlg:
:
OnDestroy()
{
CDialog:
:
OnDestroy();
joyReleaseCapture(JOYSTICKID1);
}
三应用程序实例
结合本文介绍的方法,编写了一个简单的应用程序。
此应用程序创建了一个简单
的对话窗口。
启动该应用程序后,无论何时在游戏杆上按动一个按钮,《按钮按
下》就会出现在按钮文本的旁边。
当移动游戏杆时,鼠标的光标就会在屏幕上移
动,当你释放游戏杆时,鼠标的光标在当前位置保持不变。
图1
在VisualC++5.0环境下,用AppWizard生成对话框程序框架。
对话框如图1所示。
我们只需编辑JoystDlg.cpp,就可以实现该程序。
下面给出JoystDlg.cpp的全部源代码。
//jaystdlg.cpp:
implementationfile
#include"stdafx.h"
#include"joystick.h"
#include"joystdlg.h"
#include"mmsystem.h"
#ifdef_DEBUG
#undefTHIS_FILE
staticcharBASED_CODETHIS_FILE[]=__FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//CAboutDlgdialogusedforAppAbout
{
?
?
?
}
/////////////////////////////////////////////////////////////////////////////
//CJaystickDlgdialog
CJaystickDlg:
:
CJaystickDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CJaystickDlg:
:
IDD,pParent)
{
//{{AFX_DATA_INIT(CJaystickDlg)
m_Absolute=FALSE;
//}}AFX_DATA_INIT
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
voidCJaystickDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CJaystickDlg)
DDX_Check(pDX,IDC_ABSOLUTE,m_Absolute);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CJaystickDlg,CDialog)
//{{AFX_MSG_MAP(CJaystickDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_CREATE()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CJaystickDlgmessagehandlers
BOOLCJaystickDlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
CenterWindow();
//TODO:
Addextrainitializationhere
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
voidCJaystickDlg:
:
OnPaint()
{
if(IsIconic())
{
CPaintDCdc(this);//devicecontextforpainting
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
//Centericoninclientrectangle
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
//Drawtheicon
dc.DrawIcon(x,y,m_hIcon);
}
else
{
CDialog:
:
OnPaint();
}
}
//Thesystemcallsthistoobtainthecursortodisplaywhiletheuserdrags
//theminimizedwindow.
HCURSORCJaystickDlg:
:
OnQueryDragIcon()
{
return(HCURSOR)m_hIcon;
}
LRESULTCJaystickDlg:
:
WindowProc(UINTmessage,WPARAMwParam,LPARAMlParam)
{
switch(message){
caseMM_JOY1BUTTONDOWN:
if(wParam&JOY_BUTTON1){
MessageBeep(MB_ICONQUESTION);
SetDlgItemText(IDC_BUTTON1,"Button1:
<<按钮按下>>");
}
if(wParam&JOY_BUTTON2){
MessageBeep(MB_ICONEXCLAMATION);
SetDlgItemText(IDC_BUTTON2,"Button2:
<<按钮按下>>");
}
break;
caseMM_JOY1BUTTONUP:
if(wParam&JOY_BUTTON1){
SetDlgItemText(IDC_BUTTON1,"Button1:
<<按钮按下>>");
SetDlgItemText(IDC_BUTTON2,"Button2:
");
}
elseif(wParam&JOY_BUTTON2){
SetDlgItemText(IDC_BUTTON2,"Button2:
<<按钮按下>>");
SetDlgItemText(IDC_BUTTON1,"Button1:
");
}
else{
SetDlgItemText(IDC_BUTTON1,"Button1:
");
SetDlgItemText(IDC_BUTTON2,"Button2:
");
}
break;
caseMM_JOY1MOVE:
WORDx,y;
POINTpt;
UpdateData(TRUE);
//获取当前屏幕光标位置
GetCursorPos(&pt);
//游戏杆在当前系统中的位置坐标范围从065535。
位置表示范围从0-31
if(!
m_Absolute){
x=LOWORD(lParam)/2048;
y=HIWORD(lParam)/2048;
//如果游戏杆在中心位置的左边,移动光标到左边。
反之亦然
if(x<=12)
pt.x=pt.x+x-15;
elseif(x>=20)
pt.x=pt.x+x-15;
//如果游戏杆在中心位置的下边,移动光标到下边。
反之亦然
if(y<=12)
pt.y=pt.y+y-15;
elseif(y>=20)
pt.y=pt.y+y-15;
}
else{
CDC*pDC=GetDC();
x=LOWORD(lParam);
y=HIWORD(lParam);
pt.x=(pDC->GetDeviceCaps(HORZRES)*x)/65536;
pt.y=(pDC->GetDeviceCaps(VERTRES)*y)/65536;
ReleaseDC(pDC);
}
/*Setthenewcursorposition.*/
SetCursorPos(pt.x,pt.y);
break;
}
returnCDialog:
:
WindowProc(message,wParam,lParam);
}
returnCDialog:
:
WindowProc(message,wParam,lParam);
}
//CapturetheJoystick-JK
intCJaystickDlg:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
intresult;
if(CDialog:
:
OnCreate(lpCreateStruct)==-1)
return-1;
result=joySetCapture(CDialog:
:
m_hWnd,JOYSTICKID1,0,FALSE);
if(result==JOYERR_NOCANDO){
MessageBeep(MB_ICONEXCLAMATION);
MessageBox("不能捕获游戏杆",NULL,MB_OK|MB_ICONEXCLAMATION);
return-1;
}
if(result==JOYERR_UNPLUGGED){
MessageBeep(MB_ICONEXCLAMATION);
MessageBox("游戏杆未与系统连接",NULL,MB_OK|MB_ICONEXCLAMATION);
return-1;
}
return0;
}
voidCJaystickDlg:
:
OnDestroy()
{
CDialog:
:
OnDestroy();
joyReleaseCapture(JOYSTICKID1);
}