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

2020-02-21 11:24

取输入设备状态,如果进程同时使用了后台模式与独占模式的话,当其他进程申请了独占模式的话,这个进程就会失去设备的控制权。

我们平常都是通过IDirectInputDevice8接口的SetCooperativeLevel方法来设置设备的协作级别的,我们可以在MSDN中查到SetCooperativeLevel的声明如下:

[cpp] view plaincopyprint?

1. HRESULT SetCooperativeLevel( 2. HWND hwnd, 3. DWORD dwFlags 4. )

■ 第一个参数,HWND类型的hwnd,显然就是填想要与当前设备相关联的窗口句柄了,且这个窗口需要属于当前进程的顶级窗口。 ■ 第二个参数,DWORD类型的dwFlags,描述了当前设备的协作级别类型,也就是填我们上面讲到的前台、后台模式和共享、独占模式等一些模式的标识符,可取一个值到多个值,浅墨把取值在下表中出来了: 协作级别类型 精析 DISCL_BACKGROUND 后台模式,一般我们让他与DISCL_NONEXCLUSIVE(非独占模式)配合使用 DISCL_FOREGROUND 前台模式,一般我们让他与DISCL_EXCLUSIVE(独占模式)配合使用 DISCL_EXCLUSIVE 独占模式 DISCL_NONEXCLUSIVE 非独占(共享)模式 DISCL_NOWINKEY 让键盘上烦人的Windows键失效 注意,后台模式和独占模式不能同时选择,用脚丫子来想都知道他们两个组合起来不符合逻辑,既然都是在后台了,还谈什么独占呢? 下面依旧是一个调用实例,将鼠标设备的协作级别设为前台、独占模式: [cpp] view plaincopyprint? 1. g_pMouseDevice->SetCooperativeLevel(hwnd,DISCL_FOREGROUND |DISCL_

EXCLUSIVE);

5.设置特殊属性

设备的特殊属性包含设备的数据模式、缓冲区大小、以及设备的最小最大范围等等。DirectInput为我们提供了SetProperty方法来设置设备的特殊属性,我们可以在MSDN中查到这个方法有如下原型: HRESULT SetProperty( REFGUID rguidProp, LPCDIPROPHEADER pdiph )

这个方法平常用得不算多,因为篇幅原因暂且先不详细讲了,需要用的时候大家去查一下文档就可以了。

6.获取和轮询设备

首先是一个常识,在访问和使用任何输入设备之前,首先必须获得该输入设备的控制权。权力这东西,人人都喜欢,对其趋之若鹜,在我们的计算机中也不例外。其他的程序随时都可能勾心斗角,争夺并抢走对输入设备的控制权。所以我们在使用之前,往往都要重新获取一下设备的控制权,以确保权力在我们手中。

在DirectInput中,权力的敲门砖为IDirectInput8接口的Acquire方法,我们可以在MSDN中查到这个“权力权杖”有如下的原型:

[cpp] view plaincopyprint?

1. HRESULT Acquire()

我们可以发现他简简单单清清白白,没有参数,返回值为HRESULT。调用起来当然是非常简单:

[cpp] view plaincopyprint?

1. g_pMouseDevice->Acquire();

为了大家看起来简明扼要,咱们这里没有用if和FAILD宏给他括起来,进行错误处理。

另外需要注意的是,在获得输入设备的控制权之前,必须先调用IDirectInputDevice8接口的SetDataFormat或者SetActionMap方法来设置一下数据格式,不然我们调用Acquire方法的话,将直接给我们返回DIERR_INVALIDPARAM错误的。

另外需要讲到的是轮询。

轮询可以准备在合适的情况下读取设备数据。因为数据可能具有临界时间的。这个轮询的原型也是非常非常的简单:

[cpp] view plaincopyprint?

1. HRESULT Poll()

轮询用起来当然也是非常简单的:

[cpp] view plaincopyprint?

1. g_pMouseDevice ->Poll();

7.读取设备信息

