使用DirectInput进行交互(1)

DirectInput是一些COM对象的集合(和所有DirectX组件相同),这些COM对象描绘了输入系统和各个输入设备。最主要的对象是DirectInput8,它用于初始化系统以及创建输入设备接口。

DirectInput COM对象:

IDirectInput8:主要的DirectInput8 COM接口,其他所有接口都通过这个接口进行查询。
DirectInputDevice8:用于输入设备的COM接口,每个设备都有自己单独的接口可供使用。
DirectInputEffect:用于力反馈效果的 COM接口,比如某些游戏杆和某些鼠标上的力反馈效果。

各种输入设备(比如键盘、鼠标和游戏杆)都使用相同的接口对象IDirectInputDevice8。某些设备,比如游戏杆和鼠标,能够通过查询各自的IDirectInputDevice8对象以得到另外一个接口IDirectInputEffect,这个接口用于控制设备的力反馈效果。IDirectInput8组件对象包含了很多用于初始化输入系统以及获得设备接口的函数,在这些函数中,常用的只有两个,它们是IDirectInput8::EnumDevices和IDirectInput8::CreateDevice。

初始化DirectInput

要使用DirectInput,需要确保包含了DInput.h和在工程中链接了DInput8.lib,一个IDirectInput8对象就代表了主要DirectInput对象。
DirectInput提供了帮助函数DirectInput8Create用于初始化IDirectInput8接口。

Creates a Microsoft DirectInput object and returns an IDirectInput8 or later interface.

Syntax

HRESULT WINAPI DirectInput8Create(          HINSTANCE hinst,
    DWORD dwVersion,
    REFIID riidltf,
    LPVOID *ppvOut,
    LPUNKNOWN punkOuter
);

Parameters

hinst
Instance handle to the application or dynamic-link library (DLL) that is creating the DirectInput object. DirectInput uses this value to determine whether the application or DLL has been certified and to establish any special behaviors that might be necessary for backward compatibility.

It is an error for a DLL to pass the handle to the parent application. For example, an Microsoft ActiveX control embedded in a Web page that uses DirectInput must pass its own instance handle, and not the handle to the browser. This ensures that DirectInput recognizes the control and can enable any special behaviors that might be necessary.

dwVersion
Version number of DirectInput for which the application is designed. This value is normally DIRECTINPUT_VERSION. If the application defines DIRECTINPUT_VERSION before including Dinput.h, the value must be greater than 0x0800. For earlier versions, use DirectInputCreateEx, which is in Dinput.lib.

riidltf
Unique identifier of the desired interface. This value is IID_IDirectInput8A or IID_IDirectInput8W. Passing the IID_IDirectInput8 define selects the ANSI or Unicode version of the interface, depending on whether UNICODE is defined during compilation.

ppvOut
Address of a pointer to a variable to receive the interface pointer if the call succeeds.

punkOuter
Pointer to the address of the controlling object's IUnknown interface for Component Object Model (COM) aggregation, or NULL if the interface is not aggregated. Most calling applications pass NULL. If aggregation is requested, the object returned in ppvOut is a pointer to IUnknown, as required by COM aggregation.

使用DirectInput设备的步骤

1、获取设备GUID,调用IDirectInput8::EnumDevice来实现。
2、创建设备COM对象,调用IDirectInput8::CreateDevice来实现。
3、设置数据格式,调用IDirectInputDevice8::SetDataFormat来实现。
4、设置协作级别,调用IDirectInputDevice8::SetCooperativeLevel来实现。
5、设置任何特殊属性,调用IDirectInputDevice8::SetProperty来实现。
6、获得设备,调用IDirectInputDevice8::Acquire来实现。
7、轮询设备,调用IDirectInputDevice8::Poll来实现。
8、读取数据,调用IDirectInputDevice8::GetDeviceState来实现。

在进行这些步骤前,要确保声明了一个IDirectInput设备对象,即IDirectInputDevice8对象。

获取设备GUID

