原文链接:https://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx

XInput是一个允许应用从Windows平台Xbox 360控制器中接收输入的API。该文档描述XInput和DirectInput关于Xbox 360控制器接口间的不同,并说明如何在同一时间同时支持XInput设备和传统DirectInput设备。
 
注意:传统DirectInput目前不推荐使用,并且在Windows Store里面的应用已经不支持DirectInput。
 
新的标准:XInput
XInput目前可以应用于游戏开发,这个新的输入标准可以应用于Xbox 360、Windows XP SP1及以上版本以及Windows Vista。该APIs在DirectX SDK中包含,并且通过Windows Update可以更新驱动。
 
XInput相较于DirectInput有以下方面的优势:
  • XInput比DirectInput更方便使用并且创建步骤更少
  • Xbox 360和Windows编程使用相同的核心APIs集,并且跨平台编程更方便
  • Xbox 360有一个非常大的用户群
  • XInput设备(也就是指Xbox 360控制器)将在仅使用XInput APIs时具备震动功能
  • 未来发布关于Xbox 360操纵台的控制器(也就是方向盘)将同样可以应用于Windows
 
将DirectInput应用于Xbox 360控制器
Xbox 360可以通过DirectInput进行枚举,并且可以应用DirectInput APIs。然而,某些XInput提供的功能在DirectInput中不存在:
  • 左、右扳柄不作为独立的单一按钮
  • 震动效果不可用
  • 无法查询头戴式设备
在DirectInput中设计左右扳柄处于组合状态,游戏常常假定当没有用户与设备交互时DirectInput设备轴处于中间。然而,Xbox 360控制器设计该位置为最小值,并不是中间,当触发器没有被控制时,老的游戏因此假定用户处于交互状态。
 
解决方案是配置扳柄,设置一个为负向和另一个为正向,所以当没有用户交互时表示DirectInput控制处于中间状态。
 
为了分别测试扳柄的值,此时必须用XInput。
 
同时支持XInput和DirectInput
假如仅仅支持XInput,游戏将不能工作在传统的DirectInput设备上。XInput将不会识别这些设备。
 
如何想让游戏支持传统DirectInput设备,需要同时使用DirectInput和XInput。当枚举DirectInput设备时,所有DirectInput设备将枚举成功。所有的XInput设备将同时显示在XInput和DirectInput设备中,但是他们不应该通过DirectInput处理。你需要决定那些DirectInput设备是传统设备,那些是XInput设备并且从DirectInput设备枚举集里面将他们移除。
 
