原文链接: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. 读书笔记 effective c++ Item 44 将与模板参数无关的代码抽离出来

    1. 使用模板可能导致代码膨胀 使用模板是节省时间和避免代码重用的很好的方法.你不需要手动输入20个相同的类名,每个类有15个成员函数,相反,你只需要输入一个类模板,然后让编译器来为你实例化20个特定 ...

  2. XML查询

    XPath是XML的查询语言,其内容相当复杂.可以查阅www.w3.org/TR/xpath. 下面以一个实例简单了解一线XPath的查询方法: public partial class Form1 ...

  3. Entity Framework Code First在Oracle下的伪实现

    为什么要说是伪实现,因为还做不到类似MsSql中那样完全的功能.Oralce中的数据库还是要我们自己手动去创建的.这里,我们舍掉了Model First中的EDMX文件,自己在代码里面写模型与映射关系 ...

  4. linux awk 命令详解

    awk是一个非常棒的数字处理工具.相比于sed常常作用于一整行的处理,awk则比较倾向于将一行分为数个"字段"来处理.运行效率高,而且代码简单,对格式化的文本处理能力超强.先来一个 ...

  5. 使用opencv实现自定义卷积

    对图像进行卷积是图像处理的基本操作,最近在研究图像滤波,经常要用到自定义卷积,所以实现了一下 #include "opencv2/imgproc/imgproc.hpp" #inc ...

  6. 使用JS实现鼠标悬浮切换显示

    实现的是在鼠标悬停在不同链接上,在同一位置切换显示想要显示的内容 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// ...

  7. 关于ajax post请求跨域问题的解决心得

    最近啊,公司有个项目,需要做一个手机端APP的后台管理系统.所以用到了度文本编辑框,经过了好好一番周折,终于弄好了,带到上线的时候发现啊,只能使用ip去访问网页的时候上能穿图片他不会报跨域的问题,而使 ...

  8. 1034. Head of a Gang

    One way that the police finds the head of a gang is to check people's phone calls. If there is a pho ...

  9. linux 线程编程详解

    1.线程的概念: 线程和进程有一定的相似性,通常称为轻量级的进程 同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等.但同一进程中的多个线程都有自身控制流 (它 ...

  10. html5脚本编程

    (1)跨文档消息传递,XDM.指的是来自不同域的页面间传递消息. XDM的核心是postMessage();向另一个地方传递数据,指是包含在当前页面中的iframe元素,由当前页面弹出的窗口. var ...