每个安装的设备都有一个系统分配的全局惟一标识符(global unique identification, GUID)数字。要使用一个设备,首先必须知道它的GUID。对于连接到系统上的鼠标和键盘,得到他们的GUID非常容易,DirectInput分别为鼠标和键盘的GUID定义成GUID_SysKeyboard和GUID_SysMouse。要使用GUID_SysKeyboard或GUID_SysMouse,必须在所有其他的预处理程序指令前定义INITGUID,或者将DXGuid.lib库链接到项目中。至于其他设备,必须枚举出这些设备,才能得到需要的那些设备的GUID。枚举就是遍历一个含有数据项的列表的过程,数据项就是诸如游戏杆之类的输入设备。假设有5个游戏杆连接到了系统上,那么在枚举的过程中,DirectInput就会传递各个游戏杆的相关信息,而且每次只传递一个游戏杆的信息,直到所有的游戏杆都已经被列出来或者列举被强行终止。

用于枚举设备的函数是IDirectInput8::EnumDevice。

Enumerates available devices.

Syntax

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

Parameters

dwDevType
Device type filter.

To restrict the enumeration to a particular type of device, set this parameter to a DI8DEVTYPE_* value. See DIDEVICEINSTANCE.

To enumerate a class of devices, use one of the following values.

DI8DEVCLASS_ALL
All devices.

DI8DEVCLASS_DEVICE
All devices that do not fall into another class.

DI8DEVCLASS_GAMECTRL
All game controllers.

DI8DEVCLASS_KEYBOARD
All keyboards. Equivalent to DI8DEVTYPE_KEYBOARD.

DI8DEVCLASS_POINTER
All devices of type DI8DEVTYPE_MOUSE and DI8DEVTYPE_SCREENPOINTER.

lpCallback
Address of a callback function to be called once for each device enumerated. See DIEnumDevicesCallback.

pvRef
Application-defined 32-bit value to be passed to the enumeration callback each time it is called.

dwFlags
Flag value that specifies the scope of the enumeration. This parameter can be one or more of the following values:

DIEDFL_ALLDEVICES
All installed devices are enumerated. This is the default behavior.

DIEDFL_ATTACHEDONLY
Only attached and installed devices.

DIEDFL_FORCEFEEDBACK
Only devices that support force feedback.

DIEDFL_INCLUDEALIASES
Include devices that are aliases for other devices.

DIEDFL_INCLUDEHIDDEN
Include hidden devices. For more information about hidden devices, see DIDEVCAPS.

DIEDFL_INCLUDEPHANTOMS
Include phantom (placeholder) devices.

Return Value

If the method succeeds, the return value is DI_OK.

If the method fails, the return value can be one of the following error values.

DIERR_INVALIDPARAM An invalid parameter was passed to the returning function, or the object was not in a state that permitted the function to be called. This value is equal to the E_INVALIDARG standard Component Object Model (COM) return value.
DIERR_NOTINITIALIZED The object has not been initialized.

Remarks

All installed devices can be enumerated, even if they are not present. For example, a flight stick might be installed on the system but not currently plugged into the computer. Set the dwFlags parameter to indicate whether only attached or all installed devices should be enumerated. If the DIEDFL_ATTACHEDONLY flag is not present, all installed devices are enumerated.

A preferred device type can be passed as a dwDevType filter so that only the devices of that type are enumerated.

On Microsoft Windows XP, Microsoft DirectInput enumerates only one mouse and one keyboard device, referred to as the system mouse and the system keyboard. These devices represent the combined output of all mice and keyboards respectively on a system. For information about how to read from multiple mice or keyboards individually on Windows XP, see the WM_INPUT documentation.

Note  The order in which devices are enumerated by DirectInput is not guaranteed.

lpCallback是一个指向枚举函数的指针,在系统上每找到一个匹配的设备时,就会调用该函数。

Application-defined callback function that receives Microsoft DirectInput devices as a result of a call to the IDirectInput8::EnumDevices method.

Syntax

BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi,
    LPVOID pvRef
);

Parameters

lpddi
Address of a DIDEVICEINSTANCE structure that describes the device instance.

pvRef
The application-defined value passed to IDirectInput8::EnumDevices or IDirectInput8::EnumDevicesBySemantics as the pvRef parameter.

Return Value

Returns DIENUM_CONTINUE to continue the enumeration or DIENUM_STOP to stop the enumeration.

Remarks

If a single hardware device can function as more than one DirectInput device type, it is enumerated as each device type that it supports. For example, a keyboard with a built-in mouse is enumerated twice: once as a keyboard and once as a mouse. The product globally unique identifier (GUID) is the same for each device, however.

lpddi是一个指向DIDEVICEINSTANCE结构体的指针,此结构体包含了此次调用时当前枚举设备上的信息。

