wordpress笑话站主题,江苏分销网站建设,那个网站可以找人做设计,邢台网站制作公司哪家专业功能全面地封装了XInput的输入,
1. 普通按钮按下, 按住, 弹起状态检查,
2. 摇杆4个方向的按下, 按住, 弹起检查
3. 按键状态变化检测并且记录按下触发时间, 按住保持时间, 方便用来完全自定义的输入功能
4. 多手柄输入合并 CXinputHelper.h
#pragma once
#include win…功能全面地封装了XInput的输入,
1. 普通按钮按下, 按住, 弹起状态检查,
2. 摇杆4个方向的按下, 按住, 弹起检查
3. 按键状态变化检测并且记录按下触发时间, 按住保持时间, 方便用来完全自定义的输入功能
4. 多手柄输入合并 CXinputHelper.h
#pragma once
#include windows.h
#include xinput.h
#include tchar.h
#include thread
#include functional
#include string
#include map
#pragma comment(lib, xinput.lib)#define PI (3.141592653589793f)
#define ANGLE_RANGE (22.5f)#define XINPUT_GAMEPAD_GUIDE (0x00000400)
#define XINPUT_GAMEPAD_SHARE (0x00000800)
#define XINPUT_GAMEPAD_LEFT_TRIGGER (0x00010000)
#define XINPUT_GAMEPAD_RIGHT_TRIGGER (0x00020000)
#define XINPUT_GAMEPAD_LEFT_STICK (0x00040000)
#define XINPUT_GAMEPAD_RIGHT_STICK (0x00080000)#ifdef _UNICODE
using _tstring std::wstring;
#else
using _tstring std::string;
#endif// 手柄按键状态位
typedef union _GAME_PAD_BUTTON_MASK
{DWORD dwButtons; // 标准按钮键值// 按钮比特位struct _Flags{DWORD DpadUp : 1; // 十字键 上DWORD DpadDown : 1; // 十字键 下DWORD DpadLeft : 1; // 十字键 左DWORD DpadRight : 1; // 十字键 右DWORD Start : 1; // 菜单键(开始键)DWORD Back : 1; // 返回键(选择键)DWORD LeftThumb : 1; // 左摇杆键DWORD RightThumb : 1; // 右摇杆键DWORD LeftShoulder : 1; // 左肩键DWORD RightShoulder : 1; // 右肩键DWORD Guide : 1; // 西瓜键(导航键)DWORD Share : 1; // 分享键(假设, 未验证)DWORD A : 1; // ADWORD B : 1; // BDWORD X : 1; // XDWORD Y : 1; // Y// 根据摇杆方向假设的摇杆方向键DWORD LeftStickUp : 1; // 左摇杆 上DWORD LeftStickDown : 1; // 左摇杆 下DWORD LeftStickLeft : 1; // 左摇杆 左DWORD LeftStickRight : 1; // 左摇杆 右DWORD RightStickUp : 1; // 右摇杆 上DWORD RightStickDown : 1; // 右摇杆 下DWORD RightStickLeft : 1; // 右摇杆 左DWORD RightStickRight : 1; // 右摇杆 右DWORD LeftTrigger : 1; // 左扳机DWORD RightTrigger : 1; // 右扳机}Mask;}GAME_PAD_BUTTON_MASK;// 摇杆方向状态位
typedef union _GAME_PAD_BUTTON_STATE
{uint8_t State; // 状态// 按钮比特位struct _Flags{uint8_t Down : 1; // 按下uint8_t Hold : 1; // 按住uint8_t Up : 1; // 弹起}Mask;
}GAME_PAD_BUTTON_STATE;typedef union _GAME_PAD_STICK_DIRECTION_STATE
{uint32_t State; // 状态// 按钮比特位struct _Flags{uint32_t Up : 1; // 摇杆 上uint32_t Down : 1; // 摇杆 下uint32_t Left : 1; // 摇杆 左uint32_t Right : 1; // 摇杆 右}Mask;
}GAME_PAD_STICK_DIRECTION_STATE;// 手柄按键状态位
typedef struct _GAME_PAD_BUTTON_INFO
{uint8_t Value; // 按键值GAME_PAD_BUTTON_STATE Flag; // 按键标志DWORD dwTime; // 触发时间DWORD dwDuration; // 持续时长
}GAME_PAD_BUTTON_INFO;// 摇杆方向
typedef struct _GAME_PAD_STICK_DIRECTION
{GAME_PAD_STICK_DIRECTION_STATE Direction; // 当前方向标志GAME_PAD_BUTTON_INFO Up;GAME_PAD_BUTTON_INFO Down;GAME_PAD_BUTTON_INFO Left;GAME_PAD_BUTTON_INFO Right;
}GAME_PAD_STICK_DIRECTION;// 输入事件状态
typedef struct _INPUT_EVENT_STATE
{DWORD dwIndex; // 手柄索引DWORD dwButtonMask; // 按钮标识位掩码XINPUT_STATE xinputState; // 手柄输入DWORD dwTime; // 触发时间DWORD dwDuration; // 触发时长GAME_PAD_BUTTON_STATE curButtonFlag; // 触发状态(按下, 按住, 弹起)GAME_PAD_STICK_DIRECTION curLeftStickDirection; // 左摇杆方向触发状态GAME_PAD_STICK_DIRECTION curRightStickDirection; // 右摇杆方向触发状态GAME_PAD_STICK_DIRECTION lastLeftStickDirection; // 上次左摇杆方向触发状态GAME_PAD_STICK_DIRECTION lastRightStickDirection; // 上次右摇杆方向触发状态GAME_PAD_STICK_DIRECTION stickDirection; // 摇杆方向触发状态GAME_PAD_BUTTON_MASK buttonBitMask; // 按键位状态DWORD dwButtons; // 触发按键SHORT sThumbX; // 当前摇杆X值SHORT sThumbY; // 当前摇杆Y值BYTE bTrigger; // 扳机数据BYTE fRight;_INPUT_EVENT_STATE(){memset(this, 0, sizeof(*this));}}INPUT_EVENT_STATE;// 输入事件变化回调
class CXInputHelper;
typedef bool (CXInputHelper::*pInputEventFn)(const INPUT_EVENT_STATE state);typedef struct _INPUT_EVENT_INFO
{pInputEventFn eventCb; // 输入事件变化回调函数INPUT_EVENT_STATE eventState; // 输入事件变化状态_INPUT_EVENT_INFO(pInputEventFn cb):eventCb(cb){}}INPUT_EVENT_INFO;class CXInputHelper
{
public:CXInputHelper();virtual ~CXInputHelper();bool Initialize();void Uninitialize();// 打印状态信息virtual void PrintState(const INPUT_EVENT_STATE state);// 打印void PrintText(LPCTSTR pFormat, ...);void IgnoreLeftThumbEmpty(bool bEnable true // 允许空数据触发回调);void IgnoreRightThumbEmpty(bool bEnable true // 允许空数据触发回调);void SetInterval(int millisecond 10 // 数据采集间隔时间(毫秒));void SetThumbThreshold(int nLeftThumbThreshold 4096, // 左摇杆触发阈值(死区)int nRightThumbThreshold 4096 // 右摇杆触发阈值(死区));// 设置检测每个控制器输入数据回调void SetRawStateCallback(std::functionvoid(DWORD dwIndex, // 控制器索引(有效值: 0 - 3)const XINPUT_GAMEPAD xGamepad // 控制器数据) cb);// 设置合并多个控制器输入数据回调void SetMergeStateCallback(std::functionvoid(const XINPUT_GAMEPAD xGamepad // 控制器数据) cb);// 设置检测每个控制器输入状态变化回调(发生按钮按下, 释放, 按住时触发)void SetRawChangeCallback(std::functionvoid(const INPUT_EVENT_STATE state // 回调信息) cb);// 设置合并多个控制器输入状态变化回调(发生按钮按下, 释放, 按住时触发)void SetMergeChangeCallback(std::functionvoid(const INPUT_EVENT_STATE state // 回调信息) cb);// 输入变化virtual bool OnChangeDpadUp(const INPUT_EVENT_STATE state);virtual bool OnChangeDpadDown(const INPUT_EVENT_STATE state);virtual bool OnChangeDpadLeft(const INPUT_EVENT_STATE state);virtual bool OnChangeDpadRight(const INPUT_EVENT_STATE state);virtual bool OnChangeBack(const INPUT_EVENT_STATE state);virtual bool OnChangeStart(const INPUT_EVENT_STATE state);virtual bool OnChangeGuide(const INPUT_EVENT_STATE state);virtual bool OnChangeShare(const INPUT_EVENT_STATE state);virtual bool OnChangeA(const INPUT_EVENT_STATE state);virtual bool OnChangeB(const INPUT_EVENT_STATE state);virtual bool OnChangeX(const INPUT_EVENT_STATE state);virtual bool OnChangeY(const INPUT_EVENT_STATE state);virtual bool OnChangeLeftShoulder(const INPUT_EVENT_STATE state);virtual bool OnChangeRightShoulder(const INPUT_EVENT_STATE state);virtual bool OnChangeLeftTrigger(const INPUT_EVENT_STATE state);virtual bool OnChangeRightTrigger(const INPUT_EVENT_STATE state);virtual bool OnChangeLeftStick(const INPUT_EVENT_STATE state);virtual bool OnChangeRightStick(const INPUT_EVENT_STATE state);virtual bool OnChangeLeftThumb(const INPUT_EVENT_STATE state);virtual bool OnChangeRightThumb(const INPUT_EVENT_STATE state);// 合并输入变化virtual bool OnMergeChangeDpadUp(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeDpadDown(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeDpadLeft(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeDpadRight(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeBack(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeStart(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeGuide(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeShare(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeA(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeB(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeX(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeY(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeLeftShoulder(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeRightShoulder(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeLeftTrigger(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeRightTrigger(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeLeftStick(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeRightStick(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeLeftThumb(const INPUT_EVENT_STATE state);virtual bool OnMergeChangeRightThumb(const INPUT_EVENT_STATE state);private:// 任务循环void _GamepadLoop();// 睡眠间隔void _Sleep(int millisecond);// 更新扳机状态void _UpdateTriggerState(INPUT_EVENT_STATE state, BYTE bCurTrigger, BYTE bLastTrigger);// 更新摇杆按钮void _UpdateStickButton(GAME_PAD_BUTTON_INFO curStick, GAME_PAD_BUTTON_INFO lastStick);// 更新摇杆方向状态void _UpdateStickDirection(INPUT_EVENT_STATE state, GAME_PAD_STICK_DIRECTION curStick, GAME_PAD_STICK_DIRECTION lastStick, SHORT sCurX, SHORT sCurY);// 按钮状态变化处理void _UpateButtonState(INPUT_EVENT_STATE state, const XINPUT_GAMEPAD cur, const XINPUT_GAMEPAD last, DWORD wButton);// 状态变化输入处理void _InputChangeProcess(DWORD dwIndex);// 混合输入处理void _InputMergeProcess();// 混合输入变化处理void _InputMergeChangeProcess();private:std::functionvoid(DWORD dwIndex, const XINPUT_GAMEPAD xGamepad) m_cbRawState; // 检测每个控制器输入数据回调std::functionvoid(const XINPUT_GAMEPAD xGamepad) m_cbMergeState; // 合并多个控制器输入数据回调std::functionvoid(const INPUT_EVENT_STATE state) m_cbRawChange; // 检测每个控制器输入状态变化回调(发生按钮按下, 释放, 按住时触发)std::functionvoid(const INPUT_EVENT_STATE state) m_cbMergeChange; // 合并多个控制器输入状态变化回调(发生按钮按下, 释放, 按住时触发)std::mapDWORD, INPUT_EVENT_INFO m_buttonEvents[XUSER_MAX_COUNT];std::mapDWORD, INPUT_EVENT_INFO m_mergeEvents;std::thread m_gamepadTask; // 控制器状态检测任务线程int m_LeftThumbThreshold; // 左摇杆触发阈值int m_RightThumbThreshold; // 右摇杆触发阈值int m_DataInterval; // 采集间隔时间bool m_bIgnoreLeftThumbEmpty; // 左摇杆 X,Y 轴数据均为 0 时也触发回调bool m_bIgnoreRightThumbEmpty; // 右摇杆 X,Y 轴数据均为 0 时也触发回调bool m_fQuit; // 退出标志public:XINPUT_STATE m_CurXInputState[XUSER_MAX_COUNT]; // 当前控制器输入状态XINPUT_STATE m_LastXInputState[XUSER_MAX_COUNT]; // 上次控制器输入状态XINPUT_STATE m_CurXInputMerge; // 当前全部控制器混合输入状态XINPUT_STATE m_LastXInputMerge; // 当前全部控制器混合输入状态GAME_PAD_BUTTON_MASK m_CurButtonState[XUSER_MAX_COUNT];GAME_PAD_BUTTON_MASK m_CurButtonMerge;
};CXinputHelper.cpp
#include CXInputHelper.h
#include stdint.h
#include Winerror.h
#include map
#include math.h
//#pragma comment(lib, Winmm.lib)void CXInputHelper::_Sleep(int millisecond)
{//timeBeginPeriod(1);do{const int span 1;if (millisecond span){std::this_thread::sleep_for(std::chrono::milliseconds(millisecond));return;}clock_t tmBegin clock();while (true){if (clock() - tmBegin millisecond){break;}if (m_fQuit){break;}std::this_thread::sleep_for(std::chrono::milliseconds(span));}} while (false);//timeEndPeriod(1);
}void CXInputHelper::PrintText(LPCTSTR pFormat, ...)
{size_t nCchCount MAX_PATH;_tstring strResult(nCchCount, 0);va_list args;va_start(args, pFormat);do{//格式化输出字符串int nSize _vsntprintf_s(strResult[0], nCchCount, _TRUNCATE, pFormat, args);if (-1 ! nSize){HANDLE console GetStdHandle(STD_OUTPUT_HANDLE);::WriteConsole(console, strResult.c_str(), nSize, NULL, NULL);break;}//缓冲大小超限终止if (nCchCount INT32_MAX){break;}//重新分配缓冲nCchCount * 2;strResult.resize(nCchCount);} while (true);va_end(args);
}CXInputHelper::CXInputHelper():m_bIgnoreLeftThumbEmpty(true),m_bIgnoreRightThumbEmpty(true),m_fQuit(false),m_LeftThumbThreshold(0),m_RightThumbThreshold(0),m_DataInterval(10)
{memset(m_CurXInputState, 0, sizeof(m_CurXInputState));memset(m_LastXInputState, 0, sizeof(m_LastXInputState));memset(m_CurXInputMerge, 0, sizeof(m_CurXInputMerge));memset(m_LastXInputMerge, 0, sizeof(m_LastXInputMerge));memset(m_CurButtonState, 0, sizeof(m_CurButtonState));memset(m_CurButtonMerge, 0, sizeof(m_CurButtonMerge));}CXInputHelper::~CXInputHelper()
{Uninitialize();
}bool CXInputHelper::Initialize()
{Uninitialize();m_gamepadTask std::move(std::thread([this]() {_GamepadLoop();}));return true;
}void CXInputHelper::Uninitialize()
{if (m_gamepadTask.joinable()){m_fQuit true;m_gamepadTask.join();}m_fQuit false;
}void CXInputHelper::IgnoreLeftThumbEmpty(bool bEnable
)
{m_bIgnoreLeftThumbEmpty bEnable;
}void CXInputHelper::IgnoreRightThumbEmpty(bool bEnable
)
{m_bIgnoreRightThumbEmpty bEnable;
}void CXInputHelper::SetInterval(int millisecond
)
{m_DataInterval millisecond;
}void CXInputHelper::SetThumbThreshold(int nLeftThumbThreshold/* 4096*/,int nRightThumbThreshold/* 4096*/
)
{m_LeftThumbThreshold nLeftThumbThreshold;m_RightThumbThreshold nRightThumbThreshold;
}void CXInputHelper::SetRawStateCallback(std::functionvoid(DWORD dwIndex,const XINPUT_GAMEPAD xGamepad) cb
)
{m_cbRawState cb;
}void CXInputHelper::SetMergeStateCallback(std::functionvoid(const XINPUT_GAMEPAD xGamepad) cb
)
{m_cbMergeState cb;
}void CXInputHelper::SetRawChangeCallback(std::functionvoid(const INPUT_EVENT_STATE state) cb
)
{m_cbRawChange cb;
}void CXInputHelper::SetMergeChangeCallback(std::functionvoid(const INPUT_EVENT_STATE state) cb
)
{m_cbMergeChange cb;
}// 输入变化
bool CXInputHelper::OnChangeDpadUp(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeDpadDown(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeDpadLeft(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeDpadRight(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeBack(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeStart(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeGuide(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeShare(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeA(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeB(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeX(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeY(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeLeftShoulder(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeRightShoulder(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeLeftTrigger(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeRightTrigger(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeLeftStick(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeRightStick(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeLeftThumb(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnChangeRightThumb(const INPUT_EVENT_STATE state)
{return true;
}// 合并输入变化
bool CXInputHelper::OnMergeChangeDpadUp(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeDpadDown(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeDpadLeft(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeDpadRight(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeBack(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeStart(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeGuide(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeShare(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeA(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeB(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeX(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeY(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeLeftShoulder(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeRightShoulder(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeLeftTrigger(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeRightTrigger(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeLeftStick(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeRightStick(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeLeftThumb(const INPUT_EVENT_STATE state)
{return true;
}bool CXInputHelper::OnMergeChangeRightThumb(const INPUT_EVENT_STATE state)
{return true;
}void CXInputHelper::PrintState(const INPUT_EVENT_STATE state)
{PrintText(_T(OnRightThumb Index: %d bRight: %d Trigger: %3d %6d,%6d Button: %04X Press: %d Release: %d Holding: %d Time:%08d, Duration: %08d\r\n),state.dwIndex, state.fRight, state.bTrigger, state.sThumbX, state.sThumbY, state.dwButtons, state.curButtonFlag.Mask.Down, state.curButtonFlag.Mask.Up, state.curButtonFlag.Mask.Hold,state.dwTime,state.dwDuration);
}void CXInputHelper::_GamepadLoop()
{m_buttonEvents[0] {{XINPUT_GAMEPAD_A, INPUT_EVENT_INFO(CXInputHelper::OnChangeA)},{XINPUT_GAMEPAD_B, INPUT_EVENT_INFO(CXInputHelper::OnChangeB)},{XINPUT_GAMEPAD_X, INPUT_EVENT_INFO(CXInputHelper::OnChangeX)},{XINPUT_GAMEPAD_Y, INPUT_EVENT_INFO(CXInputHelper::OnChangeY)},{XINPUT_GAMEPAD_BACK, INPUT_EVENT_INFO(CXInputHelper::OnChangeBack)},{XINPUT_GAMEPAD_START, INPUT_EVENT_INFO(CXInputHelper::OnChangeStart)},{XINPUT_GAMEPAD_GUIDE, INPUT_EVENT_INFO(CXInputHelper::OnChangeGuide)},{XINPUT_GAMEPAD_SHARE, INPUT_EVENT_INFO(CXInputHelper::OnChangeShare)},{XINPUT_GAMEPAD_DPAD_UP, INPUT_EVENT_INFO(CXInputHelper::OnChangeDpadUp)},{XINPUT_GAMEPAD_DPAD_DOWN, INPUT_EVENT_INFO(CXInputHelper::OnChangeDpadDown)},{XINPUT_GAMEPAD_DPAD_LEFT, INPUT_EVENT_INFO(CXInputHelper::OnChangeDpadLeft)},{XINPUT_GAMEPAD_DPAD_RIGHT, INPUT_EVENT_INFO(CXInputHelper::OnChangeDpadRight)},{XINPUT_GAMEPAD_LEFT_SHOULDER, INPUT_EVENT_INFO(CXInputHelper::OnChangeLeftShoulder)},{XINPUT_GAMEPAD_RIGHT_SHOULDER, INPUT_EVENT_INFO(CXInputHelper::OnChangeRightShoulder)},{XINPUT_GAMEPAD_LEFT_THUMB, INPUT_EVENT_INFO(CXInputHelper::OnChangeLeftThumb)},{XINPUT_GAMEPAD_RIGHT_THUMB, INPUT_EVENT_INFO(CXInputHelper::OnChangeRightThumb)},{XINPUT_GAMEPAD_LEFT_TRIGGER, INPUT_EVENT_INFO(CXInputHelper::OnChangeLeftTrigger)},{XINPUT_GAMEPAD_RIGHT_TRIGGER, INPUT_EVENT_INFO(CXInputHelper::OnChangeRightTrigger)},{XINPUT_GAMEPAD_LEFT_STICK, INPUT_EVENT_INFO(CXInputHelper::OnChangeLeftStick)},{XINPUT_GAMEPAD_RIGHT_STICK, INPUT_EVENT_INFO(CXInputHelper::OnChangeRightStick)}};m_buttonEvents[1] m_buttonEvents[0];m_buttonEvents[2] m_buttonEvents[0];m_buttonEvents[3] m_buttonEvents[0];m_mergeEvents {{XINPUT_GAMEPAD_A, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeA)},{XINPUT_GAMEPAD_B, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeB)},{XINPUT_GAMEPAD_X, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeX)},{XINPUT_GAMEPAD_Y, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeY)},{XINPUT_GAMEPAD_BACK, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeBack)},{XINPUT_GAMEPAD_START, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeStart)},{XINPUT_GAMEPAD_GUIDE, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeGuide)},{XINPUT_GAMEPAD_SHARE, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeShare)},{XINPUT_GAMEPAD_DPAD_UP, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeDpadUp)},{XINPUT_GAMEPAD_DPAD_DOWN, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeDpadDown)},{XINPUT_GAMEPAD_DPAD_LEFT, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeDpadLeft)},{XINPUT_GAMEPAD_DPAD_RIGHT, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeDpadRight)},{XINPUT_GAMEPAD_LEFT_SHOULDER, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeLeftShoulder)},{XINPUT_GAMEPAD_RIGHT_SHOULDER, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeRightShoulder)},{XINPUT_GAMEPAD_LEFT_THUMB, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeLeftThumb)},{XINPUT_GAMEPAD_RIGHT_THUMB, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeRightThumb)},{XINPUT_GAMEPAD_LEFT_TRIGGER, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeLeftTrigger)},{XINPUT_GAMEPAD_RIGHT_TRIGGER, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeRightTrigger)},{XINPUT_GAMEPAD_LEFT_STICK, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeLeftStick)},{XINPUT_GAMEPAD_RIGHT_STICK, INPUT_EVENT_INFO(CXInputHelper::OnMergeChangeRightStick)}};// 加载 控制器状态检测 函数HMODULE hModule LoadLibrary(_T(XInput1_4.dll));if (NULL hModule) hModule LoadLibrary(_T(xinput1_3.dll));if (NULL hModule) return;typedef int(__stdcall* _XInputGetStateEx)(DWORD dwUserIndex, XINPUT_STATE* pState);_XInputGetStateEx XInputGetStateEx (_XInputGetStateEx)::GetProcAddress(hModule, (LPCSTR)100);if (nullptr XInputGetStateEx){XInputGetStateEx (_XInputGetStateEx)::GetProcAddress(hModule, XInputGetState);}clock_t tmCount ::clock();while (!m_fQuit XInputGetStateEx){// 遍历控制器输入for (DWORD i 0; i XUSER_MAX_COUNT; i){XINPUT_STATE xTmpState { 0 };DWORD dwResult XInputGetStateEx(i, xTmpState);// 摇杆触发值限定if (abs(xTmpState.Gamepad.sThumbLX) m_LeftThumbThreshold) xTmpState.Gamepad.sThumbLX 0;if (abs(xTmpState.Gamepad.sThumbLY) m_LeftThumbThreshold) xTmpState.Gamepad.sThumbLY 0;if (abs(xTmpState.Gamepad.sThumbRX) m_RightThumbThreshold) xTmpState.Gamepad.sThumbRX 0;if (abs(xTmpState.Gamepad.sThumbRY) m_RightThumbThreshold) xTmpState.Gamepad.sThumbRY 0;m_CurXInputState[i] xTmpState;// 原始数据回调if (m_cbRawState){m_cbRawState(i, xTmpState.Gamepad);}// 未连接控制器if (ERROR_DEVICE_NOT_CONNECTED dwResult){m_LastXInputState[i] m_CurXInputState[i];continue;}// 单控制器输入变化处理_InputChangeProcess(i);}// 混合输入处理_InputMergeProcess();// 混合输入变化处理_InputMergeChangeProcess();// 输入轮询间隔while (clock() - tmCount m_DataInterval){_Sleep(1);}tmCount clock();}if (hModule){::FreeLibrary(hModule);}
}void CXInputHelper::_UpdateTriggerState(INPUT_EVENT_STATE state, BYTE bCurTrigger, BYTE bLastTrigger)
{clock_t curTime ::clock();if (0 bLastTrigger bCurTrigger){state.curButtonFlag.Mask.Down true;state.dwTime curTime;state.dwDuration 0;}if (bLastTrigger 0 bCurTrigger){state.curButtonFlag.Mask.Up true;state.dwDuration curTime - state.dwTime;}if (bLastTrigger bCurTrigger){state.curButtonFlag.Mask.Hold true;state.dwDuration curTime - state.dwTime;}
}void CXInputHelper::_UpdateStickButton(GAME_PAD_BUTTON_INFO curStick, GAME_PAD_BUTTON_INFO lastStick)
{clock_t curTime ::clock();curStick.Flag.Mask.Down false;curStick.Flag.Mask.Up false;curStick.Flag.Mask.Hold false;// 按下if (curStick.Value !lastStick.Value){curStick.Flag.Mask.Down true;curStick.dwTime curTime;curStick.dwDuration 0;}// 弹起if (!curStick.Value lastStick.Value){curStick.Flag.Mask.Up true;curStick.dwDuration curTime - curStick.dwTime;}// 按住if (curStick.Value lastStick.Value){curStick.Flag.Mask.Hold true;curStick.dwDuration curTime - curStick.dwTime;}// 无if (!curStick.Value !lastStick.Value){curStick.dwTime 0;curStick.dwDuration 0;}
}void CXInputHelper::_UpdateStickDirection(INPUT_EVENT_STATE state, GAME_PAD_STICK_DIRECTION curStick, GAME_PAD_STICK_DIRECTION lastStick, SHORT sCurX, SHORT sCurY)
{clock_t curTime ::clock();curStick.Direction.State 0;curStick.Up.Value 0;curStick.Down.Value 0;curStick.Left.Value 0;curStick.Right.Value 0;// 获取角度double fCurAngle atan2(sCurY, sCurX) * 180.0f / PI;// 上if (sCurY m_LeftThumbThreshold){if (fCurAngle (90.0f - ANGLE_RANGE) fCurAngle (90.0f ANGLE_RANGE)){curStick.Direction.Mask.Up 1;curStick.Up.Value 1;}}// 下if (sCurY -m_LeftThumbThreshold){if (fCurAngle -(90.0f ANGLE_RANGE) fCurAngle -(90.0f - ANGLE_RANGE)){curStick.Direction.Mask.Down 1;curStick.Down.Value 1;}}// 左if (sCurX -m_LeftThumbThreshold){if (fCurAngle (180.0f - ANGLE_RANGE) || fCurAngle -(180.0f - ANGLE_RANGE)){curStick.Left.Value 1;curStick.Direction.Mask.Left 1;}}// 右if (sCurX m_LeftThumbThreshold){if (fCurAngle -ANGLE_RANGE fCurAngle ANGLE_RANGE){curStick.Direction.Mask.Right 1;curStick.Right.Value 1;}}// 右上if (sCurX m_LeftThumbThreshold sCurY m_LeftThumbThreshold){if (fCurAngle (45.0f - ANGLE_RANGE) fCurAngle (45.0f ANGLE_RANGE)){curStick.Direction.Mask.Right 1;curStick.Direction.Mask.Up 1;curStick.Right.Value 1;curStick.Up.Value 1;}}// 左上if (sCurX -m_LeftThumbThreshold sCurY m_LeftThumbThreshold){if (fCurAngle (135.0f - ANGLE_RANGE) fCurAngle (135.0f ANGLE_RANGE)){curStick.Direction.Mask.Left 1;curStick.Direction.Mask.Up 1;curStick.Left.Value 1;curStick.Up.Value 1;}}// 左下if (sCurY -m_LeftThumbThreshold sCurX -m_LeftThumbThreshold){if (fCurAngle -(135.0f ANGLE_RANGE) fCurAngle -(135.0f - ANGLE_RANGE)){curStick.Direction.Mask.Left 1;curStick.Direction.Mask.Down 1;curStick.Left.Value 1;curStick.Down.Value 1;}}// 右下if (sCurY -m_LeftThumbThreshold sCurX m_LeftThumbThreshold){if (fCurAngle -(45.0f ANGLE_RANGE) fCurAngle -(45.0f - ANGLE_RANGE)){curStick.Direction.Mask.Right 1;curStick.Direction.Mask.Down 1;curStick.Right.Value 1;curStick.Down.Value 1;}}// 按下if (!lastStick.Direction.State curStick.Direction.State){state.curButtonFlag.Mask.Down true;state.dwTime curTime;state.dwDuration 0;}// 弹起if (lastStick.Direction.State !curStick.Direction.State){state.curButtonFlag.Mask.Up true;state.dwDuration curTime - state.dwTime;}// 按住if (lastStick.Direction.State curStick.Direction.State){state.curButtonFlag.Mask.Hold true;state.dwDuration curTime - state.dwTime;}// 状态转换_UpdateStickButton(curStick.Up, lastStick.Up);_UpdateStickButton(curStick.Down, lastStick.Down);_UpdateStickButton(curStick.Left, lastStick.Left);_UpdateStickButton(curStick.Right, lastStick.Right);
}void CXInputHelper::_UpateButtonState(INPUT_EVENT_STATE state, const XINPUT_GAMEPAD cur, const XINPUT_GAMEPAD last, DWORD wButton) {state.curButtonFlag.Mask.Down false;state.curButtonFlag.Mask.Up false;state.curButtonFlag.Mask.Hold false;// 左扳机if (XINPUT_GAMEPAD_LEFT_TRIGGER wButton){_UpdateTriggerState(state, cur.bLeftTrigger, last.bLeftTrigger);}// 右扳机else if (XINPUT_GAMEPAD_RIGHT_TRIGGER wButton){_UpdateTriggerState(state, cur.bRightTrigger, last.bRightTrigger);}// 左摇杆else if (XINPUT_GAMEPAD_LEFT_STICK wButton){_UpdateStickDirection(state, state.curLeftStickDirection, state.lastLeftStickDirection, cur.sThumbLX, cur.sThumbLY);state.buttonBitMask.Mask.LeftStickUp state.curLeftStickDirection.Up.Value;state.buttonBitMask.Mask.LeftStickDown state.curLeftStickDirection.Down.Value;state.buttonBitMask.Mask.LeftStickLeft state.curLeftStickDirection.Left.Value;state.buttonBitMask.Mask.LeftStickRight state.curLeftStickDirection.Right.Value;state.lastLeftStickDirection state.curLeftStickDirection;}// 右摇杆else if (XINPUT_GAMEPAD_RIGHT_STICK wButton){_UpdateStickDirection(state, state.curRightStickDirection, state.lastRightStickDirection, cur.sThumbRX, cur.sThumbRY);state.buttonBitMask.Mask.RightStickUp state.curRightStickDirection.Up.Value;state.buttonBitMask.Mask.RightStickDown state.curRightStickDirection.Down.Value;state.buttonBitMask.Mask.RightStickLeft state.curRightStickDirection.Left.Value;state.buttonBitMask.Mask.RightStickRight state.curRightStickDirection.Right.Value;state.lastRightStickDirection state.curRightStickDirection;}else{clock_t curTime ::clock();// 按下if ((0 (last.wButtons wButton)) (cur.wButtons wButton)){state.curButtonFlag.Mask.Down true;state.dwTime curTime;state.dwDuration 0;}// 弹起if ((last.wButtons wButton) (0 (cur.wButtons wButton))){state.curButtonFlag.Mask.Up true;state.dwDuration curTime - state.dwTime;}// 按住if ((last.wButtons wButton) (cur.wButtons wButton)){state.curButtonFlag.Mask.Hold true;state.dwDuration curTime - state.dwTime;}}
}void CXInputHelper::_InputChangeProcess(DWORD dwIndex)
{// 状态处理for (auto item : m_buttonEvents[dwIndex]){INPUT_EVENT_INFO eventInfo item.second;// 按钮状态变化处理_UpateButtonState(eventInfo.eventState, m_CurXInputState[dwIndex].Gamepad, m_LastXInputState[dwIndex].Gamepad, item.first);}// 得到全部输入状态m_CurButtonState[dwIndex].dwButtons 0;for (auto item : m_buttonEvents[dwIndex]){INPUT_EVENT_INFO eventInfo item.second;if (XINPUT_GAMEPAD_LEFT_TRIGGER item.first){m_CurButtonState[dwIndex].Mask.LeftTrigger eventInfo.eventState.curButtonFlag.Mask.Down || eventInfo.eventState.curButtonFlag.Mask.Hold;}else if (XINPUT_GAMEPAD_RIGHT_TRIGGER item.first){eventInfo.eventState.fRight true;m_CurButtonState[dwIndex].Mask.RightTrigger eventInfo.eventState.curButtonFlag.Mask.Down || eventInfo.eventState.curButtonFlag.Mask.Hold;}else if (XINPUT_GAMEPAD_LEFT_STICK item.first){m_CurButtonState[dwIndex].Mask.LeftStickUp eventInfo.eventState.buttonBitMask.Mask.LeftStickUp;m_CurButtonState[dwIndex].Mask.LeftStickDown eventInfo.eventState.buttonBitMask.Mask.LeftStickDown;m_CurButtonState[dwIndex].Mask.LeftStickLeft eventInfo.eventState.buttonBitMask.Mask.LeftStickLeft;m_CurButtonState[dwIndex].Mask.LeftStickRight eventInfo.eventState.buttonBitMask.Mask.LeftStickRight;}else if (XINPUT_GAMEPAD_RIGHT_STICK item.first){eventInfo.eventState.fRight true;m_CurButtonState[dwIndex].Mask.RightStickUp eventInfo.eventState.buttonBitMask.Mask.RightStickUp;m_CurButtonState[dwIndex].Mask.RightStickDown eventInfo.eventState.buttonBitMask.Mask.RightStickDown;m_CurButtonState[dwIndex].Mask.RightStickLeft eventInfo.eventState.buttonBitMask.Mask.RightStickLeft;m_CurButtonState[dwIndex].Mask.RightStickRight eventInfo.eventState.buttonBitMask.Mask.RightStickRight;}else{m_CurButtonState[dwIndex].dwButtons | (eventInfo.eventState.curButtonFlag.Mask.Down || eventInfo.eventState.curButtonFlag.Mask.Hold) ? item.first : 0;}}// 回调处理for (auto item : m_buttonEvents[dwIndex]){INPUT_EVENT_INFO eventInfo item.second;eventInfo.eventState.dwButtonMask item.first;eventInfo.eventState.dwIndex dwIndex;eventInfo.eventState.buttonBitMask.dwButtons m_CurButtonState[dwIndex].dwButtons;eventInfo.eventState.dwButtons m_CurButtonState[dwIndex].dwButtons;if (eventInfo.eventState.curButtonFlag.State){eventInfo.eventState.xinputState m_CurXInputState[dwIndex];if (XINPUT_GAMEPAD_LEFT_TRIGGER item.first){eventInfo.eventState.bTrigger m_CurXInputState[dwIndex].Gamepad.bLeftTrigger;}if (XINPUT_GAMEPAD_RIGHT_TRIGGER item.first){eventInfo.eventState.fRight true;eventInfo.eventState.bTrigger m_CurXInputState[dwIndex].Gamepad.bRightTrigger;}if (XINPUT_GAMEPAD_LEFT_STICK item.first){eventInfo.eventState.sThumbX m_CurXInputState[dwIndex].Gamepad.sThumbLX;eventInfo.eventState.sThumbY m_CurXInputState[dwIndex].Gamepad.sThumbLY;eventInfo.eventState.stickDirection eventInfo.eventState.curLeftStickDirection;}if (XINPUT_GAMEPAD_RIGHT_STICK item.first){eventInfo.eventState.fRight true;eventInfo.eventState.sThumbX m_CurXInputState[dwIndex].Gamepad.sThumbRX;eventInfo.eventState.sThumbY m_CurXInputState[dwIndex].Gamepad.sThumbRY;eventInfo.eventState.stickDirection eventInfo.eventState.curRightStickDirection;}(this-*(eventInfo.eventCb))(eventInfo.eventState);if (m_cbRawChange){m_cbRawChange(eventInfo.eventState);}}}m_LastXInputState[dwIndex] m_CurXInputState[dwIndex];
}void CXInputHelper::_InputMergeProcess()
{LONG nThumbLX 0;LONG nThumbLY 0;LONG nThumbRX 0;LONG nThumbRY 0;LONG nLeftTrigger 0;LONG nRightTrigger 0;// 混合输入按钮状态m_CurXInputMerge.Gamepad.wButtons 0;for (DWORD i 0; i XUSER_MAX_COUNT; i){m_CurXInputMerge.Gamepad.wButtons | m_CurXInputState[i].Gamepad.wButtons;nThumbLX m_CurXInputState[i].Gamepad.sThumbLX;nThumbLY m_CurXInputState[i].Gamepad.sThumbLY;nThumbRX m_CurXInputState[i].Gamepad.sThumbRX;nThumbRY m_CurXInputState[i].Gamepad.sThumbRY;nLeftTrigger m_CurXInputState[i].Gamepad.bLeftTrigger;nRightTrigger m_CurXInputState[i].Gamepad.bRightTrigger;}if (nLeftTrigger UINT8_MAX) nLeftTrigger UINT8_MAX;if (nRightTrigger UINT8_MAX) nRightTrigger UINT8_MAX;if (nThumbLX INT16_MIN) nThumbLX INT16_MIN;if (nThumbLY INT16_MIN) nThumbLY INT16_MIN;if (nThumbRX INT16_MIN) nThumbRX INT16_MIN;if (nThumbRY INT16_MIN) nThumbRY INT16_MIN;if (nThumbLX INT16_MAX) nThumbLX INT16_MAX;if (nThumbLY INT16_MAX) nThumbLY INT16_MAX;if (nThumbRX INT16_MAX) nThumbRX INT16_MAX;if (nThumbRY INT16_MAX) nThumbRY INT16_MAX;m_CurXInputMerge.Gamepad.bLeftTrigger nLeftTrigger;m_CurXInputMerge.Gamepad.bRightTrigger nRightTrigger;m_CurXInputMerge.Gamepad.sThumbLX nThumbLX;m_CurXInputMerge.Gamepad.sThumbLY nThumbLY;m_CurXInputMerge.Gamepad.sThumbRX nThumbRX;m_CurXInputMerge.Gamepad.sThumbRY nThumbRY;if (m_cbMergeState){m_cbMergeState(m_CurXInputMerge.Gamepad);}
}void CXInputHelper::_InputMergeChangeProcess()
{// 状态处理for (auto item : m_mergeEvents){INPUT_EVENT_INFO eventInfo item.second;// 按钮状态变化处理_UpateButtonState(eventInfo.eventState, m_CurXInputMerge.Gamepad, m_LastXInputMerge.Gamepad, item.first);}// 得到全部输入状态m_CurButtonMerge.dwButtons 0;for (auto item : m_mergeEvents){INPUT_EVENT_INFO eventInfo item.second;if (XINPUT_GAMEPAD_LEFT_TRIGGER item.first){m_CurButtonMerge.Mask.LeftTrigger eventInfo.eventState.curButtonFlag.Mask.Down || eventInfo.eventState.curButtonFlag.Mask.Hold;}else if (XINPUT_GAMEPAD_RIGHT_TRIGGER item.first){eventInfo.eventState.fRight true;m_CurButtonMerge.Mask.RightTrigger eventInfo.eventState.curButtonFlag.Mask.Down || eventInfo.eventState.curButtonFlag.Mask.Hold;}else if (XINPUT_GAMEPAD_LEFT_STICK item.first){m_CurButtonMerge.Mask.LeftStickUp eventInfo.eventState.buttonBitMask.Mask.LeftStickUp;m_CurButtonMerge.Mask.LeftStickDown eventInfo.eventState.buttonBitMask.Mask.LeftStickDown;m_CurButtonMerge.Mask.LeftStickLeft eventInfo.eventState.buttonBitMask.Mask.LeftStickLeft;m_CurButtonMerge.Mask.LeftStickRight eventInfo.eventState.buttonBitMask.Mask.LeftStickRight;}else if (XINPUT_GAMEPAD_RIGHT_STICK item.first){eventInfo.eventState.fRight true;m_CurButtonMerge.Mask.RightStickUp eventInfo.eventState.buttonBitMask.Mask.RightStickUp;m_CurButtonMerge.Mask.RightStickDown eventInfo.eventState.buttonBitMask.Mask.RightStickDown;m_CurButtonMerge.Mask.RightStickLeft eventInfo.eventState.buttonBitMask.Mask.RightStickLeft;m_CurButtonMerge.Mask.RightStickRight eventInfo.eventState.buttonBitMask.Mask.RightStickRight;eventInfo.eventState.sThumbX m_CurXInputMerge.Gamepad.sThumbRX;eventInfo.eventState.sThumbY m_CurXInputMerge.Gamepad.sThumbRY;}else{m_CurButtonMerge.dwButtons | eventInfo.eventState.curButtonFlag.Mask.Down || eventInfo.eventState.curButtonFlag.Mask.Hold ? item.first : 0;}}// 回调处理for (auto item : m_mergeEvents){INPUT_EVENT_INFO eventInfo item.second;eventInfo.eventState.dwButtonMask item.first;eventInfo.eventState.buttonBitMask.dwButtons m_CurButtonMerge.dwButtons;eventInfo.eventState.dwButtons m_CurButtonMerge.dwButtons;if (XINPUT_GAMEPAD_LEFT_STICK item.first){eventInfo.eventState.sThumbX m_CurXInputMerge.Gamepad.sThumbLX;eventInfo.eventState.sThumbY m_CurXInputMerge.Gamepad.sThumbLY;}if (XINPUT_GAMEPAD_RIGHT_STICK item.first){eventInfo.eventState.sThumbX m_CurXInputMerge.Gamepad.sThumbRX;eventInfo.eventState.sThumbY m_CurXInputMerge.Gamepad.sThumbRY;}if (eventInfo.eventState.curButtonFlag.State){eventInfo.eventState.xinputState m_CurXInputMerge;if (XINPUT_GAMEPAD_LEFT_TRIGGER item.first){eventInfo.eventState.bTrigger m_CurXInputMerge.Gamepad.bLeftTrigger;}if (XINPUT_GAMEPAD_RIGHT_TRIGGER item.first){eventInfo.eventState.fRight true;eventInfo.eventState.bTrigger m_CurXInputMerge.Gamepad.bRightTrigger;eventInfo.eventState.stickDirection eventInfo.eventState.curLeftStickDirection;}if (XINPUT_GAMEPAD_LEFT_STICK item.first){eventInfo.eventState.sThumbX m_CurXInputMerge.Gamepad.sThumbLX;eventInfo.eventState.sThumbY m_CurXInputMerge.Gamepad.sThumbLY;eventInfo.eventState.stickDirection eventInfo.eventState.curRightStickDirection;}if (XINPUT_GAMEPAD_RIGHT_STICK item.first){eventInfo.eventState.fRight true;eventInfo.eventState.sThumbX m_CurXInputMerge.Gamepad.sThumbRX;eventInfo.eventState.sThumbY m_CurXInputMerge.Gamepad.sThumbRY;}(this-*(eventInfo.eventCb))(eventInfo.eventState);if (m_cbMergeChange){m_cbMergeChange(eventInfo.eventState);}}}m_LastXInputMerge m_CurXInputMerge;
}main.cpp
// JoystickAssistant.cpp : 此文件包含 main 函数。程序执行将在此处开始并结束。
//#include string
#include iostream
#include windows.h
#include tchar.h
#include CWin32Utils/CXinputHelper.h
#include CWin32Utils/CInputUtils.h
#include CMainFrame.h
#include resource.h#ifdef _UNICODE
using _tstring std::wstring;
#else
using _tstring std::string;
#endifvoid LogPrintf(LPCTSTR pFormat, ...);int WINAPI WinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPSTR lpCmdLine,_In_ int nShowCmd)
{UNREFERENCED_PARAMETER(hInstance);UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);UNREFERENCED_PARAMETER(nShowCmd);CMainFrame dlg;dlg.DoModalEx(IDD_DIALOG_MAIN, NULL, TRUE, true);return 0;
}int main()
{CXInputHelper obj;obj.Initialize();obj.IgnoreLeftThumbEmpty(false);obj.IgnoreRightThumbEmpty(false);obj.SetThumbThreshold(4096);obj.SetMergeStateCallback([](const XINPUT_GAMEPAD state)- void {/*LogPrintf(_T(Button: %04X\r\n),state.wButtons);*/});obj.SetRawChangeCallback([](const INPUT_EVENT_STATE state)- void {LogPrintf(_T(Mask: %08X bRight: %d Trigger: %3d Thumb: %6d,%6d State: %d Buttons: %.8X Duration: %6d L: %d U: %d R: %d D: %d\r\n),state.dwButtonMask,state.fRight, state.bTrigger, state.sThumbX, state.sThumbY,state.curButtonFlag.State,state.dwButtons,state.dwDuration,state.stickDirection.Left.Flag.State,state.stickDirection.Up.Flag.State,state.stickDirection.Right.Flag.State,state.stickDirection.Down.Flag.State);});/*obj.SetMergeChangeCallback([](const XINPUT_GAMEPAD xGamepad, const INPUT_EVENT_STATE state)- void {LogPrintf(_T(Index: %d bRight: %d Trigger: %3d Thumb: %6d,%6d Button: %04X State: %04X Buttons: %.8X\r\n),state.dwIndex,state.fRight, state.bTrigger, state.sThumbX, state.sThumbY, state.wButton, state.curButtonFlag.State,state.allButtonState.Buttons);});*/system(pause);return 0;
}void LogPrintf(LPCTSTR pFormat, ...)
{size_t nCchCount MAX_PATH;_tstring strResult(nCchCount, 0);va_list args;va_start(args, pFormat);do{//格式化输出字符串int nSize _vsntprintf_s(strResult[0], nCchCount, _TRUNCATE, pFormat, args);if (-1 ! nSize){HANDLE console GetStdHandle(STD_OUTPUT_HANDLE);::WriteConsole(console, strResult.c_str(), nSize, NULL, NULL);break;}//缓冲大小超限终止if (nCchCount INT32_MAX){break;}//重新分配缓冲nCchCount * 2;strResult.resize(nCchCount);} while (true);va_end(args);
} 测试