DirectX9.0 —— DirectInput翻译本

使用DirectInput:
  DirectInput提供一个访问输入设备所需的接口,通过这个接口,我们能够建立设备,列举系统中的设备,或者检查特殊设备的状态。
  在建立一个DirectInput对象后,必须建立一个设备,创建的DirectInput设备使你能够获得详细而且准确的输入设备访问信息。
  创建完设备之后,你需要访问它们的输入。这个通过进程处理的动作我们叫它“获得设备”。当你获得了一个设备,你将能初始化他,得到它的性能列表,或者读取他的输入信息。
  现在你能访问设备,你就需要在每一帧去读取它的输入。

 

DirectInput对象的创建 DirectInput8Create
 HRESULT WINAPI DirectInput8Create(
 HINSTANCE hinst,  //创建DirectInput对象的应用程序实例句柄
 DWORD dwVersion,  //应用程序所请求的DirectInput版本。
 REFIID riidltf,  //请求页面的标识号,默认IID_IDirectInput8
 LPVOID *ppvOut,  //指向将被创建的DirectInput对象
 LPUNKNOWN punkOuter //此参数一般为NULL
 );

DirectInput设备的 创建 CreateDevice
 HRESULT CreateDevice(
 REFGUID rguid,  //设备的GUID号
 LPDIRECTINPUTDEVICE *lplpDirectInputDevice,//将要创建的设备
 LPUNKNOWN pUnkOuter //控制对象的接口地址,一般为NULL
 );
 
下来就要保证从设备得到的返回数据可靠,有效,所以需要建立一个数据格式。

DirectInput数据格式的设定 SetDataFormat
 HRESULT SetDataFormat (LPCDIDATAFORMAT lpdf);
 里面参数是一个描述设备各种信息的结构体
 typedef struct DIDATAFORMAT {
DWORD dwSize; //结构体的大小
DWORD dwObjSize; // LPDIOBJECTDATAFORMAT的大小
DWORD dwFlags; //指定数据格式的属性
DWORD dwDataSize; //从设备返回的数据包大小
DWORD dwNumObjs; // rgodf数组对象的数量
LPDIOBJECTDATAFORMAT rgodf; // LPDIOBJECTDATAFORMAT结构体地址
} DIDATAFORMAT, *LPDIDATAFORMAT;
 如果你想使用一个不是标准设备的输入设备,你需要创建并且使用你所拥有的DIDATAFORMAT结构。

一般常用的输入设备的DIDATAFORMAT结构可以直接使用预先定义好的宏:
  ¤c_dfDIKeyboard 这是一个表示系统键盘对象的数据格式
  ¤c_dfDIMouse  这个是四键鼠标的数据格式
  ¤c_dfDIMouse2 这个是八键鼠标的数据格式
 如果需要的就是标准,常用的设备,就可以直接找到他的预定义格式使用。
  HRESULT hr;
 hr = DI_Device->SetDataFormat(&c_dfDIKeyboard);
 if FAILED( hr )
 return false;

DirectInput设备协调层的设置 

SetCooperativeLevel
 设备协调层会告诉系统你创建的的输入设备如何跟系统一起工作,你可以设置输入设备是独占的或者非独占的进行访问。
 独占访问的意思是只有你的应用程序可以使用这个特定的设备,其他的应用程序不能分享,在全屏游戏模式下非常有用。
 HRESULT SetCooperativeLevel(
 HWND hwnd,  //请求访问设备的窗口句柄
 DWORD dwFlags //访问方式标志位的设置
 );
 dwFlags常用的有:
¤DISCL_BACKGROUND 应用程序请求后台访问设备,意思是说你能够使用输入设备,甚至是游戏窗口不是当前窗口的时候。
  ¤DISCL_EXCLUSIVE   游戏请求独占输入设备
¤DISCL_FOREGROUND 游戏请求仅当游戏窗口为当前窗口的时候访问设备。
  ¤DISCL_NONEXCLUSIVE 游戏请求非独占输入设备
  ¤DISCL_NOWINKEY 甚至屏蔽所有的WINDOWS键,就是当WINDOWS键按下后,游戏仍然保留焦点。
 ⊙这些标志需要根据实际情况的不同进行组合使用
DI_Device->SetCooperativeLevel( wndHandle,DISCL_FOREGROUND | DISCL_NONEXCLUSIVE );

DirectInput对设备访问的请求

 HRESULT Acquire(VOID);

DirectInput获得输入信息 

GetDeviceState
 在上一步只有一句的重要代码获得了设备,下面就可以进行信息获取了,无论输入设备是键盘,鼠标还是其他所有的,我们获得它们信息的方法是一样的:
 HRESULT GetDeviceState(
 DWORD cbData,  // lpvData内存的大小
 LPVOID lpvData // 接受设备当前状态的结构体地址
 );
 例如:
  char Buffer[256];
  DI_Device->GetDeviceState(sizeof(buffer),(LPVOID)&buffer);

因为我们所说的都是在有标准设备的前提下进行的,但是有些情况,用户没有我们需要的设备,所以DirectInput需要有一个决定到底系统有多少个,什么类型的输入设备。