为实现这个目的,将下面这些代码插入到DirectInput回调函数里面:
#include <wbemidl.h>
#include <oleauto.h>
#include <wmsstd.h> //-----------------------------------------------------------------------------
// Enum each PNP device using WMI and check each device ID to see if it contains
// "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device
// Unfortunately this information can not be found by just using DirectInput
//-----------------------------------------------------------------------------
BOOL IsXInputDevice( const GUID* pGuidProductFromDirectInput )
{
IWbemLocator* pIWbemLocator = NULL;
IEnumWbemClassObject* pEnumDevices = NULL;
IWbemClassObject* pDevices[] = {};
IWbemServices* pIWbemServices = NULL;
BSTR bstrNamespace = NULL;
BSTR bstrDeviceID = NULL;
BSTR bstrClassName = NULL;
DWORD uReturned = ;
bool bIsXinputDevice= false;
UINT iDevice = ;
VARIANT var;
HRESULT hr; // CoInit if needed
hr = CoInitialize(NULL);
bool bCleanupCOM = SUCCEEDED(hr); // Create WMI
hr = CoCreateInstance( __uuidof(WbemLocator),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IWbemLocator),
(LPVOID*) &pIWbemLocator);
if( FAILED(hr) || pIWbemLocator == NULL )
goto LCleanup; bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup;
bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup;
bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup; // Connect to WMI
hr = pIWbemLocator->ConnectServer( bstrNamespace, NULL, NULL, 0L,
0L, NULL, NULL, &pIWbemServices );
if( FAILED(hr) || pIWbemServices == NULL )
goto LCleanup; // Switch security level to IMPERSONATE.
CoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); hr = pIWbemServices->CreateInstanceEnum( bstrClassName, , NULL, &pEnumDevices );
if( FAILED(hr) || pEnumDevices == NULL )
goto LCleanup; // Loop over all devices
for( ;; )
{
// Get 20 at a time
hr = pEnumDevices->Next( , , pDevices, &uReturned );
if( FAILED(hr) )
goto LCleanup;
if( uReturned == )
break; for( iDevice=; iDevice<uReturned; iDevice++ )
{
// For each device, get its device ID
hr = pDevices[iDevice]->Get( bstrDeviceID, 0L, &var, NULL, NULL );
if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL )
{
// Check if the device ID contains "IG_". If it does, then it's an XInput device
// This information can not be found from DirectInput
if( wcsstr( var.bstrVal, L"IG_" ) )
{
// If it does, then get the VID/PID from var.bstrVal
DWORD dwPid = , dwVid = ;
WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" );
if( strVid && swscanf( strVid, L"VID_%4X", &dwVid ) != )
dwVid = ;
WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" );
if( strPid && swscanf( strPid, L"PID_%4X", &dwPid ) != )
dwPid = ; // Compare the VID/PID to the DInput device
DWORD dwVidPid = MAKELONG( dwVid, dwPid );
if( dwVidPid == pGuidProductFromDirectInput->Data1 )
{
bIsXinputDevice = true;
goto LCleanup;
}
}
}
SAFE_RELEASE( pDevices[iDevice] );
}
} LCleanup:
if(bstrNamespace)
SysFreeString(bstrNamespace);
if(bstrDeviceID)
SysFreeString(bstrDeviceID);
if(bstrClassName)
SysFreeString(bstrClassName);
for( iDevice=; iDevice<; iDevice++ )
SAFE_RELEASE( pDevices[iDevice] );
SAFE_RELEASE( pEnumDevices );
SAFE_RELEASE( pIWbemLocator );
SAFE_RELEASE( pIWbemServices ); if( bCleanupCOM )
CoUninitialize(); return bIsXinputDevice;
} //-----------------------------------------------------------------------------
// Name: EnumJoysticksCallback()
// Desc: Called once for each enumerated joystick. If we find one, create a
// device interface on it so we can play with it.
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
VOID* pContext )
{
HRESULT hr; if( IsXInputDevice( &pdidInstance->guidProduct ) )
return DIENUM_CONTINUE; // Device is verified not XInput, so add it to the list of DInput devices return DIENUM_CONTINUE;
}

