游戏杆和键盘输入Word格式文档下载.docx
《游戏杆和键盘输入Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《游戏杆和键盘输入Word格式文档下载.docx(48页珍藏版)》请在冰点文库上搜索。
在以下的程序中,变量g_guidJoystick储存了游戏杆的GUID。
最后,g_bUseMouse和g_bUseJoystick变量代表了鼠标或游戏杆是否正作为输入装置。
如果鼠标或游戏杆都无法使用时,键盘会成为预设的输入装置。
#include<
dinput.h>
externLPDIRECTINPUTDEVICE2g_Keyboard_pdidDevice2;
externLPDIRECTINPUT7g_Keyboard_pDI;
LPDIRECTINPUT7g_pDI;
//DInput物件
LPDIRECTINPUT7g_Keyboard_pDI;
//Dinput物件
LPDIRECTINPUTDEVICE2g_pdidDevice2;
//DIDevice2界面
LPDIRECTINPUTDEVICE2g_Keyboard_pdidDevice2;
//DIDevice2
//界面
GUIDg_guidJoystick;
//游戏杆的GUID
BOOLg_bUseKeyboard=TRUE;
BOOLg_bUseMouse=FALSE;
BOOLg_bUseJoystick=FALSE;
BOOLbMouseLookOn=TRUE;
BOOLbMouseLookup_is_mouse_forward=TRUE;
一旦定义了变量,您必须加入程序来建立DirectInput7对象。
在WinMain程序中可以用CreateDInput程序来建立DirectInput7对象。
您再CreateInputDevice建立键盘输入装置,因为在您所设计的游戏中至少要有支持键盘输入。
您不需要对键盘执行列举过程,因为所有的计算机都会有一个键盘(计算机没有安装键盘装置时甚至无法开机)。
当使用者离开游戏时,您需要去呼叫DestroyInputDevice和DestroyDInput程序去终止DirectInput装置和DirectInput接口,以确保您已经清除那些为了支持DirectInput行为而产生的对象。
那些在游戏开头和结束时(在这里是加在WinMain程序中)负责作对象的建立和终止的必要呼叫动作,如下:
//--------------------------------------------------------------------
//WinMain
//说明:
程序进入点
intPASCALWinMain(HINSTANCEhInst,HINSTANCE,LPSTR,intnCmdShow)
{
.
.
//
//建立Dinput对象
if(FAILED(d3dApp.CreateDInput(d3dApp.Get_hWnd())))
{
returnFALSE;
}
if(FAILED(hr=CoInitialize(NULL)))returnFALSE;
//建立一个键盘装置
if(FAILED(d3dApp.CreateInputDevice(d3dApp.Get_hWnd(),g_Keyboard_pDI,g_Keyboard_pdidDevice2,GUID_SysKeyboard,&
c_dfDIKeyboard,DISCL_NONEXCLUSIVE|DISCL_FOREGROUND)))
.
.
..
d3dApp.InitRRvariables();
d3dApp.LoadRR_Resources();
d3dApp.Run();
PrintMessage(NULL,"
Quitting"
NULL,LOGFILE_ONLY);
d3dApp.DestroyInputDevice();
d3dApp.DestroyDInput();
d3dApp.FreeDirectSound();
CoUninitialize();
returnTRUE;
}
您可以呼叫DirectInputCreateEx函式来建立实际的DirectInput对象。
这个函式会建立一个DirectInput对象的实例,提供DirectInput接口的最新集合。
您可以传入dinput.h中定义的DIRECTINPUT_VERSION值。
这个值一旦传入后,会请求使用最新的DirectInput版本。
您必须将第三个参数设成IID_IDirectInput7,否则会传回错误值。
如果呼叫成功,函式会传回一个指到IDirectInput7COM界面的指针。
您可以看到CreateDInput不久即会取得所有在执行系统上可用的DirectInput装置。
在这个程序中,您可以用DirectInputCreateEx程序来取得某个DirectX7DirectInput接口。
以下是DirectInputCreateEx的函式宣告:
HRESULTWINAPIDirectInputCreateEx(
HINSTANCEhInst,
DWORDdwVersion,
REFIIDriidltf,
LPVOID*ppvOut,
LPUNKNOWNpunkOuter
);
参数
说明
hInst
建立DirectInput对象的应用程序或DLL的实例程序代码。
dwVersion
版本编号,必须是dinput.h标头档中使用的DIRECTINPUT_VERSION,它可用来决定您的程序设计时使用的DirectInput版本。
riidltf
需求DirectInput界面的GUID。
可用值为IID_IDirectInput,IID_IDirectInput2和IID_IdirectInput7。
ppvOut
用一个DirectInput界面指针来初始化指针的地址。
punkOuter
控制对象的IUnknown接口的地址。
如果此接口未被聚集时,就传NULL给此参数。
大部分的呼叫者都传NULL给此参数。
//-------------------------------------------------------------------
//名称:
CreateDInput
将DirectInput物件初始化
HRESULTCMyD3Dapplication:
:
CreateDInput(HWNDhWnd)
//建立主要的DirectInput对象。
CD3Dapplication:
CreateDInput()"
NULL,
LOGFILE_ONLY);
If(FAILED(DirectInputCreateEx((HINSTANCE)GetWindowLong(
hWnd,GWL_HINSTANCE),DIRECTINPUT_VERSION,
IID_IDirectInput7,(LPVOID*)&
g_pDI,NULL)))
DisplayError("
DirectInputCreate()failed."
));
returnE_FAIL;
//检查是否有游戏杆存在。
如果有的话,列举回传
//会储存该游戏杆的GUID,以让我们稍后建立。
ZeroMemory(&
g_guidJoystick,sizeof(GUID));
g_pDI->
EnumDevices(DIDEVTYPE_JOYSTICK,EnumJoysticksCallback,&
g_guidJoystick,DIEDFL_ATTACHEDONLY);
//键盘
if(FAILED(DirectInputCreateEx((HINSTANCE)GetWindowLong(hWnd,
GWL_HINSTANCE),DIRECTINPUT_VERSION,
g_Keyboard_pDI,
NULL)))
returnS_OK;
建立DirectInput对象之后,CreateDInput程序会列举出系统上的游戏杆装置,因为除了键盘以外,您无法确定还有哪些装置存在。
因为如此,程序会呼叫IDirectInput7:
EnumDevices方法,将第一个参数设为DIDEVTYPE_JOYSTICK,以找出机器上已接的所有游戏杆装置。
(如果您想找出连接的键磁盘时,您可以将它设成DIDEV-TYPE_KEYBOARD,或是您想找出所有可用的输入装置时,可设为NULL)在DirectInput的术语中,游戏杆可以指某些装置的任一种,包括标准游戏杆、驾驶盘、游戏控制板和力回馈装置。
以下是本方法的函式宣告:
BOOLIdirectInput:
EnumDevices(
DWORDdwDevType,
LPDIENUMCALLBACKlpCallback,
LPVOIDpvRef,
DWORDdwFlags
dwDevType
装置型态筛选器。
如果您将此参数设为0,则函式会列举所有装置型态。
如果您想要列举某个特定装置型态,请传入装置型态常数,如DIDEVTYPE_MOUSE或DIDEVTYPE_KEYBOARD。
lpCallback
回传函式的地址,此函式被呼叫时会加上每个DirectInput装置的描述。
pvRef
程定定义的32位值,每次呼叫列举回传都会将此值传入。
dwFlags
表示列举的范围。
可以是以下任一旗标值:
DIEDFL_ALLDEVICES
默认值。
所有已安装的装置都会列举。
DIEDFL_ATTACHEDONLY
只列举附加及安装的装置。
DIEDFL_FORCEFEEDBACK
只列举支持力回馈的装置。
DIEDFL_INCLUDEALIASES
包含那些是其它装置的别名(alias)装置。
DIEDFL_INCLUDEPHANTOMS
包含幽灵(phantom)装置。
您可以注意到我用DIEDFL_ATTACHEDONLY值作为呼叫时的最后值,这表示我只关心有连接和安装在系统上的装置。
在许多情况下,您也会打算这么做。
您你传给EnumDevices呼叫动作的列举程序是Enum-JoysticksCallback程序。
对每个列举的游戏杆来说,这个程序只会被呼叫一次。
对每个列举装置来说,您建立了一个装置接口以应用在您的程序中。
EnumJoysticksCallback
每个列举游戏杆都会呼叫一次。
如果我们找到了,
//可以建立它的装置接口以便加以运用。
BOOLCALLBACKEnumJoysticksCallback(LPCDIDEVICEINSTANCEpInst,VOID*pvContext)
memcpy(pvContext,&
pInst->
guidInstance,sizeof(GUID))
returnDIENUM_STOP;
除了加到WinMain程序中的程序代码外,您还需要在WndProc程序中加入程序代码来取得及释放想在程序中用到的DirectInput装置。
在DirectInput中,当您取得某个装置时,您就可以让应用程序存取它。
当取得装置后,DirectInput会让您的程序使用装置的相关数据。
当某个装置被释放后,您还可以改变它的特性,但不可以取得它的数据。
一旦设定了共享等级(我们稍后会提到),当您的程序移往背景作业时,装置会被自动释放。
举例来说,当使用者按下某个菜单时,鼠标会自动被释放,因为此时Windows会接管该装置。
当您想要改变某个装置的性质时,您也需要手动加以释放(除非您是要在力回馈装置于掌控模式下改变其增益值)。
如果您没有释放它又发生了类似硬件中断的事件,存取数据缓冲区时(例如要改变缓冲区大小)可能会造成数据完全毁坏。
还有一件您应该记住的是当您的应用程序在排他模式(exclusivemode)下使用鼠标时,Windows无法存取该鼠标,因此您如果希望Windows使用鼠标时,您需要先释放它。
以下是MsgProc程序中新增用来选择输入装置的程序:
LRESULTCMyD3Dapplication:
MsgProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam)
switch(msg)
.
caseWM_COMMAND:
switch(LOWORD(wParam))
{
caseIDM_SELECTINPUTDEVICE:
DialogBox((HINSTANCE)GetWindowLong(hWnd,
GWL_HINSTANCE),
MAKEINTRESOURCE(IDD_SELECTINPUTDEVICE),
hWnd,(DLGPROC)InputDeviceSelectProc);
break;
.
.
default:
returnCD3Dapplication:
MsgProc(hWnd,uMsg,
wParam,lParam);
}
break;
.
.
default:
MsgProc(hWnd,uMsg,wParam,lParam);
returnDefWindowProc(hWnd,msg,wParam,lParam);
取得键盘、鼠标或游戏杆
一旦列举了所有输入装置,您需要让使用者选择想用的输入装置。
以下的InputDeviceSelectProc回传程序说明了一种您可以让使用者选择想要输入装置的作法。
这个程序让使用者从「选择输入装置」的下拉式菜单中挑选:
游戏杆、键盘或是键盘加鼠标。
DirectInputDevice2对象代表了输入装置。
记住我之前提过,Microsoft这里说的游戏杆指的是许多种不同的输入装置-包括游戏控制板和驾驶盘。
因此,我的程序也会引用这种术语。
我会将键盘和鼠标以外的所有装置都称作游戏杆。
有二个GUID(GUID_SysKeyboard和GUID_SysMouse)已经预先定义成键盘和鼠标。
当建立DirectInputDevice2对象来代表除了系统鼠标或键盘的其它装置时,您必须使用该装置的案例GUID,这可以从您呼叫IDirectInput7:
EnumDevices时得到。
在使用者决定了他/她想要建立的装置后,不论是要用键盘、鼠标或游戏杆都会呼叫CreateInputDevice程序。
InputDeviceSelectProc
选择输入装置的对话子程序
BOOLCALLBACKInputDeviceSelectProc(HWNDhWnd,UINTmsg,WPARAMwParam,LPARAMlParam)
HWNDhwndKeyboardButton=GetDlgItem(hWnd,IDC_KEYBOARD);
HWNDhwndMouseButton=GetDlgItem(hWnd,IDC_MOUSE);
HWNDhwndJoystickButton=GetDlgItem(hWnd,IDC_JOYSTICK);
If(WM_INITDIALOG==msg)
SendMessage(hwndKeyboardButton,BM_SETCHECK,
g_bUseKeyboard,0L);
SendMessage(hwndMouseButton,BM_SETCHECK,
g_bUseMouse,0L);
SendMessage(hwndJoystickButton,BM_SETCHECK,
g_bUseJoystick,0L);
EnableWindow(hwndJoystickButton,
(g_guidJoystick!
=GUID_NULL));
returnTRUE;
if(WM_COMMAND==msg&
&
IDOK==LOWORD(wParam))
//终止旧装置。
pCMyApp->
DestroyInputDevice();
//检查对话控件以确认建立
//的装置型态。
g_bUseKeyboard=SendMessage(hwndKeyboardButton,
BM_GETCHECK,0,0L);
g_bUseMouse=SendMessage(hwndMouseButton,
BM_GETCHECK,0,0L);
g_bUseJoystick=SendMessage(hwndJoystickButton,
If(g_bUseKeyboard)
CreateInputDevice(GetParent(hWnd),
g_Keyboard_pDI,
g_Keyboard_pdidDevice2,
GUID_SysKeyboard,
&
c_dfDIKeyboard,
DISCL_NONEXCLUSIVE|
DISCL_FOREGROUND);
g_Keyboard_pdidDevice2->
Acquire();
if(g_bUseMouse)
pCMyApp->
CreateInputDevice(GetParent(hWnd),g_pDI,g_pdidDevice2,
GUID_SysMouse,&
c_dfDIMouse,
DISCL_EXCLUSIVE|DISCL_FOREGROUND);
g_pdidDevice2->
pCMyApp->
CreateInputDevice(GetParent(hWnd),
g_Keyboard_pDI,
g_Keyboard_pdidDevice2,