GameInput 设备
每个连接到系统的物理输入设备都由 IGameInputDevice 接口表示。 与读取一样,设备实例是引用计数的单一实例,这意味着可以比较接口指针的相等性。 一个典型应用程序的主要输入代码仅以此形式使用设备实例,在调用其他 API 时作为某种设备标识符(例如,在检索读取时作为筛选器)。
通常,只有当应用程序需要以某种方式直接与特定设备进行交互时,才需要调用 IGameInputDevice 接口方法。 最常见的原因是向设备发送触觉或力回馈命令。 但是,该接口还公开设备属性,并提供对低级别设备 I/O 的访问权限,更高级的代码可能需要此访问权限。
设备属性
需要了解设备特定详细信息的应用程序可以访问设备的 GameInputDeviceInfo 结构。 此结构包含大量关于该设备的信息,但要使用它还有一些事情需要了解。
设备信息可能较大–有时 10 KB 或更大。 出于效率原因,GameInput API 不会复制设备数据,而是暂时授予应用程序直接访问 GameInput 内部存储的数据的权限。 这种方法通过避免缓冲区分配和大量内存传输来支持高性能代码,因为应用程序通常只对一小部分的数据感兴趣。 这也使 GameInputDeviceInfo 结构能够包含指向设备信息数据块中其他区域的嵌套指针,而在这些区域中可以找到各种支持的信息数组,而不会增加不限大小输出和深层复制的复杂性。
设备 ID
在设备信息中可用的一个重要信息部分就是设备的应用程序本地设备 ID。 这是一个特殊的 32 字节值,用来唯一标识设备,即使在重新启动应用程序或重新启动系统后也是如此。 只要将无线设备和有线 USB 设备插回同一 USB 端口,此 ID 就可以在断开连接和重新连接时保持稳定。
应用程序本地设备 ID 最常用于标识应用程序生命周期之外的特定设备。 例如,具有输入映射 UI 的游戏可以使用设备 ID 来确保每次应用启动时用户的输入配置都应用于相同的设备。 这对于支持跨多个设备的复杂映射的应用程序尤其重要,否则这些应用程序可能看起来相同(例如,用于飞行模拟器的一组同质仪表板设备)。
设备枚举
尽管大多数应用程序应该永远不会需要它,但 GameInput 确实支持已连接设备的显式枚举。 这可以通过 IGameInput 接口的 RegisterDeviceCallback 方法来执行。
HRESULT RegisterDeviceCallback(
_In_opt_ IGameInputDevice * device,
_In_ GameInputKind inputKind,
_In_ GameInputDeviceStatus statusFilter,
_In_ GameInputEnumerationKind enumerationKind,
_In_opt_ void * context,
_In_ GameInputDeviceCallback callbackFunc,
_Out_opt_ _Result_zeroonfailure_ GameInputCallbackToken * callbackToken);
此方法处理设备枚举和设备连接/断开连接通知,方法是首先触发每个连接设备的初始系列回调,然后在连接或断开新设备时进行后续回调。 应用程序可以使用 GameInputEnumerationKind 参数来控制该函数阻塞直至所有初始回调均已分派,还是它立即返回并异步分派回调。
有几个筛选器可用于控制在枚举中包括哪些类型的设备,以及哪些设备状态变化将触发回调。 有关详细信息,请参阅 RegisterDeviceCallback。 有关回调的工作原理的一般信息,请参阅GameInput 回调。