XInput和DirectInput的更多相关文章

  1. 如何通过XInput技术针对游戏方向盘或者手柄编程

    目前市面上的游戏外设,要么支持传统的DirectInput接口,要么支持最新的XInput技术.今天在这里聊一聊,如何通过XInput技术实现对这类游戏外设相关信息的捕获.关于DirectInput与 ...

  2. 创建DirectInput接口对象说明---(void **)&m_pDI

    读别人代码时遇到的,起初没明白过来这是怎么回事,后来忽然想明白了. if (FAILED(DirectInput8Create(appInstance, DIRECTINPUT_VERSION, II ...

  3. DirectX 9 UI三种设计学习笔记:文章4章Introducing DirectInput+文章5章Wrapping Direct3D

           本文从哈利_创.转载请注明出处.有问题欢迎联系本人!        邮箱:2024958085@qq.com 上一期的地址: DX 9 UI设计学习笔记之二 第4章 Introducin ...

  4. vux的x-input的源码分析

    <template> <div class="vux-x-input weui-cell" :class="{'weui-cell_warn': sho ...

  5. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记7——DirectInput&纹理映射

    第15章 DirectInput接口 DirectInput作为DirectX的组件之一,依然是一些COM对象的集合.DirectInput由IDirectinput8.IDirectInputDev ...

  6. Ubuntu通过xinput禁用及启用联想笔记本的触摸板

    查看设备列表 通过xinput先查看一些都有哪些设备 xinput     #或者 xinput list 显示结果如下 ddd@ddd:~$ xinput list   Virtual core p ...

  7. 如何通过DirectInput技术针对莱仕达雷驰V3II游戏方向盘编程

    三自由度的动感座椅可以让玩游戏人员在玩的过程中随座椅一起晃动,通过应用程序对方向盘动作的抓取来实现体感,动作类型主要分为加速(后仰,对应踩油门).减速(前倾,对应踩刹车 ).左转(向左打方向盘).右转 ...

  8. firefox浏览器中使用vux的x-input报错TypeError: _this3.$refs.input.scrollIntoViewIfNeeded is not a function

    最近做公众号项目,想着统一风格,所以决定使用vux. 在调试时发现,只要鼠标点击x-input输入框,就会报错 TypeError: _this3.$refs.input.scrollIntoView ...

  9. 使用vux的x-input组件中show-clear=“true”清除icon点击失效的问题

    问题场景: 在电脑浏览器点击清除icon正常 在手机浏览器,手机微信,微信开发者工具中点击清除icon失效 查看vux中的x-input组件中的源码发现,清除icon使用了v-show显示与隐藏,对应 ...

随机推荐

  1. Android中的java层的线程暂停和恢复实现

    /**  * 基础线程对象.  *  * @author jevan  * @version (1.0 at 2013-6-17)  * @version (1.1 at 2013-7-2) 增加on ...

  2. .NetCore上传多文件的几种示例

    本章和大家分享的是.NetCore的MVC框架上传文件的示例,主要讲的内容有:form方式提交上传,ajax上传,ajax提交+上传进度效果,Task并行处理+ajax提交+上传进度,相信当你读完文章 ...

  3. 搭建MySQL高可用负载均衡集群

    1.简介 使用MySQL时随着时间的增长,用户量以及数据量的逐渐增加,访问量更是剧增,最终将会使MySQL达到某个瓶颈,那么MySQL的性能将会大大降低.这一结果也不利于软件的推广. 那么如何跨过这个 ...

  4. 实现TOLock过程中的一处多线程bug

    背景 最近在啃<多处理器编程的艺术>,书中的7.6节介绍了时限锁--实现了tryLock方法的队列锁. 书中重点讲解了tryLock的实现,也就是如何实现在等待超时后退出队列,放弃锁请求, ...

  5. H5前端框架推荐合集

    Ionic ionic 吧开发流程都帮你做好了,已经不再是单纯的UI框架,而是开发框架了,非常适合快速开发.基于angular2,丰富的UI组件,大大改进的编程模型, Semantic UI 中文官网 ...

  6. android在myeclipse上创建的项目各种报错

    这几天被android弄得头疼死了.差不多把电脑弄了个遍. 先是离线安装ADT,下载ADT,然后配置,但是因为ADT与MyEclipse冲突.所以直接不要再myeclipse下弄Android的环境了 ...

  7. hdu1540线段树

    https://vjudge.net/contest/66989#problem/I #include<iostream> #include<cstdio> #include& ...

  8. ListView在异步加载动态图片时,往往最后一项或几项被遮盖(IM场景居多)

    如果ListView中得默认图片比较小,新图片加载后,撑大ListView中的对应项,导致最后一项或几项被覆盖. 解决思路: 1.默认图片设定和新图大小一样,换句话说,新图加载后转成和默认图片一样的大 ...

  9. 使用CSS3中的input标签与lable标签组合实现banner图的切换

    在做网页时,我们经常可以碰到banner图的切换.对于那些JS薄弱的同学来说,这就很尴尬了.今天,我来告诉大家如何使用CSS做出banner图切换的效果. 这里,用到了lable标签与input的组合 ...

  10. Spring+SpringMVC+MyBatis+easyUI整合优化篇(十四)谈谈写博客的原因和项目优化

    阶段总结 又到了优化篇的收尾阶段了,这其实是一篇阶段总结性的文章,今天是4月29号,距离第一次发布博客已经两个月零5天,这两个多月的时间,完成了第一个项目ssm-demo的更新,过程中也写了33篇博客 ...