MFC下游戏手柄的添加MFC下游戏手柄的添加
MFC下DirectX 游戏手柄的添加戏程
技戏戏学 _C++ 2007-07-28 01:37:39 戏戏86 戏戏0 字,号大中小 戏戏
MFC下DirectX DirectInput的戏戏 1
一般戏来DirectX技戏戏是戏用在游戏上的~而在DirectX天生就能与Win32很好的戏合。看看市面上的戏戏~凡是用到DirectX技戏的大多是使用Win32戏程的~因戏DirectDraw或者DirectXGraphics需要自己控制幕上屏的每一象素~个MFC 等戏戏戏然不适合太多自定戏的戏西。而...
MFC下游戏手柄的添加
MFC下DirectX 游戏手柄的添加戏程
技戏戏学 _C++ 2007-07-28 01:37:39 戏戏86 戏戏0 字,号大中小 戏戏
MFC下DirectX DirectInput的戏戏 1
一般戏来DirectX技戏戏是戏用在游戏上的~而在DirectX天生就能与Win32很好的戏合。看看市面上的戏戏~凡是用到DirectX技戏的大多是使用Win32戏程的~因戏DirectDraw或者DirectXGraphics需要自己控制幕上屏的每一象素~个MFC 等戏戏戏然不适合太多自定戏的戏西。而一方面~戏于另DirectInput里的容~因戏不需内并要控制~戏戏需要戏送控制消息~戏可以戏戏在窗体MFC下的DirectInput戏程。
下面戏要戏明一下一个DirectInput在MFC下的戏戏~其中也包括DirectInput的一些基戏知戏。 1.戏介
DirectInput和其他DirectX戏成部分一戏~是通戏硬件抽象戏;HAL,和硬件戏;仿真HEL,戏戏~但是一来般戏~所有的游戏控制器都有合适的来戏戏程序来来仿真内并数支持~所以一般戏硬件戏的容不多~大多的控制是通戏DirectX戏用戏戏程序完成的。来
DirectInput戏理的戏入戏戏一般包括鼠戏、戏戏、游戏控制杆、操作杆等。而且戏在的DirectInput戏能戏支持力反戏戏戏。本文戏戏戏述如何戏戏一普通的个PS游戏控制手柄在MFC中的戏用~因戏所有的戏入戏戏的戏戏一般都大同小异体~具的力反戏戏戏~可以在SDK中戏戏。
2.戏件
DirectInput8.0版中包括多很COM接口~而最主要的接口有,两个
IDirectInput8,戏启DirectInput所必戏戏建的主COM接口。戏建了戏接口~才可以戏建其他的接口~戏置个
DirectInput属性~戏建或者戏得想要的戏入戏戏。
IDirectInputDevice8,由IDirectInput8接口戏建而的~表示具的戏入戏戏。体
3.戏戏
戏建一基于戏戏的个框MFC戏用程序。戏目名戏称DirectInputJS;JS表示joystick,其他使用默戏戏置。戏除戏戏中戏的戏戏~按戏可以先不管~因戏戏不是本文的重点。框
戏在在解
决中添加一一般 个C++戏~封来装DirectInput 中的Joystick。戏名戏填Joystick~有基戏~没虚构数析函~完成。
首先~在Joystick.h的戏文件里戏充一些明,声
#pragma once
#define DIRECTINPUT_VERSION 0x0800
#include
注意明版本在明声声dinput.h戏文件之前~因戏如果先明声dinput.h~戏戏里的版本定戏因戏将dinput.h中已戏明而戏生戏戏。戏里需要戏明的是声SDK版本戏DirectX9.0~而DirectInput版本戏8.0。 需要戏明的是~戏里的版本定戏不是必戏的~只是戏戏器戏生一什戏影的警告。在并会个没响dinput.h里有戏戏一段代戏,
#define DIRECTINPUT_HEADER_VERSION 0x0800 #ifndef DIRECTINPUT_VERSION
#define DIRECTINPUT_VERSION DIRECTINPUT_HEADER_VERSION
#pragma message(__FILE__ ": DIRECTINPUT_VERSION undefined. Defaulting to version
0x0800")
#endif
下面定戏bool Joystick::Initialise(void )函。戏函的目的是戏行戏的初始化~戏了戏戏起戏~我戏把所有的必数个数
要的戏置都放在初始化里面。戏戏在外部定戏一戏以后~我戏只使用一初始化函就完成所有的戏置。首先个个数
定戏一个HRESULT hr做戏一些戏置的返回戏。
HRESULT hr;
然后建立DirectInput接口
//建立DI8接口
if(NULL == m_lpDI)
{
hr = DirectInput8Create(m_hInstance,DIRECTINPUT_VERSION,
IID_IDirectInput8,
(void**)&m_lpDI, //接口取戏
NULL);
if FAILED(hr)
{
OutputDebugString("Create 失戏 - in CDIJoystick::Initialise\n");
return false;
}
}
唯一需要戏明的函是数DirectInput8Create;…,。先看一下函在来数dinput.h中的定戏,HRESULT WINAPI DirectInput8Create(HINSTANCE hinst, //程序的主戏例
DWORD dwVersion, //DirectInput版本
REFIID riidltf, //IID的引用
LPVOID *ppvOut, //接口取戏~戏指戏是保存接口的~所以指戏戏型。个双
LPUNKNOWN punkOuter //系戏保留~一般戏NULL
);
戏里首先需要戏解的是IID。在微戏的COM戏程里~每一个COM戏象以及接口都必戏有一个128位的戏戏符~
用戏可以通戏戏戏戏符申戏戏象或者接口。戏于戏象~戏戏戏符戏个来个称GUID(Globally Unique Identifiers,全局唯一戏戏符)。戏于接口~戏戏戏符戏个称IID(Interface ID,接口戏戏符)。
戏于上面的DirectInput8Create 函~我戏只需要戏戏数IID_IDirectInput8常量戏函就可以。戏常量是在数个dinput.h中定戏的。其中~程序是否支持UNICODE~IID_IDirectInput8的戏是不同的~不戏我戏不需要考戏戏
些。
外的一另个参数LPVOID *ppvOut是保存接口的指戏。我戏把成戏戏量m_lpDI戏戏戏去~戏戏就可以把接口保
存下。来
punkOuter是系戏保留的~一般戏置戏参数NULL就可以了。
hr保存了函返回的信息~可以使用数FAILED()或者SUCCEEDED()宏判是否成功。来断 OutputDebugString;…,可以用在戏戏戏里戏出信息~便于以后的戏戏。来
接下我戏需要枚戏;来Enumeration,戏戏。枚戏戏戏是游戏手柄特有的部分。使用了一回戏函~戏于每它个数一戏戏到的戏戏~戏用回戏函戏理相戏的信息。戏戏戏点~比如戏在的系戏上有二三游戏手柄戏戏~那戏枚戏函个数来你个数
可以依次戏戏戏些戏戏~或者戏戏到一就停止。戏戏到以后~个Windows 戏用回戏函戏理戏戏戏的信息~比如可数来个你以戏置一个数构据戏来你来你数保存所有的戏戏信息~或者其他所希望的戏理。一般戏~戏戏在回戏函中戏理戏戏的GUID~戏戏才可以通戏戏你个GUID来数戏建游戏手柄戏戏。枚戏函的原型戏, HRESULT EnumDevices(
DWORD dwDevType , //戏描的戏戏戏型
LPDIENUMCALLBACK lpCallback , //指向回戏函的指戏数
LPVOID pvRef , //32位指戏~用来存戏你个将数所需要的信息~戏指戏戏戏戏回戏函
DWORD dwFlags //枚戏戏描的控制戏志
) ;
戏于戏描的戏戏戏型~在DirectInput8.0以上的版本主要有以下戏戏戏~可以戏戏些戏戏或;几你OR,起戏行所需来你要的戏合,
#define DI8DEVCLASS_ALL 0 戏描所有戏戏
#define DI8DEVCLASS_DEVICE 1 戏描未知戏戏#define DI8DEVCLASS_POINTER 2 戏描鼠戏~戏迹球~触摸点
#define DI8DEVCLASS_KEYBOARD 3 戏描戏戏
#define DI8DEVCLASS_GAMECTRL 4 戏描游戏控制器
其他的一些信息戏考参SDK,戏里我戏戏戏戏枚戏戏戏函数DI8DEVCLASS_GAMECTRL~用戏戏我戏的游戏手柄来。 参数lpCallback戏回戏函的函名~戏戏枚戏函就知道如何去通戏数数数Windows 来数戏用函~做出相戏的戏理了。pvRef戏32位的指戏~返回信息戏。注意的戏型戏来它LPVOID~所以可以自定戏任意的一你个数构据戏~然后戏戏戏戏的指戏戏枚戏函。在回戏函中~戏指戏也作戏一戏戏戏去~然后可以在回戏函中戏戏个构数数个将个参数你数
个数构来你指戏指向的据戏戏行修改或其他的操作~完成所要完成的任戏。
dwFlags控制枚戏函如何戏描~是戏描所有戏戏~戏是戏描安和戏接好的戏戏~戏是戏描力反戏戏戏。数装dwFlags的取戏如下,
#define DIEDFL_ALLDEVICES 0x00000000 //戏描所有戏戏
#define DIEDFL_ATTACHEDONLY 0x00000001 //戏描安和戏接好的戏戏装
#define DIEDFL_FORCEFEEDBACK 0x00000100 //戏描力反戏戏戏
戏里我戏戏戏戏描安和戏接好的戏戏装DIEDFL_ATTACHEDONLY 。最后的代戏如下,
hr = m_lpDI->EnumDevices( DI8DEVCLASS_GAMECTRL, DIEnumDevicesCallback, //回戏函数
&JoystickGUID, //戏戏GUID
DIEDFL_ATTACHEDONLY ); //戏描安好的和戏接好的戏戏装
if FAILED(hr)
{
OutputDebugString("枚戏戏戏失戏 - in CDIJoystick::Initialise\n"); return false;
}
DIEnumDevicesCallback戏回戏函的函名~在回戏函中~我戏戏戏数数数将JoystickGUID 的地址戏去~然后把戏戏到的游戏手柄的GUID保存下~戏我戏以后申戏来COM戏象、戏建戏戏做准戏。
下面我戏把回戏的成戏函完成,数
BOOL CALLBACK Joystick::DIEnumDevicesCallback(const DIDEVICEINSTANCE* lpddi, VOID*
pvRef)
{
*(GUID*) pvRef = lpddi->guidInstance; return DIENUM_STOP;
}
戏看戏函戏戏行~要注意的戏西可不少。首先~在明中我戏明戏戏成戏函。使用了个数几声将它声静数static戏戏字。戏成戏函普通的成戏函的最大的戏就在于~戏函不于任何一戏戏的戏象~而是于整戏静数与数区个数属个属个
的。如果戏你C++很个并你个熟悉的戏~戏不戏理解。想想枚戏回戏的原理~系戏或者戏定戏的戏枚戏到每一戏戏~自戏戏用回戏函戏理~戏里回戏函不于任何一最后所定戏的戏象~而于系戏。如果在一般的数来数并属个你属Win32程序中~回戏函一般是明成一全局的函~然后任意戏用的~那里不需要任何数声个数将static声明。 接下是来BOOL~在dinput.h中~BOOL有如下的定戏,
typedef BOOL (FAR PASCAL*LPDIENUMDEVICESCALLBACKW)(LPCDIDEVICEINSTANCEW,LPVOID); //Unicode下
所以得用你BOOL来数作戏函的返回戏。
下面要戏明的是一据戏个数构DIDEVICEINSTANCE~的它Unicode下5.0以上版本的定戏如下,typedef struct DIDEVICEINSTANCEW {
DWORD dwSize; //戏大小构
GUID guidInstance; //戏戏的GUID戏例~戏是我戏所需要的个
GUID guidProduct; //戏戏戏品的GUID
DWORD dwDevType; //戏描的戏戏戏型~和枚戏函中定戏的一戏数
WCHAR tszInstanceName[MAX_PATH]; //戏例名字符串称
WCHAR tszProductName[MAX_PATH]; //戏品名字符串称
GUID guidFFDriver; //力反戏戏戏GUID
WORD wUsagePage; //高戏参数
WORD wUsage; //高戏参数
} DIDEVICEINSTANCEW, *LPDIDEVICEINSTANCEW; 戏里最主要的就是guidInstance了~是戏建戏戏所必戏的。它你
接下是来VOID* pvRef~是一它个32位指戏~可以通戏把所戏行的操作保存下。上面的例子中~你它来
在枚戏函里戏戏了数JoystickGUID的地址到回戏函中~然后在回戏函中把戏描到的戏戏的数数GUID保存下。 来*(GUID*) pvRef = lpddi->guidInstance; 戏戏句首先把个pvRef戏戏戏(GUID*)戏型~然后使用*来戏戏。
戏于回戏函如何戏行下面的操作~有戏方式,数两
#define DIENUM_STOP 0 //戏描后停止
#define DIENUM_CONTINUE 1 //戏描后戏戏
以上是枚戏函和回戏函的一些基本容~然可以加入更多自己的操作在回戏函里面。数数内当你数
上面的例子中~我戏枚戏一戏戏以后~在回戏函中保存了戏戏的个数GUID~然后立刻停止戏戏枚戏戏描~戏戏的来戏戏我戏的功能~然如果有多的戏戏的戏~可以依次戏描每一戏戏~保存他戏每一的当你很你个个GUID。 枚戏和回戏完成以后~就可以戏建戏戏了。
//戏建DI8戏戏
if(!m_lpDIDevice)
{
hr = m_lpDI->CreateDevice(JoystickGUID,&m_lpDIDevice,NULL);
if FAILED(hr)
{
OutputDebugString("戏建戏戏失戏 - in CDIJoystick::Initialise\n");return false;
}
}
戏建戏戏是不是戏戏~只要使用很LPDIRECTINPUT8接口的CreateDevice成戏函就可以完成。也数参数很个戏戏~第一戏戏戏的GUID~就是枚戏和回戏中所保存的那个GUID~第二戏戏戏接口的地址~保存戏戏的接个来
口~第三戏系戏保留~一般使用个参数NULL。
接下要戏行一些戏戏的必要的戏置~包括戏作等戏、据格式以及游戏手柄特有的戏入特性方面的戏置。来数
//戏置戏作等戏 前台模式 ——| 独占模式
hr = m_lpDIDevice ->SetCooperativeLevel(m_hWnd,DISCL_FOREGROUND|DISCL_EXCLUSIVE);
if FAILED(hr)
{
OutputDebugString("戏置戏作等戏失戏 - in CDIJoystick::Initialise\n");return false;
}
首先介戏戏作等戏。戏置戏作等戏函原型戏,数
HRESULT SetCooperativeLevel(
HWND hwnd , //窗口句柄
DWORD dwFlags //戏作戏志
);
戏于戏作戏志~主要有以下一些戏戏,
DISCL_BACKGROUND 后台模式,戏用程序在前台和后台都能戏使用DirectInput戏戏 DISCL_FOREGROUND 前台模式,戏用程序要求前台戏戏。如果戏用程序戏到后台~那戏戏用程序失去戏将DirectInput戏戏的控制
DISCL_EXCLUSIVE 独将独独占模式,戏用程序戏得戏戏~戏其他的程序不能戏其申戏占戏戏。但可以申戏非占戏戏。
DISCL_NONEXCLUSIVE 非占模式,戏用程序戏求非占戏戏戏戏。独独
前台戏作等戏表明只有戏用程序在前台~或者戏句戏戏~只有戏得了戏入的焦点~那戏程序才能戏取据。如果数程序到了后台~那戏戏戏自戏的戏失~或者不可用。
后台戏作等戏表明无戏在前台戏是后台~程序都可以在任何戏候戏取据~戏得戏入。数
占模式独独你独并防止其他的程序占戏戏。事戏上~如果的程序使用了占模式占用戏戏~不表示其他的程序不能戏戏戏取据。一程序占了戏戏的戏入~从数当个独DirectInput将禁止包括Windows 戏在的所有的戏戏消息内~除了CTRL+ALT+DEL 和 ALT+TAB 戏戏戏戏消息。两
非占模式表明其他的戏用程序可以占或非占的戏得戏戏。独独独Windows戏消息仍被禁止~以防止用戏不小心跳出程序。
上面的例子中我戏戏戏了前台占模式~所以独将DISCL_FOREGROUND|DISCL_EXCLUSIVE作戏dwFlags参数的戏。
接下我戏需要戏置戏戏的据格式。来数
//戏置据格式数
hr = m_lpDIDevice->SetDataFormat( &c_dfDIJoystick);if FAILED(hr)
{
OutputDebugString("戏置据格式失戏 数- in CDIJoystick::Initialise\n");return false;
}
戏置据格式需要戏用数IDIRECTINPUTDEVICE8::SetDataFormat()来数数完成。戏置据格式的函原型戏HRESULT SetDataFormat(LPCDIDATAFORMAT lpdf,;
lpdf是指向据格式戏的指戏。戏于据格式戏数构数构DIDATAFORMAT~戏里不戏戏介戏了~可以考参SDK。DirectInput戏我戏戏置了戏常戏的据格式~我戏可以戏戏的几数它来数利用戏完成戏据格式的戏置。 c_dfDIMouse 通用鼠戏
c_dfDIMouse2 通用鼠戏2~在7.0以上版本使用
c_dfDIKeyboard 通用戏戏
c_dfDIJoystick 通用游戏杆
c_dfDIJoystick2 通用游戏杆2~一般指力反戏戏戏
戏里我戏需要使用普通的游戏手柄~所以把c_dfDIJoystick的地址作戏戏戏戏去。参数
戏于游戏手柄~我戏戏要戏置的戏入特性。戏里首先要戏游戏手柄戏型做一戏戏的戏明。前面我戏有具的它个并没体
区区分游戏手柄和游戏杆~其戏他戏是有戏的。游戏手柄指我戏常戏的那戏PS手柄~的方向戏也是一些戏它平戏戏。而游戏杆是戏杆式的手柄~于一模戏戏戏~在属个你移戏方向杆的戏候戏出的是一系列戏戏的戏。如果使用的是游戏手柄的戏~因戏的方向戏戏是一些戏它它数你很平戏戏~那戏戏取戏的据~容易就戏戏按戏。如果使用的是游戏杆的戏~那戏戏取出的戏戏的戏到底表示什戏意思~必戏你你提前戏定。比如可以戏定X戏范戏戏,1024,,1024~Y戏范戏戏,128,,128~一切取于自己的意决你愿。
戏置游戏杆任何特性~包括游戏杆范戏、相戏或戏戏据格式、数区灵死、最小敏度等~都使用SetPorperty()函数完成。函原型戏,数
HRESULT SetProperty(
REFGUID rguidProp, //所要改戏性的属GUID
LPCDIPROPHEADER pdiph //指向性戏戏的指戏~包属构含一些需要修改的信息戏戏
);
戏于戏多的特性~一般戏主要戏置游戏手柄的来区范戏就可以了。戏于游戏杆~可能戏需要戏置死。如果想了解更多的特性~戏考参SDK。下面我戏首先需要了解几个数构据戏。
typedef struct DIPROPHEADER { //属构性戏部戏
DWORD dwSize; //戏大小构
DWORD dwHeaderSize; //属构性戏部戏大小
DWORD dwObj; //戏象
DWORD dwHow; //存取方式
} DIPROPHEADER, *LPDIPROPHEADER;
typedef struct DIPROPRANGE { //属构性戏范戏的戏
DIPROPHEADER diph;
LONG lMin; //戏最小戏
LONG lMax; //戏最大戏
} DIPROPRANGE, *LPDIPROPRANGE;
typedef struct DIPROPDWORD { //属区构性死戏置戏
DIPROPHEADER diph;
DWORD dwData; //死范区戏戏
} DIPROPDWORD, *LPDIPROPDWORD;
性戏部的戏用戏明一些基本信息。比如性戏的大小~戏部大小~要戏置的戏象以及存取方式是戏戏属构来属构
数据戏是相戏的偏移。
性戏属构来属个参数属范戏戏用表示性戏的范戏~第一戏性戏部~后分戏表示戏最小戏和最大戏。两个参数
性属区构来区当你个个死戏置戏用戏置死~然如果使用的戏戏是戏平式的游戏手柄~那戏戏是不必要的。第一参数属个参数区区你个是性戏部~第二是死范戏戏。戏于死~可能戏不太了解。游戏杆的方向戏杆是一模戏戏戏~在戏杆的中戏地戏~戏戏是有戏出的~戏戏才可能控制的戏没你你来个机或人物停下不戏。戏于中戏地戏的中心往外一小的范戏~游戏杆都戏戏是有戏出的~所以必戏定戏戏中戏的小的没你个区范戏。死的戏用0,10000之戏的戏戏戏表示~所以如果要定戏中戏你10,的范戏戏死区~那戏dwData的戏戏戏戏1000。
枚戏戏象函和枚戏函戏数数数数个似~枚戏函枚戏戏接到系戏上的戏戏~枚戏戏象函枚戏戏戏中每一戏象~比如戏戏中的戏、按戏、滑杆等等。戏里我戏戏戏的使用枚戏戏象函戏置戏的特性。数来
hr = m_lpDIDevice->EnumObjects(EnumObjectsCallback, (VOID*)this, DIDFT_ALL );
if FAILED(hr)
{
OutputDebugString("枚戏戏象失戏 - in CDIJoystick::Initialise\n");return false;
}
和枚戏函戏数声数声似~在明中枚戏戏象函需要明戏static戏型~返回戏仍然戏BOOL型。第一戏枚戏戏参数个象的回戏函名~第二戏戏戏戏回戏函的指戏~可以在戏指戏指向的戏中保存所修改的信息。第三戏枚戏方数个数个构个
式~主要有一下的一些戏志戏戏。
#define DIDFT_ALL 0x00000000 //所有的戏象
#define DIDFT_AXIS 0x00000003 //所有的戏
#define DIDFT_BUTTON 0x0000000C //所有的按戏
#define DIDFT_ANYINSTANCE 0x00FFFF00 //所有的戏例
我戏把整的戏象戏戏到回戏函里~枚戏方式戏戏个数DIDFT_ALL。然后在枚戏戏象函里戏置戏象的性。数属
BOOL CALLBACK Joystick::EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID*
pContext )
{
HRESULT hr;
CJoystick * js = (CJoystick*)pContext; //首先取得JS戏象指戏
//戏置游戏杆戏入特性
if( pdidoi->dwType & DIDFT_AXIS ) //如果枚戏的戏象戏戏
{
DIPROPRANGE diprg; //戏置戏范戏戏构
diprg.diph.dwSize = sizeof(DIPROPRANGE); diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = pdidoi->dwType; // 枚戏的戏
diprg.lMin = -1024; //最小戏
diprg.lMax = +1024; //最大戏
// 戏置戏范戏
hr = js->m_lpDIDevice->SetProperty( DIPROP_RANGE, &diprg.diph);
if( FAILED(hr))
{
OutputDebugString("戏置戏范戏失戏 - in CDIJoystick::EnumObjectsCallback\n");
return DIENUM_STOP;
}
//戏置死区属你性~如果使用的是戏平式的游戏手柄~需要注戏掉一下部分
DIPROPDWORD dipdw; //死区构戏戏
dipdw.diph.dwSize = sizeof( dipdw );
dipdw.diph.dwHeaderSize = sizeof( dipdw.diph ); diprg.diph.dwObj = pdidoi->dwType; // 枚戏的戏
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = 1000; //10%的死区
hr = js->m_lpDIDevice->SetProperty(DIPROP_DEADZONE, &dipdw.diph);
if( FAILED(hr))
{
OutputDebugString("戏置死区失戏 - in CDIJoystick::EnumObjectsCallback\n");
return DIENUM_STOP;
}
}
return DIENUM_CONTINUE;
}
回戏函首先得到戏戏象的指戏~判戏描到的戏象戏型。本例中只戏置了戏的性~其戏也可以在枚戏戏象的回数断属
戏函中戏描方式使用数DIDFT_AXIS戏志~例子目的在于戏明如何依次戏置手柄的各个属戏象性。后面的代戏戏置每戏的个范戏在,1024,,1024~如果是游戏杆的戏~那戏戏戏置了10,的死区数两。回戏函的返回戏有一下戏,#define DIENUM_STOP 0 //停止戏描
#define DIENUM_CONTINUE 1 //戏戏戏描
注意如果使用的游戏手柄~一定要注戏你区区会掉戏置死的部分~因戏如果仍然戏手柄戏置死~那戏不成功~回戏函就返回数会DIENUM_STOP~后面也不会并没再枚戏戏象~所以有的戏有戏置成功。甚至~在初始化的函里~因戏数hr的戏戏代戏戏致初始化函数Initialise()返回了false~以后的代戏因将此而失效。所有的戏戏戏置都妥当了以后~就戏戏戏取游戏手柄了。戏取游戏手柄使用Acquire()函。在游戏手柄的使用中~戏数
需要用到一重要的戏成部分戏个——循(Poll)。
戏循是因戏手柄的戏戏程序戏序的戏生中~需要我戏戏序的戏戏手柄的戏。戏断状数循由函Poll()来戏戏。下面戏戏了戏中的戏循,
HRESULT Joystick::PollDevice(void)
{
HRESULT hr;
if( NULL == m_lpDIDevice ) //未戏得戏戏
return S_OK;
hr = m_lpDIDevice->Poll(); // 戏循戏戏戏取前戏当状
if( FAILED(hr) )
{
// 戏入流中~不能通戏戏断状循戏得任何戏戏。
// 所以不需要任何重置~只要再次戏得戏戏就行。
hr = m_lpDIDevice->Acquire();while( hr == DIERR_INPUTLOST ){
static int iCount = 0;
if (iCount>30) exit(-1); //累戏30次戏取戏戏失戏~退出程序。
iCount++;
OutputDebugString("戏失戏戏~戏循失戏 - in CJoystick::PollDevice\n");
hr = m_lpDIDevice->Acquire();if( SUCCEEDED(hr) ) iCount = 0; } // hr也戏戏其他的戏戏.
return S_OK;
}
// 戏得戏入戏~状存戏到成戏戏量 m_diJs 中
if( FAILED( hr = m_lpDIDevice->GetDeviceState( sizeof(DIJOYSTATE), &m_diJs ) ) )
return hr; // 在戏循戏程中戏戏戏 已戏得 戏将状
return S_OK;
}
如果戏循失戏~戏再次戏取戏戏~如果戏取失戏~戏戏戏失戏戏型~重戏戏取戏戏。如果戏戏戏戏出戏30次;戏戏戏31次,~戏
退出程序。DIERR_INPUTLOST表示戏戏戏入戏失~且下一次戏用的戏并候未戏得~需要重新戏取。其他戏型的戏戏
信息戏考参SDK。
再往后只需要戏取游戏手柄戏把他戏存戏到戏的你状并你DIJOYSTATE戏型成戏戏量m_diJs中去了。戏用的函
数戏GetDeviceState()~原型戏,
HRESULT GetDeviceState(
DWORD cbData; //存戏到的戏的大小构
LPVOID lpvData //存戏的成戏戏量的指戏
);
至此~的游戏手柄戏已戏基本完成了~如果需要什戏其他的功能或者需要戏行其他的戏置~可以自己你你你
去添加和修改。戏在的戏已戏可以戏的程序你你你来你工作了~接下戏戏做的就是在的MFC 程序中明一戏的声个
戏象戏用他~然后戏戏戏戏完成相戏的戏出。并状并
在DirectInputJSDlg.cpp文件中加入自定戏戏的戏文件#include "Joystick.h"。 然后在所有函的戏始明一全局戏量数声个Joystick joystick。
然后在函数BOOL CDIJoystickDlg::OnInitDialog()的最后添加如下代戏,joystick.m_hWnd = m_hWnd; //首先戏得口句柄窗
if(!joystick.Initialise()) //初始化
{
OutputDebugString("初始化游戏杆失戏 - in CDIJoystickDlg::OnInitDialog\n");
OnCancel();
return FALSE;
}
SetTimer(1,50,NULL); //戏置一个50毫秒定戏器
首先需要把口句柄戏戏到窗m_hWnd中~因戏在戏置戏作等戏的戏候需要用到戏句柄。然后戏行初始化。最后戏个置一个50毫秒的定戏器~戏生它会WM_TIMER消息。
在CDirectInputJSDlg戏的性中点戏重戏戏添加属框写CDirectInputJSDlg::OnCancel()函。加入如下代数戏,
KillTimer(1); //戏毁定戏器
OutputDebugString("程序退出 - OnCancel()\n"); 在CDirectInputJSDlg戏的性中点戏消息戏戏~在属框WM_TIMER消息中戏戏添加OnTimer()函~下面数将代戏入函,写数
char ch[20];
if(FAILED( joystick.PollDevice() ) ) //戏循
{
KillTimer( 1 );
MessageBox(TEXT("戏取戏戏戏戏戏状") \
TEXT("程序即将退出"), TEXT("DirectInput 示例"),
MB_ICONERROR | MB_OK );
}
if (joystick.m_diJs.lX < 0 )
OutputDebugString(" 方向左戏按下 \n");
if (joystick.m_diJs.lX > 0 )
OutputDebugString(" 方向右戏按下 \n");
if (joystick.m_diJs.lY < 0 )
OutputDebugString(" 方向上戏按下 \n");
if (joystick.m_diJs.lY > 0 )
OutputDebugString(" 方向下戏按下 \n");
for(int i = 0; i < 32 ; i++)
if (joystick.m_diJs.rgbButtons[i] & 0x80){
StringCchPrintf(ch,20,"按戏 %d 戏按下\n",i);
OutputDebugString(ch);
}
戏里如果戏循失戏~戏戏毁定戏器~做出提示。然后判断joystick.m_diJs的各个成戏。 注意joystick.m_diJs.rgbButtons[i] & 0x80 ~判手柄按戏的戏需要戏断状它跟0x80相。与 外~如果要使用另StringCchPrintf()函~需要添加戏文件~数#include 。
戏在完成戏戏离遥你剩一步之了~需要的是戏戏境的戏置。
右戏点戏~戏戏性~在戏接器~戏入戏戏中的属框附加依戏戏中添加如下的戏, dxguid.lib dxerr9.lib dinput8.lib comctl32.lib
然后在菜戏戏工具中戏戏戏戏~戏目~VC++目戏戏戏中添加框SDK的包含文件目戏和戏文件目戏。 最后可以戏戏的程序看看是否成功。在你你Debug模式下~可以在戏戏戏中看到戏出信息。 戏~基本上就是戏戏。如果需要戏手柄的戏入做更多的戏出~那戏可以戏戏你你心思戏戏
本文档为【MFC下游戏手柄的添加】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。