Enumerating Input Devices(简)
 正象Direct3D能通过在系统中安装的视频卡来列出并且得到它们的性能,DirectInput也能对输入系统做同样的事情。
 通过DirectInput对象使用有效的方法,DirectInput能获得系统有效的输入设备的数量,也包括每个设备的类型,功能。
 DirectInput是通过IDirectInput8::EnumDevices方法来完成这个任务的。
 HRESULT EnumDevices(
DWORD dwDevType,//设备类型
LPDIENUMDEVICESCALLBACK lpCallback, //回调函数
LPVOID pvRef, //向回调函数传递参数,你可以用任意32位值。(NULL)
DWORD dwFlags //标志位
);
dwDevType:这个参数为设备搜寻设置一个过滤器,主要的值有:
∷DI8DEVCLASS_ALL 搜寻所有安装的输入设备
∷DI8DEVCLASS_DEVICE 搜寻所有不属于其他类型的设备
∷DI8DEVCLASS_GAMECTRL 搜寻所有的游戏控制器
∷DI8DEVCLASS_KEYBOARD 搜索所有的键盘
 ∷DI8DEVCLASS_POINTER 搜索所有的
 DI8DEVTYPE_MOUSE&DI8DEVTYPE_SCREENPOINTER类型的设备
dwFlags:让该方法EnumDevices知道列表的范围,例如,如果你想让EnumDevices仅搜索系统安装了的设备,或者有回馈的设备,就需要这里设置说明,相关值如下:
∷DIEDFL_ALLDEVICES 这个是默认值,列出系统所有设备
∷DIEDFL_ATTACHEDONLY 列出当前附属于系统的设备
∷DIEDFL_FORCEFEEDBACK 列出支持回馈的设备
∷DIEDFL_INCLUDEALIASES
∷DIEDFL_INCLUDEHIDDEN 列出系统的隐藏设备
∷DIEDFL_INCLUDEPHANTOMS 
 例子 

HRESULT hr;
hr = DI_Object->EnumDevices( DI8DEVCLASS_GAMECTRL,
 EnumJoysticksCallback,NULL,DIEDFL_ATTACHEDONLY ) ;
If FAILED( hr )
return false;

 
从键盘获得输入信息
 从键盘读取数据简单的原因是键盘是一个缺省设备,键盘需要一个256字节的数组:
 如:

char  buffer[256];
 这个字符数组保存键盘上所有按键的状态。
 下来的任务就是判断按键,简单的方法是做宏:
 #define KEYDOWN(name,key) (name[key] & 0x80)
 直接判断然后分别执行就OK了。

 

从鼠标获得输入信息
 鼠标信息的读取和键盘读取类似。主要不同在于GUID和数据格式的不同。
 存储鼠标状态的结构体为DIMOUSESTATE(四键消息结构)

支持多输入设备
 每个输入设备都要拥有属于自己的DirectInputDevice,所以代码需要支持多个DirectInputDevice。你能做的就是创建一个DirectInputDevice数组或者向量。
 下一步是系统中安装的设备列表。当你存储了每个设备的数据后,你就能调用CreateDevice,你需要用为每个你保存了回调函数的设备调用CreateDevice方法,在你创建了所有的设备后,你就能进行所有你想要信息的访问。
Buffer For Hold Keyboard Data
 DIPROPDWORD Structure
 Syntax :
  typedef struct DIPROPDWORD{
   DIPROPHEADER diph;
   DWORD dwData;
  } DIPROPDWORD, *LPDIPROPDWORD ;
  typedef const DIPROPWORD *LPCDIPROPDWORD ;
 members :
  dwData  设置或获得指定的属性
  diph  一个DIPROPHEADER结构体
    dwSize    sizeof(DIPROPDWORD)
    dwHearderSize  sizeof(DIPROPHEADER)
    dwHow    指定应该怎么解释dwObj成员,
 dwObj         如果dwHow成员是DIPH_DEVICE,则它必为
                0.
 如果dwHow成员是DIPH_BYID,则它必须是
 一个对象的标识,这个对象的属性设置可以设置或者获得。
相关DIPROPDWORD的操作: 
 IDirectInputDevice8::SetProperty  设置定义设备行为的属性,这些属性包括输入缓冲大小和“轴”模式。
 HRESULT SetProperty ( REFGUID rguidProp,
  LPCDIPROPHEADER pdiph);
 RguidProp 指示一个GUID的地址,关于键盘缓冲的预定义为:
 DIPROP_BUFFERSIZE 设置输入缓冲区大小这个设置将应用于整个设备,所以dwHow成员必须设置DIPH_DEVICE 
DIDEVICEOBJECTDATA Structure
 结构包含了设备缓冲区信息。
 结构在IDirectInputDevice8::GetDeviceData和
 IDirectInputDevice8::SendDeviceData方法中用到。
 Syntax :
  typedef stuct DIDEVICEOBJECTDATA{
     DWORD dwOfs;
 DWORD dwData;
 DWORD dwTimeStamp;
 DWORD dwSequence;
 UINT_PTR uAppData;
 } DIDEVICEOBJECTDATA, *LPDIDEVICEOBJECTDATA;
    typedef const DIDEVICEOBJECTDATA *LPCDIDEVICEOBJECTDATA;

你可能感兴趣的:(input)