当前位置:51VIP源码软件音乐小游戏下载联盟网络学院程序开发VC → DirectX揭密

DirectX揭密

减小字体 增大字体 作者:      来源:本站整理  发布时间:2008-9-6 6:13:34 我要发布文章
COM技术中的聚合有关,可以用NULL安全的忽略。返回
值是一个HRESULT,是COM的标准返回类型,可以将返回值与可能的返回值比较,也可以使
用COM宏定义SUCCESS或FAILED来检查。

使用DirectInputCreate能够容易地创建高层对象并得到其主。这是DirectX的又
一个设计方法,每个DirectX组件都提供助手来创建高层对象,例如DirectInputCreate
或DirectDrawCreate。在程序中可以用这些助手函数创建DirectX对象,然而,这些
实际上创建的是COM对象。这个工作也可以用叫作CoCreateInstance的标准Win32 API函
数来完成。这就引出了创建DirectInput对象的第二中方法。

在Win32中用CoCreateInstance创建COM对象非常普遍。如果程序中已经使用
CoCreateInstance创建了其他COM对象,开发者可能就会希望也用它来创建DirectX对象。
因为COM对象在安装时就在系统中注册过,所以唯一需要知道的就是对象的GUID,用它来
创建一个实例。创建DirectX对象需要的全部GUID都在头文件中声明,并在库文件
DXGUID.LIB中定义。可以将一个预定义的GUID传递给CoCreateInstance,让Windows为你
创建对象。CoCreateInstance定义如下:

STDAPI CoCreateInstance(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID * ppv
);


第一个参数是要创建对象的GUID,DirectX定义的GUID是叫作CLSID_DirectInput的GUID
结构变量。第二个参数是熟悉的pUnkOuter,同样可以用NULL忽略。第三个参数dwClsContext
定义COM对象在何处创建,DirectX只支持进程内服务器,所以必须使用
CLSCTX_INPROC_SERVER。

第四个参数是两种方法真正的不同之处。记住COM对象对外提供,与对象本身一样,接
口也用GUID识别。使用第一种方法,不能选择得到的,总是得到IdirectInput。使用
CoCreateInstance可以请求对象所支持的任何接口,方法是使用为预定义的GUID。但
是在DirectInput这是没有意义的,因为DirectInput对象的唯一有用的就是
IdirectInput。其它DirectX组件支持多个有用的。(例如,DirectDraw对象可以用
IdirectDraw或IDirectDraw2操作。)

最后一个参数是程序中变量的实际地址。

现在就拥有了对象和对象的一个。CoCreateInstance方法还需要另外一步:必须要首
先调用一个初始化对象。DirectInputCreate提供的是一个已经初始化过的
DirectInput对象,但CoCreateInstance没有特定于DirectInput的认识,因此必须调用
IdirectInput接口的初始化成员。 假设如下定义IdirectInput变量:

LPDIRECTINPUT g_lpDI

可以如下调用初始化:

g_lpDI->Initialize( hInstance, DIRECTINPUT_VERSION);

既然选择采取这种标准方法创建对象,就不得不注意COM需要的其他标准,例如需要调用
CoInitialize和CoUninitialize。
使用DirectInput对象
一旦拥有了DirectInput对象,就可以用它来创建DirectInputDevice对象,来管理系统中
特定的设备。创建DirectInputDevice对象要使用CreateDevice,它是作为
IdirectInput一部分的五个之一。CreateDevice需要所请求设备的GUID,返回新
DirectInputDevice对象的IdirectInputDevice。

HRESULT CreateDevice(
REFGUID rguid,
LPDIRECTINPUTDEVICE *lplpDirectInputDevice,
LPUNKNOWN pUnkOuter
);

这些内容看起来很熟悉,因为它与CoCreateInstance和DirectInputCreate类似。但是,
现在还没有完全准备好开始DirectInputDevice对象,原因是在创建DirectInputDevice对
象前需要该设备的GUID。

DirectInput库为创建DirectInputDevice对象预定义了两个GUID:GUID_SysKeyboard和
GUID_SysMouse。将两者之一直接传递给CreateDevice,就会得到相应设备的
DirectInputDevice对象。

注意,令人感到奇怪的是缺少对游戏杆的预定义GUID。在Windows中,通常都有系统键盘
和系统鼠标,另一方面,系统本身并不使用游戏杆。可以安装一个或者多个游戏杆,但系统
管理的范围只限于驱动程序级。系统并为这些设备指定特殊的系统状态,也不会在日常事务
中使用这些设备。因此,为游戏杆定义GUID对DirectInput来说是不合理的。

那么,如何才能找到与系统连接的游戏杆的GUID呢?要得到它们,必须要列举设备。列举
系统设备和性能在DirectX中相当普遍。要列举系统中的输入设备,需要使用EnumDevices
。EnumDevices是IdirectInput的一部分,如下定义:

HRESULT EnumDevices(
DWORD dwDevType,
LPDIENUMCALLBACK lpCallback,
LPVOID pvRef,
DWORD dwFlags
);

注意此与Windows中其它列举API相同,例如EnumWindows。第二个参数是一个回调函
数。第三个参数是程序中定义的32位值。第一个参数是想要列举的设备类型,对游戏杆来
说,是DIDEVTYPE_JOYSTICK(全部的设备类型列在表4中)。最后一个参数是详细描述想要
列举的设备的标志。现在支持的标志是DIEDFL_ATTACHEDONLY和DIEDFL_ALLDEVICES(这两
个标志是互斥独占的),此外还有DIEDFL_FORCEFEEDBACK,此标志表示力反馈设备,能够和
另两个标志位或操作。

图4:定义列举的输入设备:
以下定义的值可以传递给EnumDevices来选择列举哪种类型的输入设备。另外也支持子类
型,见SDK中DIDEVICEINSTANCE结构的文档。
值 说明
DIDEVTYPE_MOUSE 列举鼠标设备 (标准、轨迹球等)
DIDEVTYPE_KEYBOARD 列举键盘设备 (标准、键区等)
DIDEVTYPE_JOYSTICK 列举游戏杆设备 (操纵杆、操纵轮、方向舵等)
DIDEVTYPE_DEVICE 列举其它设备


当EnumDevices列举系统中的输入设备时,反复地调用回调函数。回调定义如下:

BOOL CALLBACK EnumProc(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) ;

因为回调是由用户程序定义并传递给EnumDevices的,所以是调用CreateDevice的最
合适地方,直到创建了满足需要的足够DirectInputDevice对象为止。但是回调并非一
定要如此实现,可以简单的将列举设备的所有GUID保存在一个表中,在以后的代码中使用。

回调接受两个参数。第二个参数是程序定义的传递给EnumDevices的32位值。更重要
的是,第一个参数传递指向一个结构的,该结构包含关于能够与列举标准匹配的单个设
备的许多信息。这是一个DIDEVICEINSTANCE结构。此结构中最重要的一条信息是设备的
GUID,保存在结构的guidInstance成员中。

程序中完全完成DirectInput有关的工作后,就应该调用IdirectInput的Release
成员。这就告诉DirectInput对象可以释放自己了。在DirectX中,最好养成释放对象的习
惯,从低层对象开始,到高层对象结束。正常情况下程序会作为清除或者关闭的例行公事的
一部分调用Release。这是使用每个DirectX组件的必要步骤,也是使用每个COM组件的必
要步骤。

[1]  

上一页  [1] [2]