VC++2010游戏开发随记之四十二 - 图文(2)

2020-02-21 11:24

2.创建DirectInput接口和设备

在DirectInput中我通过们调用DirectInputCreate函数创建并初始化IDirectInput接口,我们可以在MSDN中查到该函数的声明如下:

[cpp] view plaincopyprint?

1. HRESULT DirectInput8Create( 2. HINSTANCE hinst, 3. DWORD dwVersion, 4. REFIID riidltf, 5. LPVOID * ppvOut, 6. LPUNKNOWN punkOuter 7. )

■ 第一个参数,HINSTANCE类型的hinst,表示我们当前创建的DirectInput的Windows程序句柄,这个值填我们在WinMain函数的参数中的实例句柄就可以了。 ■ 第二个参数,DWORD类型的dwVersion,表示我们当前使用的DirectInput版本号,通常可以取DIRECTINPUT_VERSION或者DIRECTINPUT_HEADER_VERSION,这两个值对应的是同一个值,为0x0800。所以我们在这里还可以直接填0x0800。

归根揭底的话,可以通过【转到定义】大法在dinput.h中查到有如下代码:

[cpp] view plaincopyprint?

1. #define DIRECTINPUT_HEADER_VERSION 0x0800 2. #ifndef DIRECTINPUT_VERSION

3. #define DIRECTINPUT_VERSION DIRECTINPUT_HEADER_VERSION

大体意思很清楚了吧,先定义一下DIRECTINPUT_HEADER_VERSION=0x0800,然后再说如果没有定义DIRECTINPUT_VERSION的话,就定义一个DIRECTINPUT_VERSION= DIRECTINPUT_HEADER_VERSION。

■ 第三个参数,REFIID类型的riidltf,表示接口的标志,通常取IID_IDirectInput8就可以了。

■ 第四个参数,LPVOID 类型的* ppvOut,用于返回我们新创建的IDirectInput8接口对象的指针。

■ 第五个参数,LPUNKNOWN类型的punkOuter,一个和COM对象接口相关的参数,通常我们设为NULL就可以了。

这个函数执行成功的话TINPUTVER会返回HRESULT类型的DI_OK,而失败的话根据不同的调用失败原因,会返回

DIERR_BETADIRECSION,DIERR_INVALIDPARAM,DIERR_OLDDIRECTINPUTVERSION, DIERR_OUTOFMEMORY中的一个。所以我们可以根据FAILED宏来判断我们IDirectInput8接口对象是否创建成功了。 下面是一个调用的例子:

[cpp] view plaincopyprint?

1. // 创建DirectInput设备

2. LPDIRECTINPUT8 g_pDirectInput = NULL;

3. if(FAILED(DirectInput8Create(hInstance,0x0800, IID_IDirectInput8,

(void**)&g_pDirectInput, NULL))) 4. return E_FAIL;

这步完成之后,咱们的定义的DIRECTINPUT8接口对象g_pDirectInput就有了权利,新官上任了。

在IDirectInput8接口中包含了很多用于初始化输入设备及获得设备接口的方法。其中,常用的方法为EnumDevices和CreateDevices。前者EnumDevices用于获得输入设备的类型,而后者CreateDevices用于为输入设备创建IDirectInputDevice8接口对象。

系统中每一个已安装的设备都有一个系统分配的全局唯一标示符(GUID,Global Unique Identification),从英文单词意义上就可以知道,系统中的每个设备都有着独一无二的GUID,这个GUID又唯一的标志了系统中的某某设备。就像我们每个人都有着独一无二的的身份证号码。

要使用某个设备的话,首先我们就需要知道他的GUID。

鼠标和键盘作为我们电脑中最为重要的外设,DirectInput对他们做了特殊对待,给了后门,定义了他们的GUID分别为GUID_Keyboard和GUID_SysMouse。而对于其他的输入设备,我们就用上面提到过的EnumDevices方法枚举出这些设备,以得到他们的GUID,我们可以在MSDN中查到这个方法有如下声明:

[cpp] view plaincopyprint?

1. HRESULTEnumDevices( 2. DWORD dwDevType,

3. LPDIENUMDEVICESCALLBACKlpCallback, 4. LPVOID pvRef, 5. DWORD dwFlags 6. )

■ 第一个参数,DWORD类型的dwDevType,指定我们需要枚举的设备类型。 可取的值为DI8DEVCLASS_ALL,DI8DEVCLASS_DEVICE,DI8DEVCLASS_GAMECTRL,DI8DEVCLASS_KEYBOARD,DI8DEVCLASS_POINTER中的一个。