在Direct3D应用程序中,拿到对输入设备的控制权之后,就可调用IDirectInputDevice8接口的GetDeviceState方法来读取设备的数据。而为了存储设备的数据信息,在调用该方法时,须传递一个数据缓冲区给GetDeviceState方法,这个GetDeviceState方法的原型我们可以在MSDN中查到是如下:

[cpp] view plaincopyprint?

1. HRESULT GetDeviceState( 2. DWORD cbData, 3. LPVOID lpvData 4. )

■ 第一个参数,DWORD类型的cbData,指定了我们缓冲区的大小(具体是哪个缓冲区在第二个参数中)。

■ 第二个参数,LPVOID类型的lpvData,表示一个获取当前设备状态的结构体的地址值。

他的数据格式和我们之前调用的IDirectInputDevice8::SetDataFormat方法有着前后呼应的密切联系。下面我们通过一个表格来看看是如何联系的: SetDataFormat中指定的数据格式 GetDeviceState中对应的缓冲区结构体 c_dfDIMouse DIMOUSESTATE结构体 c_dfDIMouse2 DIMOUSESTATE2结构体 c_dfDIKeyboard 大小为256个字节的数组 c_dfDIJoystick DIJOYSTATE结构体 c_dfDIJoystick2 DIJOYSTATE2结构体 比如,我们先调用了SetDataFormat设置了设备的数据格式为c_dfDIMouse: [cpp] view plaincopyprint? 1. g_pMouseDevice->SetDataFormat(&c_dfDIMouse);

那么我们在读取设备信息的时候调用GetDeviceState就需要把第二个参数填与dfDIMouse对应的DIMOUSESTATE结构体的一个实例:

[cpp] view plaincopyprint?

1. DIMOUSESTATE dimouse

2. g_pMouseDevice-> GetDeviceState(sizeof(dimouse),(LPVOID)&dimouse)

;

对此,我们可以抽象出一个函数,专门对付疑难杂症,应对各种类型的设备的数据读取,而且还考虑到了设备如果丢失掉了,在合适的时间自动重新获取该设备:

[cpp] view plaincopyprint?

1. //***************************************************************

************************** 2. // Name: Device_Read(); 3. // Desc: 智能读取设备的输入数据

4. //***************************************************************

**************************

5. BOOL Device_Read(IDirectInputDevice8*pDIDevice, void* pBuffer, lo

nglSize)

6. {

7. HRESULThr; 8. while(true) 9. {

10. pDIDevice->Poll(); // 轮询设备 11. pDIDevice->Acquire(); // 获取设备的控制

12. if(SUCCEEDED(hr = pDIDevice->GetDeviceState(lS

ize, pBuffer))) break;

13. if(hr !=DIERR_INPUTLOST || hr != DIERR_NOTACQ

UIRED) return FALSE;

14. if(FAILED(pDIDevice->Acquire())) return FALSE; 15. }

16. returnTRUE; 17. }

到这一步之后,就是调用一下Device_Read来读取数据了。调用之后,我们的键位数据其实就存在了g_pKeyStateBuffer之中,我们接下来要做的就是用if语句对g_pKeyStateBuffer数组中对应的键位进行试探,看看这个键是否被按下了。如果按下,就进行相关的处理就可以了,比如:

[cpp] view plaincopyprint?

1. Device_Read(g_pKeyboardDevice,(LPVOID)g_pKeyStateBuffer,sizeof(g_

pKeyStateBuffer)); 2.

3. if (g_pKeyStateBuffer[DIK_A] & 0x80) 4. fPosX -= 0.005f;

当然,在最后,使用完输入设备后,必须调用IDirectInputDevice8接口的Unacquire方法释放设备的控制权,所谓的杯酒释兵权,且需要接着调用Release方法释放掉设备接口对象。

[cpp] view plaincopyprint?

1. g_pMouseDevice->Unacquire(); 2. g_pMouseDevice->Release();


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

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

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

马上注册会员

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