Describes an instance of a Microsoft DirectInput device. This structure is used with the IDirectInput8::EnumDevices, IDirectInput8::EnumDevicesBySemantics, and IDirectInputDevice8::GetDeviceInfo methods.

Syntax

typedef struct DIDEVICEINSTANCE {
    DWORD dwSize;
    GUID  guidInstance;
    GUID  guidProduct;
    DWORD dwDevType;
    TCHAR tszInstanceName[MAX_PATH];
    TCHAR tszProductName[MAX_PATH];
    GUID  guidFFDriver;
    WORD  wUsagePage;
    WORD  wUsage;
} DIDEVICEINSTANCE, *LPDIDEVICEINSTANCE;
 
typedef const DIDEVICEINSTANCE  *LPCDIDEVICEINSTANCE;

Members

dwSize
Size of this structure, in bytes. This member must be initialized before the structure is used.

guidInstance
Unique identifier for the instance of the device. An application can save the instance globally unique identifier (GUID) into a configuration file and use it at a later time. Instance GUIDs are specific to a particular computer. An instance GUID obtained from one computer is unrelated to instance GUIDs on another.

guidProduct
Unique identifier for the product. This identifier is established by the manufacturer of the device.

dwDevType
Device type specifier. The least-significant byte of the device type description code specifies the device type. The next-significant byte specifies the device subtype. This value can also be combined with DIDEVTYPE_HID, which specifies a Human Interface Device (HID).

tszInstanceName
Friendly name for the instance. For example, "Joystick 1."

tszProductName
Friendly name for the product.

guidFFDriver
Unique identifier for the driver being used for force feedback. The driver's manufacturer establishes this identifier.

wUsagePage
If the device is a Human Interface Device (HID), this member contains the HID usage page code.

wUsage
If the device is a Human Interface Device (HID), this member contains the HID usage code.

创建设备COM对象

有了设备GUID,就能创建实际的IDirectInputDevice8 COM对象了,用于创建此COM对象的函数是IDirectInput8::CreateDevice。

Creates and initializes an instance of a device based on a given globally unique identifier (GUID), and obtains an IDirectInputDevice8 interface.

Syntax

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

Parameters

rguid
Reference to (C++) or address of (C) the instance GUID for the desired input device (see Remarks). The GUID is retrieved through the IDirectInput8::EnumDevices method, or it can be one of the predefined GUIDs listed below. For the following GUID values to be valid, your application must define INITGUID before all other preprocessor directives at the beginning of the source file, or link to Dxguid.lib.

GUID_SysKeyboard
The default system keyboard.

GUID_SysMouse
The default system mouse.

lplpDirectInputDevice
Address of a variable to receive the IDirectInputDevice8 interface pointer if successful.

pUnkOuter
Address of the controlling object's IUnknown interface for Component Object Model (COM) aggregation, or NULL if the interface is not aggregated. Most calling applications pass NULL.

Return Value

If the method succeeds, the return value is DI_OK.

If the method fails, the return value can be one of the following:

DIERR_DEVICENOTREG: The device or device instance is not registered with Microsoft DirectInput. This value is equal to the REGDB_E_CLASSNOTREG standard COM return value.

DIERR_INVALIDPARAM: An invalid parameter was passed to the returning function, or the object was not in a state that permitted the function to be called. This value is equal to the E_INVALIDARG standard COM return value.

DIERR_NOINTERFACE: The specified interface is not supported by the object. This value is equal to the E_NOINTERFACE standard COM return value.

DIERR_NOTINITIALIZED: The object has not been initialized.

DIERR_OUTOFMEMORY: The DirectInput subsystem couldn't allocate sufficient memory to complete the call. This value is equal to the E_OUTOFMEMORY standard COM return value.

Remarks

Calling this method with pUnkOuter = NULL is equivalent to creating the object by CoCreateInstance (&CLSID_DirectInputDevice, NULL, CLSCTX_INPROC_SERVER, riid, lplpDirectInputDevice) and then initializing it with Initialize.

Calling this method with pUnkOuter != NULL is equivalent to creating the object by CoCreateInstance (&CLSID_DirectInputDevice, punkOuter, CLSCTX_INPROC_SERVER, &IID_IUnknown, lplpDirectInputDevice). The aggregated object must be initialized manually.
原文地址:https://www.cnblogs.com/lancidie/p/1949349.html