■ 第二个参数,LPDIENUMDEVICESCALLBACK类型的lpCallback,用于指定一个回调函数的地址,当系统中每找到一个匹配的设备时,就会自动调用这个回调函数。 ■ 第三个参数,LPVOID类型的pvRef,返回我们当前匹配设备的GUID值。 ■ 第四个参数,DWORD类型的dwFlags,指定我们枚举设备的方式。取值可以下面的一个或者多个值:DIEDFL_ALLDEVICES,DIEDFL_ATTACHEDONLY,DIEDFL_FORCEFEEDBACK,DIEDFL_INCLUDEALIASES,DIEDFL_INCLUDEHIDDEN,DIEDFL_INCLUDEPHANTOMS。

取得我们需要使用的设备的GUID后,就可以根据这个GUID来调用IDirectInput8接口的CreateDevice方法,进而来创建设备的IDirectInputDevice8接口对象了。 我们可以在MSDN中查到IDirectInput8::CreateDevice方法的声明如下:

[cpp] view plaincopyprint?

1. HRESULTCreateDevice( 2. REFGUID rguid,

3. LPDIRECTINPUTDEVICE*lplpDirectInputDevice, 4. LPUNKNOWN pUnkOuter 5. )

■ 第一个参数,REFGUID类型的rguid,就是填我们上面讲到的输出设备的GUID。系统中当前使用的键盘对应GUID_SysKeyboard,当前使用的鼠标对应

GUID_SysMouse。其他设备的话,就用我们刚刚讲过的EnumDevices获取一下就行了。

■ 第二个参数,LPDIRECTINPUTDEVICE类型的*lplpDirectInputDevice,表示我们所创建的输入设备对象的指针地址,可以说调用这个CreateDevice参数就是在初始化这个参数。

■ 第三个参数,LPUNKNOWN类型的pUnkOuter,、和COM对象的IUnknown接口相关的一个参数,一般我们不去管它,设为NULL就可以了。

讲解完了,当然得看一个调用实例。下面的代码中CreateDevice方法的第二个参数我们填的是GUID_SysMouse,所以我们在为系统鼠标创建一个DirectInput设备接口对象:

[cpp] view plaincopyprint?

1. LPDIRECTINPUTDEVICE8 g_pMouseDevice = NULL;

2. if(FAILED (g_pDirectInput->CreateDevice(GUID_SysKeyboard,&g_pKeyb

oardDevice,NULL)))

3. return E_FAIL;

3.设置数据格式

数据格式用于表示设备状态信息的存储方式,每种设备都有一种用于读取对应数据的特定数据格式,所以对每种设备都要区别对待。所以要使程序从设备读入数据的话,首先我们需要告诉DirectInput读取这种数据所采用的格式。

设置数据格式通常我们都是通过IDirectInputDevice8接口的SetDataFormat方法来做到的,这个方法可以把设备的数据格式填充到一个DIDATAFORMAT接口类型的对象。该方法的声明如下:

[cpp] view plaincopyprint?

1. HRESULT SetDataFormat( 2. LPCDIDATAFORMAT lpdf 3. )

SetDataFormat方法唯一的变量就是LPCDIDATAFORMAT类型的lpdf,DirectInput已经为我们准备好了一些备选的参数,下面是一个列表: 数据格式 精析 c_dfDIkeyboard 标准键盘结构,包含256个字符,每个字符对应着每个键 c_dfDIMouse 标准鼠标结构,带有3个轴和4个按钮 c_dfDIMouse2 扩展鼠标结构,带有3个轴和8个按钮 c_dfDIJoystick 标准游戏杆,带有三个定位轴,3个旋转轴,两个滑块,1个POV hat和32个按钮 c_dfDIJoystick2 扩展的游戏杆 依然是一个调用实例,设置鼠标的数据格式: [cpp] view plaincopyprint? 1. g_pMouseDevice->SetDataFormat(&c_dfDIMouse);

4.设置协作级别

在Windows操作系统中,系统中的每个应用程序都通常会使用多个输入设备,并且同一输入设备也可能被多个应用程序同时使用。因此,需要一种方式来共享和协调应用程序对设备的访问。在DirectInput中,祭出的是协作级别(Cooperative Level)这套处理方式。

协作级别定义了进程与其他应用程序和操作系统共享设备的方式。设备一旦创建就需要设置它的协作级别,协作级别表示了应用程序对设备的控制权。

DirectInput的协作级别可以以两套方案来分类:前台、后台模式和共享、独占模式。

Ⅰ.前台模式与后台模式

其中,前台模式表示只有当窗口处于激活状态时,才能获得设备的控制权。而当处于非激活状态时,会自动失去设备的控制权;后台模式表示可以在任何状态下获取设备,即使是在窗口处于非激活状态时。后天模式可以被任何应用程序在任何时候使用并获取设备数据。

Ⅱ.共享模式与独占模式

共享模式表示多个应用程序可以共同使用该设备,而独占模式表示应用程序是唯一使用该设备的应用程序。这里需要注意一下,独占模式并非意味着其他应用程序不能获


VC++2010游戏开发随记之四十二 - 图文(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:船舶管理笔记(1)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: