编写XBOX控制器实现鼠标键盘输入

1.核心部分, XINPUT输入封装

XInput封装icon-default.png?t=O83Ahttps://mp.csdn.net/mp_blog/creation/editor/1420701282.对话框窗口编写

Win32 对话框封装-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/Flame_Cyclone/article/details/142110008?spm=1001.2014.3001.5501

3.使用到的其他封装

字符串编码转换与常用操作(Win32,C++)_windows字符串编码转换-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/Flame_Cyclone/article/details/135514476键盘鼠标模拟输入(Win32, C++)_win32 键盘输入-CSDN博客文章浏览阅读547次。简单封装SendInput的简单操作_win32 键盘输入https://blog.csdn.net/Flame_Cyclone/article/details/133162010Ini配置文件读写(Win32, C++)_win32 读取ini配置文件-CSDN博客文章浏览阅读134次。简单封装ini配置文件读写操作_win32 读取ini配置文件https://blog.csdn.net/Flame_Cyclone/article/details/130812165

4.结合输入与界面编写主要逻辑

main.cpp

#include <string>
#include <iostream>
#include <windows.h>
#include <tchar.h>
#include "CWin32Utils/CXinputHelper.h"
#include "CMainFrame.h"
#include "resource.h"#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endifint 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.SetAxisThreshold(4096, 4096);#if 0obj.SetRawEventCallback([](const GAMEPAD_INPUT_EVENT& event)-> void {CXInputHelper::PrintText(_T("Mask: %08X bRight: %d Trigger: %3d Axis: %6d,%6d Data: %d Buttons: %.8X Duration: %6d Axis: (Left: %d Up: %d Right: %d Down: %d)\r\n"),event.eButton,event.fRight, event.bTrigger, event.sAxisX, event.sAxisY,event.curButtonEvent.Event,event.curButtonState.Button,event.curButtonEvent.uDuration,event.curAxisEvent.Left.Event,event.curAxisEvent.Up.Event,event.curAxisEvent.Right.Event,event.curAxisEvent.Down.Event);});
#endifobj.SetMergeEventCallback([](const GAMEPAD_INPUT_EVENT& event)-> void {CXInputHelper::PrintText(_T("Mask: %08X bRight: %d Trigger: %3d Axis: %6d,%6d Data: %d Buttons: %.8X Duration: %6d Axis: (Left: %d Up: %d Right: %d Down: %d)\r\n"),event.eButton,event.fRight, event.bTrigger, event.sAxisX, event.sAxisY,event.curButtonEvent.Event,event.curButtonState.Button,event.curButtonEvent.uDuration,event.curAxisEvent.Left.Event,event.curAxisEvent.Up.Event,event.curAxisEvent.Right.Event,event.curAxisEvent.Down.Event);});system("pause");return 0;
}

CMainFrame.h

#pragma once
#include "CWindow/CDialogBase.h"
#include "CWin32Utils/CXInputHelper.h"
#include "CWin32Utils/CStrUtils.h"
#include "CWin32Utils/CIniHelper.h"#define NORMAL_COLOR                                    RGB(200, 200, 255)
#define ACTIVE_COLOR                                    RGB(255, 255, 0)
#define LAST_BUTTON_COLOR                               RGB(128, 128, 255)
#define VALUE_COLOR                                     RGB(255, 255, 0)
#define LAST_VALUE_COLOR                                RGB(96, 96, 255)#define MOUSE_MOVE_THRESHOLD                            (1024 * 6)     //鼠标移动摇杆阈值
#define MOUSE_SRCOLL_THRESHOLD                          (32768 / 2)     //鼠标滚轮摇杆阈值enum eMouseType
{eMouseNone,eMouseMove,eMouseWheel,eMouseLeft,eMouseRight,eMouseMiddle
};class CMainFrame: public CDialogBase, CXInputHelper
{
public:LRESULT OnInitDialog(WPARAM wParam, LPARAM lParam);LRESULT OnClose(WPARAM wParam, LPARAM lParam);LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);LRESULT OnEraseBkgnd(WPARAM wParam, LPARAM lParam);LRESULT OnPaint(WPARAM wParam, LPARAM lParam);LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);LRESULT OnDrawItem(WPARAM wParam, LPARAM lParam);LRESULT OnCtlColorDlg(WPARAM wParam, LPARAM lParam);LRESULT OnReset(WORD wNotify, WORD wID, HWND hWnd);LRESULT OnVibrationLeft(WORD wNotify, WORD wID, HWND hWnd);LRESULT OnVibrationRight(WORD wNotify, WORD wID, HWND hWnd);LRESULT OnKey(WORD wNotify, WORD wID, HWND hWnd);LRESULT OnMouse(WORD wNotify, WORD wID, HWND hWnd);LRESULT OnNone(WORD wNotify, WORD wID, HWND hWnd);LRESULT OnModifierChange(WORD wNotify, WORD wID, HWND hWnd);LRESULT OnKeyChange(WORD wNotify, WORD wID, HWND hWnd);LRESULT OnMouseChange(WORD wNotify, WORD wID, HWND hWnd);LRESULT OnDrawButton(WORD wNotify, WORD wID, HWND hWnd);private:RECT GetItemRect(WORD wID);void DrawButtonItem(DWORD wID);void DrawStatic(LPDRAWITEMSTRUCT lpDrawItem, WORD wID);void DrawAxis(LPDRAWITEMSTRUCT lpDrawItem, WORD wID);void DrawNormalButton(LPDRAWITEMSTRUCT lpDrawItem, WORD wID);void DrawABXYButton(LPDRAWITEMSTRUCT lpDrawItem, WORD wID);void DrawDpadButton(LPDRAWITEMSTRUCT lpDrawItem, WORD wID);void DrawTriggerButton(LPDRAWITEMSTRUCT lpDrawItem, WORD wID);void UpdateButtonFunction(WORD wID);void ShowButtonFunction(WORD wID);void InitList();void SaveConfig();void LoadConfig();void DoFunction(WORD wID, GAMEPAD_INPUT_EVENT& event);void DoMouseMove(int x, int y);void DoMouseWheel(int x, int y);
private:// 方向键回调virtual void OnMergeEventDpadUp(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventDpadDown(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventDpadLeft(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventDpadRight(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventBack(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventStart(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventGuide(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventA(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventB(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventX(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventY(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventLB(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventRB(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventLSB(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventRSB(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventLT(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventRT(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventLS(GAMEPAD_INPUT_EVENT& event);virtual void OnMergeEventRS(GAMEPAD_INPUT_EVENT& event);protected:DECLARE_DLG_MESSAGE_MAP()private:HDC             m_hMemDC = NULL;            // 内存DCHBITMAP         m_hMemBitmap = NULL;        // 内存位图HBRUSH          m_hBgBrush = NULL;XINPUT_STATE    m_lastState;bool m_fWndQuit = false;bool m_fVibrationLeft = false;bool m_fVibrationRight = false;HWND m_hModifier;HWND m_hKeys;HWND m_hMouse;HWND m_hNone;WORD m_wFocusID = 0;XINPUT_VIBRATION m_Vibration = { 0 };CIniHelper m_config;LONG m_sThumbLX_Min = 0;LONG m_sThumbLY_Min = 0;LONG m_sThumbRX_Min = 0;LONG m_sThumbRY_Min = 0;LONG m_sThumbLX_Max = 0;LONG m_sThumbLY_Max = 0;LONG m_sThumbRX_Max = 0;LONG m_sThumbRY_Max = 0;
};

CMainFrame.cpp

#include "CMainFrame.h"
#include "resource.h"
#include <map>
#include <vector>
#include "CWin32Utils/CInputUtils.h"enum eButtonFunction
{eNone,eKey,eMouse
};typedef struct _BUTTON_FUNCTION_INFO
{eButtonFunction eType;                  // 0: 无 1: 键盘 2: 鼠标std::vector<int> vModifier;             // 修饰键名std::vector<int> vKeys;                 // 键盘名std::vector<int> vMouse;                // 鼠标功能
}BUTTON_FUNCTION_INFO;std::map<DWORD, BUTTON_FUNCTION_INFO> g_ButtonFunctionList;//原始按键
LPCTSTR g_ModifierName[] = {_T("None"),_T("LCtrl"),        _T("RCtrl"),        _T("LAlt"),         _T("RAlt"),         _T("LWin"),         _T("RWin"),         _T("LShift"),       _T("RShift")     
};//原始按键
LPCTSTR g_KeysName[] = {_T("None"),_T("Esc"),          _T("F1"),           _T("F2"),           _T("F3"),           _T("F4"),           _T("F5"),           _T("F6"),           _T("F7"),           _T("F8"),           _T("F9"),           _T("F10"),          _T("F11"),          _T("F12"),          _T("`"),            _T("1"),            _T("2"),            _T("3"),            _T("4"),            _T("5"),            _T("6"),            _T("7"),            _T("8"),            _T("9"),            _T("0"),            _T("-"),            _T("="),            _T("Backspace"),    _T("Application"),  _T("Tab"),          _T("Space"),        _T("Enter"),        _T("["),            _T("]"),            _T("\\"),           _T(";"),            _T("\'"),           _T(","),            _T("."),            _T("/"),            _T("A"),            _T("B"),            _T("C"),            _T("D"),            _T("E"),            _T("F"),            _T("G"),            _T("H"),            _T("I"),            _T("J"),            _T("K"),            _T("L"),            _T("M"),            _T("N"),            _T("O"),            _T("P"),            _T("Q"),            _T("R"),            _T("S"),            _T("T"),            _T("U"),            _T("V"),            _T("W"),            _T("X"),            _T("Y"),            _T("Z"),            _T("Up"),           _T("Down"),         _T("Left"),         _T("Right"),        /*_T("UpArrow"),      _T("DownArrow"),    _T("LeftArrow"),    _T("RightArrow"),   */_T("Num Up"),       _T("Num Down"),     _T("Num Left"),     _T("Num Right"),    _T("Insert"),       _T("Home"),         _T("Page Up"),      _T("Delete"),       _T("End"),          _T("Page Down"),    _T("Prnt Scrn"),    _T("PrintScreen"),_T("Scroll Lock"),  _T("Num Lock"),     _T("Caps Lock"),    _T("Pause"),        _T("Num 0"),        _T("Num 1"),        _T("Num 2"),        _T("Num 3"),        _T("Num 4"),        _T("Num 5"),        _T("Num 6"),        _T("Num 7"),        _T("Num 8"),        _T("Num 9"),        _T("Num Home"),     _T("Num End"),      _T("Num Page Up"),  _T("Num Page Down"),_T("Clear"),        _T("Num /"),        _T("Num *"),        _T("Num -"),        _T("Num +"),        _T("Num Enter"),    _T("Num Del"),      _T("Num Insert"),   _T("Num ."),        };  //118个按键//原始按键
LPCTSTR g_MouseName[] = {_T("None"),_T("Move"),_T("Wheel"),_T("Left Button"),_T("Right Button"),_T("Middle Button"),
};WORD g_DrawItemIDs[] = {IDC_BUTTON_LEFTSTICK        ,IDC_BUTTON_RIGHTSTICK       ,IDC_BUTTON_DPAD_UP          ,IDC_BUTTON_DPAD_DOWN        ,IDC_BUTTON_DPAD_LEFT        ,IDC_BUTTON_DPAD_RIGHT       ,IDC_BUTTON_Y                ,IDC_BUTTON_A                ,IDC_BUTTON_X                ,IDC_BUTTON_B                ,IDC_BUTTON_BACK             ,IDC_BUTTON_START            ,IDC_BUTTON_GUIDE            ,IDC_BUTTON_LB               ,IDC_BUTTON_RB               ,IDC_BUTTON_LT               ,IDC_BUTTON_RT               ,IDC_BUTTON_LSB               ,IDC_BUTTON_RSB               ,IDC_STATIC_LEFT_STICK_X    ,IDC_STATIC_LEFT_STICK_Y    ,IDC_STATIC_RIGHT_STICK_X   ,IDC_STATIC_RIGHT_STICK_Y   ,
};BEGIN_DLG_MESSAGE_MAP(CMainFrame, CDialogBase)ON_DLG_MESSAGE(WM_INITDIALOG, &CMainFrame::OnInitDialog)ON_DLG_MESSAGE(WM_CLOSE, &CMainFrame::OnClose)ON_DLG_MESSAGE(WM_DESTROY, &CMainFrame::OnDestroy)ON_DLG_MESSAGE(WM_ERASEBKGND, &CMainFrame::OnEraseBkgnd)ON_DLG_MESSAGE(WM_PAINT, &CMainFrame::OnPaint)//ON_DLG_MESSAGE(WM_CTLCOLORDLG, &CMainFrame::OnCtlColorDlg)ON_DLG_MESSAGE(WM_LBUTTONDOWN, &CMainFrame::OnLButtonDown)ON_DLG_MESSAGE(WM_DRAWITEM, &CMainFrame::OnDrawItem)ON_DLG_COMMAND(IDC_CHECK_VIBRATION_LEFT, &CMainFrame::OnVibrationLeft)ON_DLG_COMMAND(IDC_CHECK_VIBRATION_RIGHT, &CMainFrame::OnVibrationRight)ON_DLG_COMMAND(IDC_BUTTON_RESET, &CMainFrame::OnReset)ON_DLG_COMMAND(IDC_RADIO_KEY, &CMainFrame::OnKey)ON_DLG_COMMAND(IDC_RADIO_MOUSE, &CMainFrame::OnMouse)ON_DLG_COMMAND(IDC_RADIO_NONE, &CMainFrame::OnNone)ON_DLG_COMMAND_NOTIFY(LBN_SELCHANGE, IDC_LIST_MODIFIER, &CMainFrame::OnKeyChange)ON_DLG_COMMAND_NOTIFY(LBN_SELCHANGE, IDC_LIST_KEYS, &CMainFrame::OnKeyChange)ON_DLG_COMMAND_NOTIFY(LBN_SELCHANGE, IDC_LIST_MOUSE, &CMainFrame::OnMouseChange)ON_DLG_COMMAND(IDC_BUTTON_LSB            , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_RSB            , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_LEFTSTICK     , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_RIGHTSTICK    , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_DPAD_UP       , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_DPAD_DOWN     , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_DPAD_LEFT     , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_DPAD_RIGHT    , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_Y             , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_A             , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_X             , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_B             , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_BACK          , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_START         , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_GUIDE         , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_LB            , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_RB            , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_LT            , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_RT            , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_BUTTON_RESET         , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_CHECK_VIBRATION_LEFT , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_CHECK_VIBRATION_RIGHT, &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_STATIC_LEFT_STICK_X  , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_STATIC_LEFT_STICK_Y  , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_STATIC_RIGHT_STICK_X , &CMainFrame::OnDrawButton)ON_DLG_COMMAND(IDC_STATIC_RIGHT_STICK_Y , &CMainFrame::OnDrawButton)END_DLG_MESSAGE_MAP()LRESULT CMainFrame::OnInitDialog(WPARAM wParam, LPARAM lParam)
{memset(&m_lastState, 0, sizeof(m_lastState));RECT rect = { 0 };::GetClientRect(m_hWnd, &rect);WORD cxClient = rect.right - rect.left;WORD cyClient = rect.bottom - rect.top;HDC hdc = ::GetDC(m_hWnd);BuildDcBitmap(hdc, &m_hMemDC, &m_hMemBitmap, cxClient, cyClient);HFONT hFont = (HFONT)SendMessage(WM_GETFONT, 0, 0);m_hBgBrush = (HBRUSH)SendMessage(WM_CTLCOLORDLG, 0, 0);::FillRect(m_hMemDC, &rect, m_hBgBrush);::SelectObject(m_hMemDC, hFont);// 设置图标HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON));if (hIcon){::SendMessage(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);::SendMessage(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);}PostCommand(IDC_BUTTON_RESET);Initialize();m_hModifier = GetItem(IDC_LIST_MODIFIER);m_hKeys = GetItem(IDC_LIST_KEYS);m_hMouse = GetItem(IDC_LIST_MOUSE);InitList();::EnableWindow(m_hModifier, FALSE);::EnableWindow(m_hKeys, FALSE);::EnableWindow(m_hMouse, FALSE);CheckButton(IDC_RADIO_NONE, true);CheckButton(IDC_RADIO_KEY, false);CheckButton(IDC_RADIO_MOUSE, false);LoadConfig();return (LRESULT)TRUE;
}LRESULT CMainFrame::OnCtlColorDlg(WPARAM wParam, LPARAM lParam)
{return (LRESULT)GetStockBrush(WHITE_BRUSH);
}LRESULT CMainFrame::OnClose(WPARAM wParam, LPARAM lParam)
{m_fWndQuit = true;Uninitialize();DeleteDcBitmap(&m_hMemDC, &m_hMemBitmap);SaveConfig();return (LRESULT)FALSE;
}LRESULT CMainFrame::OnDestroy(WPARAM wParam, LPARAM lParam)
{return (LRESULT)FALSE;
}LRESULT CMainFrame::OnEraseBkgnd(WPARAM wParam, LPARAM lParam)
{return (LRESULT)TRUE;
}LRESULT CMainFrame::OnPaint(WPARAM wParam, LPARAM lParam)
{PAINTSTRUCT ps = { 0 };HDC hdc = ::BeginPaint(m_hWnd, &ps);RECT rect = { 0 };::GetClientRect(m_hWnd, &rect);{::BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom, m_hMemDC, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);}::EndPaint(m_hWnd, &ps);return FALSE;
}void CMainFrame::DrawButtonItem(DWORD wID)
{PostCommand(wID);
}LRESULT CMainFrame::OnLButtonDown(WPARAM wParam, LPARAM lParam)
{for (const auto& item : g_DrawItemIDs){RECT reReset = GetItemRect(item);POINT pt = { 0 };pt.x = GET_X_LPARAM(lParam);pt.y = GET_Y_LPARAM(lParam);if (PtInRect(&reReset, pt)){m_wFocusID = item;}}// 刷新显示for (auto item : g_DrawItemIDs){DRAWITEMSTRUCT DrawItem = { 0 };DrawItem.CtlID = item;OnDrawItem(0, (LPARAM)&DrawItem);InvalidateRect(GetItem(item), NULL, FALSE);}ShowButtonFunction(m_wFocusID);return FALSE;
}LRESULT CMainFrame::OnVibrationLeft(WORD wNotify, WORD wID, HWND hWnd)
{m_fVibrationLeft = IsButtonChecked(wID);return TRUE;
}LRESULT CMainFrame::OnVibrationRight(WORD wNotify, WORD wID, HWND hWnd)
{m_fVibrationRight = IsButtonChecked(wID);return TRUE;
}LRESULT CMainFrame::OnKey(WORD wNotify, WORD wID, HWND hWnd)
{EnableWindow(m_hModifier, true);EnableWindow(m_hKeys, true);EnableWindow(m_hMouse, false);UpdateButtonFunction(wID);return TRUE;
}LRESULT CMainFrame::OnMouse(WORD wNotify, WORD wID, HWND hWnd)
{EnableWindow(m_hModifier, false);EnableWindow(m_hKeys, false);EnableWindow(m_hMouse, true);UpdateButtonFunction(wID);return TRUE;
}LRESULT CMainFrame::OnNone(WORD wNotify, WORD wID, HWND hWnd)
{EnableWindow(m_hModifier, false);EnableWindow(m_hKeys, false);EnableWindow(m_hMouse, false);UpdateButtonFunction(wID);return TRUE;
}LRESULT CMainFrame::OnReset(WORD wNotify, WORD wID, HWND hWnd)
{RECT rtClient = { 0 };::GetClientRect(m_hWnd, &rtClient);::FillRect(m_hMemDC, &rtClient, (HBRUSH)SendMessage(WM_CTLCOLORDLG, 0, 0));m_sThumbLX_Min = 0;m_sThumbLY_Min = 0;m_sThumbRX_Min = 0;m_sThumbRY_Min = 0;m_sThumbLX_Max = 0;m_sThumbLY_Max = 0;m_sThumbRX_Max = 0;m_sThumbRY_Max = 0;memset(&m_lastState, 0, sizeof(m_lastState));for (auto item : g_DrawItemIDs){PostCommand(item);}return (LRESULT)TRUE;
}LRESULT CMainFrame::OnDrawItem(WPARAM wParam, LPARAM lParam)
{LPDRAWITEMSTRUCT lpDrawItem = (LPDRAWITEMSTRUCT)lParam;lpDrawItem->hDC = m_hMemDC;lpDrawItem->rcItem = GetItemRect(lpDrawItem->CtlID);if (lpDrawItem->CtlID == IDC_BUTTON_A ||lpDrawItem->CtlID == IDC_BUTTON_B ||lpDrawItem->CtlID == IDC_BUTTON_X ||lpDrawItem->CtlID == IDC_BUTTON_Y){DrawABXYButton(lpDrawItem, lpDrawItem->CtlID);}if (lpDrawItem->CtlID == IDC_BUTTON_DPAD_UP || lpDrawItem->CtlID == IDC_BUTTON_DPAD_DOWN || lpDrawItem->CtlID == IDC_BUTTON_DPAD_LEFT || lpDrawItem->CtlID == IDC_BUTTON_DPAD_RIGHT){DrawDpadButton(lpDrawItem, lpDrawItem->CtlID);}if (lpDrawItem->CtlID == IDC_BUTTON_LB ||lpDrawItem->CtlID == IDC_BUTTON_RB ||lpDrawItem->CtlID == IDC_BUTTON_LSB ||lpDrawItem->CtlID == IDC_BUTTON_RSB ||lpDrawItem->CtlID == IDC_BUTTON_BACK ||lpDrawItem->CtlID == IDC_BUTTON_GUIDE ||lpDrawItem->CtlID == IDC_BUTTON_START || lpDrawItem->CtlID == IDC_BUTTON_RESET){DrawNormalButton(lpDrawItem, lpDrawItem->CtlID);}if (lpDrawItem->CtlID == IDC_BUTTON_LT || lpDrawItem->CtlID == IDC_BUTTON_RT){DrawTriggerButton(lpDrawItem, lpDrawItem->CtlID);}if (lpDrawItem->CtlID == IDC_BUTTON_LEFTSTICK || lpDrawItem->CtlID == IDC_BUTTON_RIGHTSTICK){DrawAxis(lpDrawItem, lpDrawItem->CtlID);}if (lpDrawItem->CtlID == IDC_STATIC_LEFT_STICK_X ||lpDrawItem->CtlID == IDC_STATIC_LEFT_STICK_Y ||lpDrawItem->CtlID == IDC_STATIC_RIGHT_STICK_X ||lpDrawItem->CtlID == IDC_STATIC_RIGHT_STICK_Y){DrawStatic(lpDrawItem, lpDrawItem->CtlID);}::InvalidateRect(m_hWnd, &lpDrawItem->rcItem, FALSE);return (LRESULT)TRUE;
}void CMainFrame::DrawStatic(LPDRAWITEMSTRUCT lpDrawItem, WORD wID)
{HBRUSH hBkgBrush = m_hBgBrush;HDC hdc = lpDrawItem->hDC;RECT rcItem = lpDrawItem->rcItem;LONG nWidth = rcItem.right - rcItem.left;LONG nHeight = rcItem.bottom - rcItem.top;LONG sThumbX = 0;LONG sThumbY = 0;if (wID == IDC_STATIC_LEFT_STICK_X){sThumbX = m_CurXInputStateMerge.Gamepad.sThumbLX;_tstring strValue = CStrUtils::Format(_T("X: %6d"), sThumbX);RECT rtText = GetItemRect(IDC_STATIC_LEFT_STICK_X);::FillRect(hdc, &rtText, hBkgBrush);::TextOut(hdc, rtText.left, rtText.top, strValue.c_str(), strValue.size());}if (wID == IDC_STATIC_LEFT_STICK_X){sThumbY = -m_CurXInputStateMerge.Gamepad.sThumbLY;_tstring strValue = CStrUtils::Format(_T("Y: %6d"), -sThumbY);RECT rtText = GetItemRect(IDC_STATIC_LEFT_STICK_Y);::FillRect(hdc, &rtText, hBkgBrush);::TextOut(hdc, rtText.left, rtText.top, strValue.c_str(), strValue.size());}if (wID == IDC_STATIC_RIGHT_STICK_X){sThumbX = m_CurXInputStateMerge.Gamepad.sThumbRX;_tstring strValue = CStrUtils::Format(_T("X: %6d"), sThumbX);RECT rtText = GetItemRect(IDC_STATIC_RIGHT_STICK_X);::FillRect(hdc, &rtText, hBkgBrush);::TextOut(hdc, rtText.left, rtText.top, strValue.c_str(), strValue.size());}if (wID == IDC_STATIC_RIGHT_STICK_Y){sThumbY = -m_CurXInputStateMerge.Gamepad.sThumbRY;_tstring strValue = CStrUtils::Format(_T("Y: %6d"), -sThumbY);RECT rtText = GetItemRect(IDC_STATIC_RIGHT_STICK_Y);::FillRect(hdc, &rtText, hBkgBrush);::TextOut(hdc, rtText.left, rtText.top, strValue.c_str(), strValue.size());}}RECT CMainFrame::GetItemRect(WORD wID)
{RECT rtItem = { 0 };::GetWindowRect(GetItem(wID), &rtItem);POINT ptClient = { rtItem.left, rtItem.top };::ScreenToClient(m_hWnd, &ptClient);RECT rtResult = { 0 };rtResult.left = ptClient.x;rtResult.top = ptClient.y;rtResult.right = ptClient.x + (rtItem.right - rtItem.left);rtResult.bottom = ptClient.y + (rtItem.bottom - rtItem.top);return rtResult;
}void CMainFrame::DrawAxis(LPDRAWITEMSTRUCT lpDrawItem, WORD wID)
{HBRUSH hBkgBrush = m_hBgBrush;HBRUSH hNormalBrush = ::CreateSolidBrush(NORMAL_COLOR);HBRUSH hActiveBrush = ::CreateSolidBrush(ACTIVE_COLOR);HBRUSH hValueBrush = ::CreateSolidBrush(VALUE_COLOR);HBRUSH hLastBrush = ::CreateSolidBrush(LAST_BUTTON_COLOR);HBRUSH hLastValueBrush = ::CreateSolidBrush(LAST_VALUE_COLOR);HDC hdc = lpDrawItem->hDC;RECT rcItem = lpDrawItem->rcItem;LONG nWidth = rcItem.right - rcItem.left;LONG nHeight = rcItem.bottom - rcItem.top;LONG sThumbX = 0;LONG sThumbY = 0;_tstring strText = GetItemString(wID);::SetBkMode(hdc, TRANSPARENT);{RECT rcBg = lpDrawItem->rcItem;rcBg.right += 1;rcBg.bottom += 1;::FillRect(hdc, &rcBg, hBkgBrush);}HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, hNormalBrush);::Ellipse(hdc, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);::SelectObject(hdc, hOldBrush);if (wID == IDC_BUTTON_LEFTSTICK){sThumbX = m_CurXInputStateMerge.Gamepad.sThumbLX;sThumbY = -m_CurXInputStateMerge.Gamepad.sThumbLY;}if (wID == IDC_BUTTON_RIGHTSTICK){sThumbX = m_CurXInputStateMerge.Gamepad.sThumbRX;sThumbY = -m_CurXInputStateMerge.Gamepad.sThumbRY;}if (wID == IDC_BUTTON_LEFTSTICK){RECT rtLast = {};rtLast.left = rcItem.left + nWidth / 2 + (double)m_sThumbLX_Min / (double)32768 * nWidth / 2;rtLast.top = rcItem.top + nHeight / 2 + (double)m_sThumbLY_Min / (double)32768 * nHeight / 2;rtLast.right = rcItem.left + nWidth / 2 + (double)m_sThumbLX_Max / (double)32768 * nWidth / 2 + 1;rtLast.bottom = rcItem.top + nWidth / 2 + (double)m_sThumbLY_Max / (double)32768 * nHeight / 2 + 1;::FillRect(hdc, &rtLast, hLastValueBrush);}if (wID == IDC_BUTTON_RIGHTSTICK){RECT rtLast = {};rtLast.left = rcItem.left + nWidth / 2 + (double)m_sThumbRX_Min / (double)32768 * nWidth / 2;rtLast.top = rcItem.top + nHeight / 2 + (double)m_sThumbRY_Min / (double)32768 * nHeight / 2;rtLast.right = rcItem.left + nWidth / 2 + (double)m_sThumbRX_Max / (double)32768 * nWidth / 2 + 1;rtLast.bottom = rcItem.top + nWidth / 2 + (double)m_sThumbRY_Max / (double)32768 * nHeight / 2 + 1;::FillRect(hdc, &rtLast, hLastValueBrush);}{HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, ::GetStockObject(NULL_BRUSH));HPEN hOldPen = (HPEN)::SelectObject(hdc, m_wFocusID == wID ? GetStockObject(BLACK_PEN) :  GetStockObject(WHITE_PEN));::Ellipse(hdc, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);::SelectObject(hdc, hOldBrush);::SelectObject(hdc, hOldPen);}{HPEN hOldPen = (HPEN)::SelectObject(hdc, GetStockObject(WHITE_PEN));::MoveToEx(hdc, rcItem.left, rcItem.top + nHeight / 2, nullptr);::LineTo(hdc, rcItem.right, rcItem.top + nHeight / 2);::MoveToEx(hdc, rcItem.left + nWidth/ 2, rcItem.top, nullptr);::LineTo(hdc, rcItem.left + nWidth/ 2, rcItem.bottom);::SelectObject(hdc, hOldPen);}RECT rcThumb = rcItem;LONG nX = (double)sThumbX / (double)32768 * nWidth / 2;LONG nY = (double)sThumbY / (double)32768 * nHeight / 2;rcThumb.right = rcThumb.left + nX;rcThumb.bottom = rcThumb.top + nY;if (rcThumb.right < rcThumb.left){LONG tmp = rcThumb.right;rcThumb.right = rcThumb.left;rcThumb.left = tmp;}if (rcThumb.bottom < rcThumb.top){LONG tmp = rcThumb.bottom;rcThumb.bottom = rcThumb.top;rcThumb.top = tmp;}::OffsetRect(&rcThumb, nWidth / 2, nHeight / 2);{HPEN hPen = CreatePen(PS_SOLID, 1, VALUE_COLOR);HPEN hOldPen = (HPEN)::SelectObject(hdc, hPen);HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, hValueBrush);rcThumb.right += 1;rcThumb.bottom += 1;::Rectangle(hdc, rcThumb.left, rcThumb.top, rcThumb.right, rcThumb.bottom);::SelectObject(hdc, hOldBrush);::SelectObject(hdc, hOldPen);::DeleteObject(hPen);}::DeleteObject(hLastBrush);::DeleteObject(hValueBrush);::DeleteObject(hLastValueBrush);::DeleteObject(hNormalBrush);::DeleteObject(hActiveBrush);
}void CMainFrame::DrawTriggerButton(LPDRAWITEMSTRUCT lpDrawItem, WORD wID)
{HBRUSH hBkgBrush = m_hBgBrush;HBRUSH hNormalBrush = ::CreateSolidBrush(NORMAL_COLOR);HBRUSH hActiveBrush = ::CreateSolidBrush(ACTIVE_COLOR);HBRUSH hValueBrush = ::CreateSolidBrush(VALUE_COLOR);HBRUSH hLastBrush = ::CreateSolidBrush(LAST_BUTTON_COLOR);HDC hdc = lpDrawItem->hDC;RECT rcItem = lpDrawItem->rcItem;BYTE bTrigger = 0;BYTE bLastTrigger = 0;if (wID == IDC_BUTTON_LT){bTrigger = m_CurXInputStateMerge.Gamepad.bLeftTrigger;bLastTrigger = m_lastState.Gamepad.bLeftTrigger;}if (wID == IDC_BUTTON_RT){bTrigger = m_CurXInputStateMerge.Gamepad.bRightTrigger;bLastTrigger = m_lastState.Gamepad.bRightTrigger;}_tstring strText = GetItemString(wID);::SetBkMode(hdc, TRANSPARENT);::FillRect(hdc, &rcItem, hNormalBrush);{RECT rcTrigger = rcItem;rcTrigger.top = rcItem.bottom - ((rcItem.bottom - rcItem.top) * (double)((double)bLastTrigger / (double)255));::FillRect(hdc, &rcTrigger, hLastBrush);}{RECT rcTrigger = rcItem;rcTrigger.top = rcItem.bottom - ((rcItem.bottom - rcItem.top) * (double)((double)bTrigger / (double)255));::FillRect(hdc, &rcTrigger, hActiveBrush);}::FrameRect(hdc, &rcItem, hBkgBrush);::DrawText(hdc, strText.c_str(), strText.size(), &rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);_tstring strValue = CStrUtils::Format(_T("%d"), bTrigger);rcItem.bottom -= 4;::DrawText(hdc, strValue.c_str(), strValue.size(), &rcItem, DT_CENTER | DT_BOTTOM | DT_SINGLELINE);{rcItem = lpDrawItem->rcItem;::FrameRect(hdc, &rcItem, wID == m_wFocusID ? GetStockBrush(BLACK_BRUSH) : GetStockBrush(WHITE_BRUSH));}::DeleteObject(hLastBrush);::DeleteObject(hValueBrush);::DeleteObject(hNormalBrush);::DeleteObject(hActiveBrush);
}void CMainFrame::DrawABXYButton(LPDRAWITEMSTRUCT lpDrawItem, WORD wID)
{HBRUSH hNormalBrush = ::CreateSolidBrush(NORMAL_COLOR);HBRUSH hActiveBrush = ::CreateSolidBrush(ACTIVE_COLOR);HBRUSH hValueBrush = ::CreateSolidBrush(VALUE_COLOR);HBRUSH hLastBrush = ::CreateSolidBrush(LAST_BUTTON_COLOR);HDC hdc = lpDrawItem->hDC;RECT rcItem = lpDrawItem->rcItem;bool fHitState = 0;bool fLastState = 0;DWORD dwTextColor = RGB(0, 0, 0);if (wID == IDC_BUTTON_X){fHitState = m_CurXInputStateMerge.Gamepad.wButtons & XINPUT_GAMEPAD_X;fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_X;dwTextColor = RGB(0, 51, 103);}if (wID == IDC_BUTTON_Y){fHitState = m_CurXInputStateMerge.Gamepad.wButtons & XINPUT_GAMEPAD_Y;fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_Y;dwTextColor = RGB(255, 255, 0);}if (wID == IDC_BUTTON_B){fHitState = m_CurXInputStateMerge.Gamepad.wButtons & XINPUT_GAMEPAD_B;fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_B;dwTextColor = RGB(255, 0, 0);}if (wID == IDC_BUTTON_A){fHitState = m_CurXInputStateMerge.Gamepad.wButtons & XINPUT_GAMEPAD_A;fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_A;dwTextColor = RGB(0, 255, 0);}_tstring strText = GetItemString(wID);::SetBkMode(hdc, TRANSPARENT);HPEN hOldPen = (HPEN)::SelectObject(hdc, wID == m_wFocusID ? GetStockObject(BLACK_PEN) : GetStockObject(WHITE_PEN));// 焦点状态if (fHitState){// 绘制按键HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, hActiveBrush);::Ellipse(hdc, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);::SelectObject(hdc, hOldBrush);}else{if (fLastState){HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, hLastBrush);::Ellipse(hdc, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);::SelectObject(hdc, hOldBrush);}else{HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, hNormalBrush);::Ellipse(hdc, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);::SelectObject(hdc, hOldBrush);}}::SelectObject(hdc, hOldPen);// 绘制文本DWORD dwLastColor = ::SetTextColor(hdc, dwTextColor);::DrawText(hdc, strText.c_str(), strText.size(), &rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);::SetTextColor(hdc, dwLastColor);::DeleteObject(hLastBrush);::DeleteObject(hValueBrush);::DeleteObject(hNormalBrush);::DeleteObject(hActiveBrush);
}void CMainFrame::DrawDpadButton(LPDRAWITEMSTRUCT lpDrawItem, WORD wID)
{HBRUSH hBkgBrush = m_hBgBrush;HBRUSH hNormalBrush = ::CreateSolidBrush(NORMAL_COLOR);HBRUSH hActiveBrush = ::CreateSolidBrush(ACTIVE_COLOR);HBRUSH hValueBrush = ::CreateSolidBrush(VALUE_COLOR);HBRUSH hLastBrush = ::CreateSolidBrush(LAST_BUTTON_COLOR);HDC hdc = lpDrawItem->hDC;RECT rcItem = lpDrawItem->rcItem;LONG nWidth = rcItem.right - rcItem.left;LONG nHeight = rcItem.bottom - rcItem.top;POINT ptButton[3] = { 0 };bool fHitState = 0;bool fLastState = 0;if (wID == IDC_BUTTON_DPAD_UP){fHitState = m_CurXInputStateMerge.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP;fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP;ptButton[0] = {rcItem.left + nWidth / 4, rcItem.bottom - nHeight / 4};ptButton[1] = {rcItem.right - nWidth / 4, rcItem.bottom - nHeight / 4};ptButton[2] = {rcItem.left + nWidth / 2, rcItem.top + nHeight / 3};}if (wID == IDC_BUTTON_DPAD_DOWN){ fHitState = m_CurXInputStateMerge.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN;fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN;ptButton[0] = {rcItem.left + nWidth / 4, rcItem.top + nHeight / 4};ptButton[1] = {rcItem.right - nWidth / 4, rcItem.top + nHeight / 4};ptButton[2] = {rcItem.left + nWidth / 2, rcItem.bottom - nHeight / 3};}if (wID == IDC_BUTTON_DPAD_LEFT){ fHitState = m_CurXInputStateMerge.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT;fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT;ptButton[0] = {rcItem.right - nWidth / 4, rcItem.top + nHeight / 4};ptButton[1] = {rcItem.right - nWidth / 4, rcItem.bottom - nHeight / 4};ptButton[2] = {rcItem.left + nWidth / 3, rcItem.top + nHeight / 2};}if (wID == IDC_BUTTON_DPAD_RIGHT){ fHitState = m_CurXInputStateMerge.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT;fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT;ptButton[0] = {rcItem.left + nWidth / 4, rcItem.top + nHeight / 4};ptButton[1] = {rcItem.left + nWidth / 4, rcItem.bottom - nHeight / 4};ptButton[2] = {rcItem.right - nWidth / 3, rcItem.top + nHeight / 2};}_tstring strText = GetItemString(wID);::SetBkMode(hdc, TRANSPARENT);// 焦点状态if (fHitState){::FillRect(hdc, &rcItem, hActiveBrush);::FrameRect(hdc, &rcItem, hBkgBrush);}else{if (fLastState){::FillRect(hdc, &rcItem, hLastBrush);::FrameRect(hdc, &rcItem, hBkgBrush);}else{::FillRect(hdc, &rcItem, hNormalBrush);::FrameRect(hdc, &rcItem, hBkgBrush);}}{// 绘制按键HPEN hPen = CreatePen(PS_NULL, 1, VALUE_COLOR);HPEN hOldPen = (HPEN)::SelectObject(hdc, hPen);::Polygon(hdc, ptButton, _countof(ptButton));::SelectObject(hdc, hOldPen);::DeleteObject(hPen);}::FrameRect(hdc, &rcItem, wID == m_wFocusID ? GetStockBrush(BLACK_BRUSH) : GetStockBrush(WHITE_BRUSH));::DeleteObject(hLastBrush);::DeleteObject(hValueBrush);::DeleteObject(hNormalBrush);::DeleteObject(hActiveBrush);
}void CMainFrame::DrawNormalButton(LPDRAWITEMSTRUCT lpDrawItem, WORD wID)
{HBRUSH hBkgBrush = m_hBgBrush;HBRUSH hNormalBrush = ::CreateSolidBrush(NORMAL_COLOR);HBRUSH hActiveBrush = ::CreateSolidBrush(ACTIVE_COLOR);HBRUSH hValueBrush = ::CreateSolidBrush(VALUE_COLOR);HBRUSH hLastBrush = ::CreateSolidBrush(LAST_BUTTON_COLOR);HDC hdc = lpDrawItem->hDC;RECT rcItem = lpDrawItem->rcItem;LONG nWidth = rcItem.right - rcItem.left;LONG nHeight = rcItem.bottom - rcItem.top;bool fHitState = 0;bool fLastState = 0;if (wID == IDC_BUTTON_LSB)      fHitState = m_CurButtonStateMerge.LSB;if (wID == IDC_BUTTON_RSB)      fHitState = m_CurButtonStateMerge.RSB;if (wID == IDC_BUTTON_X)        fHitState = m_CurButtonStateMerge.X;if (wID == IDC_BUTTON_Y)        fHitState = m_CurButtonStateMerge.Y;if (wID == IDC_BUTTON_B)        fHitState = m_CurButtonStateMerge.B;if (wID == IDC_BUTTON_A)        fHitState = m_CurButtonStateMerge.A;if (wID == IDC_BUTTON_LB)       fHitState = m_CurButtonStateMerge.LB;if (wID == IDC_BUTTON_RB)       fHitState = m_CurButtonStateMerge.RB;if (wID == IDC_BUTTON_BACK)     fHitState = m_CurButtonStateMerge.Back;if (wID == IDC_BUTTON_GUIDE)    fHitState = m_CurButtonStateMerge.Guide;if (wID == IDC_BUTTON_START)    fHitState = m_CurButtonStateMerge.Start;if (wID == IDC_BUTTON_LSB)      fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB;if (wID == IDC_BUTTON_RSB)      fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB;if (wID == IDC_BUTTON_X)        fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_X;if (wID == IDC_BUTTON_Y)        fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_Y;if (wID == IDC_BUTTON_B)        fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_B;if (wID == IDC_BUTTON_A)        fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_A;if (wID == IDC_BUTTON_LB)       fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER;if (wID == IDC_BUTTON_RB)       fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER;if (wID == IDC_BUTTON_BACK)     fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_BACK;if (wID == IDC_BUTTON_GUIDE)    fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE;if (wID == IDC_BUTTON_START)    fLastState = m_lastState.Gamepad.wButtons & XINPUT_GAMEPAD_START;_tstring strText = GetItemString(wID);::SetBkMode(hdc, TRANSPARENT);HBRUSH hFillBrush = hActiveBrush;// 焦点状态if (fHitState){hFillBrush = hActiveBrush;}else{if (fLastState){hFillBrush = hLastBrush;}else{hFillBrush = hNormalBrush;}}// 焦点状态if (IDC_BUTTON_GUIDE != wID){::FillRect(hdc, &rcItem, hFillBrush);::FrameRect(hdc, &rcItem, hBkgBrush);}if (IDC_BUTTON_GUIDE == wID){// 绘制背景HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, hFillBrush);HPEN hOldPen = (HPEN)::SelectObject(hdc, wID == m_wFocusID ? GetStockObject(BLACK_PEN) : GetStockObject(WHITE_PEN));::Ellipse(hdc, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);::SelectObject(hdc, hOldPen);::SelectObject(hdc, hOldBrush);::DrawText(hdc, strText.c_str(), strText.size(), &rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);}else if (IDC_BUTTON_BACK == wID){RECT rtButton = rcItem;rtButton.top = rcItem.top + nHeight / 8;rtButton.bottom = rtButton.top + nHeight / 2;rtButton.left = rcItem.left + nWidth / 8;rtButton.right = rcItem.right - nWidth / 3;::FillRect(hdc, &rtButton, GetStockBrush(WHITE_BRUSH));::InflateRect(&rtButton, -4, -4);::FillRect(hdc, &rtButton, hFillBrush);rtButton = rcItem;rtButton.top = rcItem.top + nHeight / 8;rtButton.bottom = rtButton.top + nHeight / 2;rtButton.left = rcItem.left + nWidth / 8;rtButton.right = rcItem.right - nWidth / 3;::OffsetRect(&rtButton, nWidth / 8, nHeight / 8);::FillRect(hdc, &rtButton, hFillBrush);::OffsetRect(&rtButton, nWidth / 8, nHeight / 8);::FillRect(hdc, &rtButton, GetStockBrush(WHITE_BRUSH));::InflateRect(&rtButton, -4, -4);::FillRect(hdc, &rtButton, hFillBrush);::FrameRect(hdc, &rcItem, wID == m_wFocusID ? GetStockBrush(BLACK_BRUSH) : GetStockBrush(WHITE_BRUSH));}else if (IDC_BUTTON_START == wID){RECT rtButton = rcItem;rtButton.top = rcItem.top + nHeight / 6;rtButton.bottom = rtButton.top + nHeight / 8;rtButton.left = rcItem.left + nWidth / 8;rtButton.right = rcItem.right - nWidth / 8;::FillRect(hdc, &rtButton, GetStockBrush(WHITE_BRUSH));::OffsetRect(&rtButton, 0, nHeight / 4);::FillRect(hdc, &rtButton, GetStockBrush(WHITE_BRUSH));::OffsetRect(&rtButton, 0, nHeight / 4);::FillRect(hdc, &rtButton, GetStockBrush(WHITE_BRUSH));::FrameRect(hdc, &rcItem, wID == m_wFocusID ? GetStockBrush(BLACK_BRUSH) : GetStockBrush(WHITE_BRUSH));}else{::FrameRect(hdc, &rcItem, wID == m_wFocusID ? GetStockBrush(BLACK_BRUSH) : GetStockBrush(WHITE_BRUSH));::DrawText(hdc, strText.c_str(), strText.size(), &rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);}::DeleteObject(hLastBrush);::DeleteObject(hValueBrush);::DeleteObject(hNormalBrush);::DeleteObject(hActiveBrush);
}LRESULT CMainFrame::OnDrawButton(WORD wNotify, WORD wID, HWND hWnd)
{DRAWITEMSTRUCT DrawItem = { 0 };DrawItem.CtlID = wID;OnDrawItem(0, (LPARAM)&DrawItem);return 0;
}void CMainFrame::OnMergeEventDpadUp(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_DPAD_UP){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_DPAD_UP;}DrawButtonItem(IDC_BUTTON_DPAD_UP);DoFunction(IDC_BUTTON_DPAD_UP, event);
}void CMainFrame::OnMergeEventDpadDown(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_DPAD_DOWN){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_DPAD_DOWN;}DrawButtonItem(IDC_BUTTON_DPAD_DOWN);DoFunction(IDC_BUTTON_DPAD_DOWN, event);
}void CMainFrame::OnMergeEventDpadLeft(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_DPAD_LEFT){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_DPAD_LEFT;}DrawButtonItem(IDC_BUTTON_DPAD_LEFT);DoFunction(IDC_BUTTON_DPAD_LEFT, event);
}void CMainFrame::OnMergeEventDpadRight(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_DPAD_RIGHT){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_DPAD_RIGHT;}DrawButtonItem(IDC_BUTTON_DPAD_RIGHT);DoFunction(IDC_BUTTON_DPAD_RIGHT, event);
}void CMainFrame::OnMergeEventBack(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_BACK){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_BACK;}DrawButtonItem(IDC_BUTTON_BACK);DoFunction(IDC_BUTTON_BACK, event);
}void CMainFrame::OnMergeEventStart(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_START){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_START;}DrawButtonItem(IDC_BUTTON_START);DoFunction(IDC_BUTTON_START, event);
}void CMainFrame::OnMergeEventGuide(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_GUIDE){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_GUIDE;}DrawButtonItem(IDC_BUTTON_GUIDE);::Sleep(100);DoFunction(IDC_BUTTON_GUIDE, event);
}void CMainFrame::OnMergeEventA(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_A){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_A;}DrawButtonItem(IDC_BUTTON_A);DoFunction(IDC_BUTTON_A, event);
}void CMainFrame::OnMergeEventB(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_B){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_B;}DrawButtonItem(IDC_BUTTON_B);DoFunction(IDC_BUTTON_B, event);
}void CMainFrame::OnMergeEventX(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_X){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_X;}DrawButtonItem(IDC_BUTTON_X);DoFunction(IDC_BUTTON_X, event);
}void CMainFrame::OnMergeEventY(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_Y){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_Y;}DrawButtonItem(IDC_BUTTON_Y);DoFunction(IDC_BUTTON_Y, event);
}void CMainFrame::OnMergeEventLB(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_LEFT_SHOULDER){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_LEFT_SHOULDER;}DrawButtonItem(IDC_BUTTON_LB);DoFunction(IDC_BUTTON_LB, event);
}void CMainFrame::OnMergeEventRB(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_RIGHT_SHOULDER){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_RIGHT_SHOULDER;}DrawButtonItem(IDC_BUTTON_RB);DoFunction(IDC_BUTTON_RB, event);
}void CMainFrame::OnMergeEventLSB(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_LEFT_THUMB){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_LEFT_THUMB;}DrawButtonItem(IDC_BUTTON_LSB);DoFunction(IDC_BUTTON_LSB, event);
}void CMainFrame::OnMergeEventRSB(GAMEPAD_INPUT_EVENT& event)
{if (event.curButtonState.Button & XINPUT_GAMEPAD_RIGHT_THUMB){m_lastState.Gamepad.wButtons |= event.curButtonState.Button & XINPUT_GAMEPAD_RIGHT_THUMB;}DrawButtonItem(IDC_BUTTON_RSB);DoFunction(IDC_BUTTON_RSB, event);
}void CMainFrame::OnMergeEventLT(GAMEPAD_INPUT_EVENT& event)
{if (event.bTrigger >= m_lastState.Gamepad.bLeftTrigger){m_lastState.Gamepad.bLeftTrigger = event.bTrigger;}DrawButtonItem(IDC_BUTTON_LT);if (m_fVibrationLeft){m_Vibration.wLeftMotorSpeed = event.bTrigger * 65536 / 256;::XInputSetState(0, &m_Vibration);}DoFunction(IDC_BUTTON_LT, event);
}void CMainFrame::OnMergeEventRT(GAMEPAD_INPUT_EVENT& event)
{if (event.bTrigger >= m_lastState.Gamepad.bRightTrigger){m_lastState.Gamepad.bRightTrigger = event.bTrigger;}DrawButtonItem(IDC_BUTTON_RT);if (m_fVibrationRight){m_Vibration.wRightMotorSpeed = event.bTrigger * 65536 / 256;::XInputSetState(0, &m_Vibration);}DoFunction(IDC_BUTTON_RT, event);
}void CMainFrame::OnMergeEventLS(GAMEPAD_INPUT_EVENT& event)
{if (event.sAxisX <= m_sThumbLX_Min){m_sThumbLX_Min = event.sAxisX;}if (event.sAxisX >= m_sThumbLX_Max){m_sThumbLX_Max = event.sAxisX;}if (-event.sAxisY <= m_sThumbLY_Min){m_sThumbLY_Min = -event.sAxisY;}if (-event.sAxisY >= m_sThumbLY_Max){m_sThumbLY_Max = -event.sAxisY;}DrawButtonItem(IDC_BUTTON_LEFTSTICK);DrawButtonItem(IDC_BUTTON_LSB);DrawButtonItem(IDC_STATIC_LEFT_STICK_X);DrawButtonItem(IDC_STATIC_LEFT_STICK_Y);DoFunction(IDC_BUTTON_LEFTSTICK, event);
}void CMainFrame::OnMergeEventRS(GAMEPAD_INPUT_EVENT& event)
{if (event.sAxisX <= m_sThumbRX_Min){m_sThumbRX_Min = event.sAxisX;}if (event.sAxisX >= m_sThumbRX_Max){m_sThumbRX_Max = event.sAxisX;}if (-event.sAxisY <= m_sThumbRY_Min){m_sThumbRY_Min = -event.sAxisY;}if (-event.sAxisY >= m_sThumbRY_Max){m_sThumbRY_Max = -event.sAxisY;}DrawButtonItem(IDC_BUTTON_RIGHTSTICK);DrawButtonItem(IDC_BUTTON_RSB);DrawButtonItem(IDC_STATIC_RIGHT_STICK_X);DrawButtonItem(IDC_STATIC_RIGHT_STICK_Y);DoFunction(IDC_BUTTON_RIGHTSTICK, event);
}void CMainFrame::InitList()
{for (int i = 0; i < _countof(g_ModifierName); i++){::SendMessage(m_hModifier, LB_ADDSTRING, 0, (LPARAM)g_ModifierName[i]);}for (int i = 0; i < _countof(g_KeysName); i++){::SendMessage(m_hKeys, LB_ADDSTRING, 0, (LPARAM)g_KeysName[i]);}for (int i = 0; i < _countof(g_MouseName); i++){::SendMessage(m_hMouse, LB_ADDSTRING, 0, (LPARAM)g_MouseName[i]);}
}void CMainFrame::UpdateButtonFunction(WORD wID)
{eButtonFunction eType = eButtonFunction::eNone;::EnableWindow(m_hModifier, false);::EnableWindow(m_hKeys, false);::EnableWindow(m_hMouse, false);if (IDC_RADIO_NONE == wID){eType = eButtonFunction::eNone;}if (IDC_RADIO_KEY == wID){eType = eButtonFunction::eKey;::EnableWindow(m_hModifier, true);::EnableWindow(m_hKeys, true);}if (IDC_RADIO_MOUSE == wID){eType = eButtonFunction::eMouse;::EnableWindow(m_hMouse, true);}if (0 == m_wFocusID){return;}auto itFind = g_ButtonFunctionList.find(m_wFocusID);if (g_ButtonFunctionList.end() != itFind){itFind->second.eType = eType;}
}LRESULT CMainFrame::OnModifierChange(WORD wNotify, WORD wID, HWND hWnd)
{if (0 == m_wFocusID){return TRUE;}auto itFind = g_ButtonFunctionList.find(m_wFocusID);if (itFind != g_ButtonFunctionList.end()){std::vector<int> vModifier;int nIndex = 0;for (const auto& item : g_ModifierName){LRESULT bSel = ::SendMessage(m_hModifier, LB_GETSEL, nIndex, 0);if (bSel){vModifier.push_back(nIndex);}nIndex++;}itFind->second.vModifier = vModifier;}return TRUE;
}LRESULT CMainFrame::OnKeyChange(WORD wNotify, WORD wID, HWND hWnd)
{if (0 == m_wFocusID){return TRUE;}auto itFind = g_ButtonFunctionList.find(m_wFocusID);if (itFind != g_ButtonFunctionList.end()){{std::vector<int> vModifier;int nIndex = 0;for (const auto& item : g_ModifierName){LRESULT bSel = ::SendMessage(m_hModifier, LB_GETSEL, nIndex, 0);if (bSel){vModifier.push_back(nIndex);}nIndex++;}itFind->second.vModifier = vModifier;}{std::vector<int> vKeys;int nIndex = 0;for (const auto& item : g_KeysName){LRESULT bSel = ::SendMessage(m_hKeys, LB_GETSEL, nIndex, 0);if (bSel){vKeys.push_back(nIndex);}nIndex++;}itFind->second.vKeys = vKeys;}}return TRUE;
}LRESULT CMainFrame::OnMouseChange(WORD wNotify, WORD wID, HWND hWnd)
{if (0 == m_wFocusID){return TRUE;}auto itFind = g_ButtonFunctionList.find(m_wFocusID);if (itFind != g_ButtonFunctionList.end()){std::vector<int> vMouse;int nIndex = 0;for (const auto& item : g_MouseName){LRESULT bSel = ::SendMessage(m_hMouse, LB_GETSEL, nIndex, 0);if (bSel){vMouse.push_back(nIndex);}nIndex++;}itFind->second.vMouse = vMouse;}return TRUE;
}void CMainFrame::ShowButtonFunction(WORD wID)
{::EnableWindow(m_hModifier, FALSE);::EnableWindow(m_hKeys, FALSE);::EnableWindow(m_hMouse, FALSE);if (0 == wID){}else{auto itFind = g_ButtonFunctionList.find(wID);if (itFind != g_ButtonFunctionList.end()){CheckButton(IDC_RADIO_NONE, false);CheckButton(IDC_RADIO_KEY, false);CheckButton(IDC_RADIO_MOUSE, false);if (eButtonFunction::eNone == itFind->second.eType){CheckButton(IDC_RADIO_NONE, true);}if (eButtonFunction::eKey == itFind->second.eType){CheckButton(IDC_RADIO_KEY, true);::EnableWindow(m_hModifier, TRUE);::EnableWindow(m_hKeys, TRUE);}if (eButtonFunction::eMouse == itFind->second.eType){CheckButton(IDC_RADIO_MOUSE, true);::EnableWindow(m_hMouse, TRUE);}::SendMessage(m_hModifier, LB_SETSEL, FALSE, -1);for (const auto& item : itFind->second.vModifier){LRESULT bSel = ::SendMessage(m_hModifier, LB_SETSEL, TRUE, item);}::SendMessage(m_hKeys, LB_SETSEL, FALSE, -1);for (const auto& item : itFind->second.vKeys){LRESULT bSel = ::SendMessage(m_hKeys, LB_SETSEL, TRUE, item);}::SendMessage(m_hMouse, LB_SETSEL, FALSE, -1);for (const auto& item : itFind->second.vMouse){LRESULT bSel = ::SendMessage(m_hMouse, LB_SETSEL, TRUE, item);}}else{BUTTON_FUNCTION_INFO info;info.eType = eButtonFunction::eNone;g_ButtonFunctionList.insert(std::make_pair(wID, info));::SendMessage(m_hKeys, LB_SETSEL, FALSE, -1);::SendMessage(m_hMouse, LB_SETSEL, FALSE, -1);::EnableWindow(m_hModifier, FALSE);::EnableWindow(m_hKeys, FALSE);::EnableWindow(m_hMouse, FALSE);CheckButton(IDC_RADIO_NONE, true);CheckButton(IDC_RADIO_KEY, false);CheckButton(IDC_RADIO_MOUSE, false);}}
}void CMainFrame::SaveConfig()
{WORD wIDs[] = {IDC_BUTTON_LEFTSTICK        ,IDC_BUTTON_RIGHTSTICK       ,IDC_BUTTON_DPAD_UP          ,IDC_BUTTON_DPAD_DOWN        ,IDC_BUTTON_DPAD_LEFT        ,IDC_BUTTON_DPAD_RIGHT       ,IDC_BUTTON_Y                ,IDC_BUTTON_A                ,IDC_BUTTON_X                ,IDC_BUTTON_B                ,IDC_BUTTON_BACK             ,IDC_BUTTON_START            ,IDC_BUTTON_GUIDE            ,IDC_BUTTON_LB               ,IDC_BUTTON_RB               ,IDC_BUTTON_LT               ,IDC_BUTTON_RT               ,};for (auto item : wIDs){auto itFind = g_ButtonFunctionList.find(item);if (itFind != g_ButtonFunctionList.end()){DWORD wID = itFind->first;_tstring strModifier;_tstring strKey;_tstring strMouse;for (auto item : itFind->second.vModifier){strModifier += CStrUtils::Format(_T("%d,"), item);}for (auto item : itFind->second.vKeys){strKey += CStrUtils::Format(_T("%d,"), item);}for (auto item : itFind->second.vMouse){strMouse += CStrUtils::Format(_T("%d,"), item);}m_config.SetNumber(CStrUtils::Format(_T("%04X"), wID),_T("type"), itFind->second.eType);m_config.SetString(CStrUtils::Format(_T("%04X"), wID),_T("modifier"), strModifier.c_str());m_config.SetString(CStrUtils::Format(_T("%04X"), wID),_T("keys"), strKey.c_str());m_config.SetString(CStrUtils::Format(_T("%04X"), wID),_T("mouse"), strMouse.c_str());}}
}void CMainFrame::LoadConfig()
{WORD wIDs[] = {IDC_BUTTON_LEFTSTICK        ,IDC_BUTTON_RIGHTSTICK       ,IDC_BUTTON_DPAD_UP          ,IDC_BUTTON_DPAD_DOWN        ,IDC_BUTTON_DPAD_LEFT        ,IDC_BUTTON_DPAD_RIGHT       ,IDC_BUTTON_Y                ,IDC_BUTTON_A                ,IDC_BUTTON_X                ,IDC_BUTTON_B                ,IDC_BUTTON_BACK             ,IDC_BUTTON_START            ,IDC_BUTTON_GUIDE            ,IDC_BUTTON_LB               ,IDC_BUTTON_RB               ,IDC_BUTTON_LT               ,IDC_BUTTON_RT               ,};for (auto item : wIDs){_tstring strModifier = m_config.GetString(CStrUtils::Format(_T("%04X"), item), _T("modifier"));_tstring strKey = m_config.GetString(CStrUtils::Format(_T("%04X"), item), _T("keys"));_tstring strMouse = m_config.GetString(CStrUtils::Format(_T("%04X"), item), _T("mouse"));std::vector<_tstring> vModifier = CStrUtils::SplitStr(strModifier, _T(","));std::vector<_tstring> vKeys = CStrUtils::SplitStr(strKey, _T(","));std::vector<_tstring> vMouse = CStrUtils::SplitStr(strMouse, _T(","));BUTTON_FUNCTION_INFO info;info.eType = (eButtonFunction)m_config.GetNumber(CStrUtils::Format(_T("%04X"), item),_T("type"), eButtonFunction::eNone);for (const auto& item : vModifier){info.vModifier.push_back(_tcstol(item.c_str(), NULL, 10));}for (const auto& item : vKeys){info.vKeys.push_back(_tcstol(item.c_str(), NULL, 10));}for (const auto& item : vMouse){info.vMouse.push_back(_tcstol(item.c_str(), NULL, 10));}g_ButtonFunctionList.insert(std::make_pair(item, info));}
}void CMainFrame::DoMouseMove(int x, int y)
{enum eDirectionType{eUp = 1,eDown = 2,eLeft = 4,eRight = 8,};int nStickType = 0;nStickType |= y > MOUSE_MOVE_THRESHOLD ? eUp : 0;nStickType |= y < -MOUSE_MOVE_THRESHOLD ? eDown : 0;nStickType |= x < -MOUSE_MOVE_THRESHOLD ? eLeft : 0;nStickType |= x > MOUSE_MOVE_THRESHOLD ? eRight : 0;float left = 0;float up = 0;float right = 0;float down = 0;int limit = (double)(32767 - MOUSE_MOVE_THRESHOLD);int speed_level = 10;int speed = limit / speed_level;int ThumbLX = x;int ThumbLY = y;if (ThumbLX < 0){if (ThumbLX < -MOUSE_MOVE_THRESHOLD){ThumbLX += MOUSE_MOVE_THRESHOLD;ThumbLX -= speed;}else{ThumbLX = 0;}}if (ThumbLX > 0){if (ThumbLX > MOUSE_MOVE_THRESHOLD){ThumbLX -= MOUSE_MOVE_THRESHOLD;ThumbLX += speed;}else{ThumbLX = 0;}}if (ThumbLY < 0){if (ThumbLY < -MOUSE_MOVE_THRESHOLD){ThumbLY += MOUSE_MOVE_THRESHOLD;ThumbLY -= speed;}else{ThumbLY = 0;}}if (ThumbLY > 0){if (ThumbLY > MOUSE_MOVE_THRESHOLD){ThumbLY -= MOUSE_MOVE_THRESHOLD;ThumbLY += speed;}else{ThumbLY = 0;}}if (ThumbLX < 0){left = abs(ThumbLX / speed);}if (ThumbLX > 0){right = abs(ThumbLX / speed);}if (ThumbLY < 0){down = abs(ThumbLY / speed);}if (ThumbLY > 0){up = abs(ThumbLY / speed);}float dx = (right - left);float dy = (down - up);CInputUtils::MouseMove(dx, dy, false);
}void CMainFrame::DoMouseWheel(int x, int y)
{float left = 0;float up = 0;float right = 0;float down = 0;if (x < -MOUSE_SRCOLL_THRESHOLD){left = 1;}if (x > MOUSE_SRCOLL_THRESHOLD){right = 1;}if (y < -MOUSE_SRCOLL_THRESHOLD){down = 1;}if (y > MOUSE_SRCOLL_THRESHOLD){up = 1;}static float last_dx = 0;static float last_dy = 0;float dx = (right - left);float dy = (down - up);bool bHoriz = false;if (abs(dx) > abs(dy)){bHoriz = true;}last_dx = dx;last_dy = dy;if (0 != dx || 0 != dy){CInputUtils::MouseWheel(-dy, dx);}
}void CMainFrame::DoFunction(WORD wID, GAMEPAD_INPUT_EVENT& event)
{auto itFInd = g_ButtonFunctionList.find(wID);if (itFInd != g_ButtonFunctionList.end()){if (IDC_BUTTON_LEFTSTICK == wID && eButtonFunction::eMouse == itFInd->second.eType){bool fHasMouseMove = false;bool fHasMouseWheel = false;for (const auto& item: itFInd->second.vMouse){if (item == eMouseType::eMouseMove){fHasMouseMove = true;}if (item == eMouseType::eMouseWheel){fHasMouseWheel = true;}}if (fHasMouseMove){DoMouseMove(m_CurXInputStateMerge.Gamepad.sThumbLX, m_CurXInputStateMerge.Gamepad.sThumbLY);}if (fHasMouseWheel){DoMouseWheel(m_CurXInputStateMerge.Gamepad.sThumbLX, m_CurXInputStateMerge.Gamepad.sThumbLY);}return;}if (IDC_BUTTON_RIGHTSTICK == wID && eButtonFunction::eMouse == itFInd->second.eType){bool fHasMouseMove = false;bool fHasMouseWheel = false;for (const auto& item: itFInd->second.vMouse){if (item == eMouseType::eMouseMove){fHasMouseMove = true;}if (item == eMouseType::eMouseWheel){fHasMouseWheel = true;}}if (fHasMouseMove){DoMouseMove(m_CurXInputStateMerge.Gamepad.sThumbRX, m_CurXInputStateMerge.Gamepad.sThumbRY);}if (fHasMouseWheel){DoMouseWheel(m_CurXInputStateMerge.Gamepad.sThumbRX, m_CurXInputStateMerge.Gamepad.sThumbRY);}return;}if (eButtonFunction::eMouse == itFInd->second.eType){bool fHasMouseLeft = false;bool fHasMouseRight = false;bool fHasMouseMiddle = false;for (const auto& item: itFInd->second.vMouse){if (item == eMouseType::eMouseLeft){fHasMouseLeft = true;}if (item == eMouseType::eMouseRight){fHasMouseRight = true;}if (item == eMouseType::eMouseMiddle){fHasMouseMiddle = true;}}if (fHasMouseLeft){CInputUtils::MouseKey(eInputMouseButton::eMButton_Left, event.curButtonEvent.Down, event.curButtonEvent.Up);}if (fHasMouseRight){CInputUtils::MouseKey(eInputMouseButton::eMButton_Right, event.curButtonEvent.Down, event.curButtonEvent.Up);}if (fHasMouseMiddle){CInputUtils::MouseKey(eInputMouseButton::eMButton_Middle, event.curButtonEvent.Down, event.curButtonEvent.Up);}}if (eButtonFunction::eKey == itFInd->second.eType){if (event.curButtonEvent.Down){for (const auto& item : itFInd->second.vModifier){CInputUtils::KeyboardByName(g_ModifierName[item], event.curButtonEvent.Down, event.curButtonEvent.Up);}for (const auto& item : itFInd->second.vKeys){CInputUtils::KeyboardByName(g_KeysName[item], event.curButtonEvent.Down, event.curButtonEvent.Up);}}if (event.curButtonEvent.Hold){for (const auto& item : itFInd->second.vKeys){CInputUtils::KeyboardByName(g_KeysName[item], event.curButtonEvent.uTime > 500, event.curButtonEvent.Up);}}if (event.curButtonEvent.Up){for (const auto& item : itFInd->second.vKeys){CInputUtils::KeyboardByName(g_KeysName[item], event.curButtonEvent.Down, event.curButtonEvent.Up);}for (const auto& item : itFInd->second.vModifier){CInputUtils::KeyboardByName(g_ModifierName[item], event.curButtonEvent.Down, event.curButtonEvent.Up);}}}}
}

资源相关

resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 XboxAssistant.rc 使用
//
#define IDI_ICON                        102
#define IDD_DIALOG_MAIN                 103
#define IDR_ACCELERATOR                 105
#define IDC_BUTTON_LEFTSTICK            1001
#define IDC_BUTTON_RIGHTSTICK           1002
#define IDC_BUTTON_DPAD_UP              1003
#define IDC_BUTTON_DPAD_DOWN            1004
#define IDC_BUTTON_DPAD_LEFT            1005
#define IDC_BUTTON_DPAD_RIGHT           1006
#define IDC_BUTTON_Y                    1007
#define IDC_BUTTON_A                    1008
#define IDC_BUTTON_X                    1009
#define IDC_BUTTON_B                    1010
#define IDC_BUTTON_BACK                 1011
#define IDC_BUTTON_START                1012
#define IDC_BUTTON_GUIDE                1013
#define IDC_BUTTON_LB                   1014
#define IDC_BUTTON_RB                   1015
#define IDC_BUTTON_LT                   1017
#define IDC_BUTTON_RT                   1018
#define IDC_STATIC_LEFT_STICK_X         1019
#define IDC_STATIC_RIGHT_STICK_Y        1020
#define IDC_BUTTON_RESET                1021
#define IDC_CHECK_VIBRATION_LEFT        1022
#define IDC_CHECK_VIBRATION_RIGHT       1023
#define IDC_STATIC_LEFT_STICK_Y         1024
#define IDC_STATIC_RIGHT_STICK_X        1025
#define IDC_RADIO_KEY                   1028
#define IDC_LIST_KEYS                   1029
#define IDC_LIST_MOUSE                  1030
#define IDC_RADIO_MOUSE                 1031
#define IDC_RADIO_NONE                  1032
#define IDC_LIST_MODIFIER               1033
#define IDC_BUTTON_LSB                   1034
#define IDC_BUTTON_RSB2                  1035
#define IDC_BUTTON_RSB                   1035// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        106
#define _APS_NEXT_COMMAND_VALUE         40003
#define _APS_NEXT_CONTROL_VALUE         1035
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

XboxAssistant.rc 

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"#define APSTUDIO_READONLY_SYMBOLS
/
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"/
#undef APSTUDIO_READONLY_SYMBOLS/
// 中文(简体,中国) resources#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED#ifdef APSTUDIO_INVOKED
/
//
// TEXTINCLUDE
//1 TEXTINCLUDE 
BEGIN"resource.h\0"
END2 TEXTINCLUDE 
BEGIN"#include ""winres.h""\r\n""\0"
END3 TEXTINCLUDE 
BEGIN"\r\n""\0"
END#endif    // APSTUDIO_INVOKED/
//
// Icon
//// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON                ICON                    "icon.ico"/
//
// Dialog
//IDD_DIALOG_MAIN DIALOGEX 0, 0, 442, 243
STYLE DS_SETFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
CAPTION "XboxAssistant"
FONT 12, "楷体", 700, 0, 0x86
BEGINPUSHBUTTON      "",IDC_BUTTON_LSB,50,81,8,8,NOT WS_VISIBLEPUSHBUTTON      "",IDC_BUTTON_RSB,196,161,8,8,NOT WS_VISIBLECONTROL         "LT",IDC_BUTTON_LT,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,7,7,19,183CONTROL         "LB",IDC_BUTTON_LB,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,29,7,33,14CONTROL         "RB",IDC_BUTTON_RB,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,192,7,33,14CONTROL         "RT",IDC_BUTTON_RT,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,230,7,19,183LTEXT           "X: -32767",IDC_STATIC_LEFT_STICK_X,29,31,50,8,NOT WS_VISIBLELTEXT           "Y: -32767",IDC_STATIC_LEFT_STICK_Y,29,44,50,8,NOT WS_VISIBLECONTROL         "",IDC_BUTTON_LEFTSTICK,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,29,60,50,50CONTROL         "Guide",IDC_BUTTON_GUIDE,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,119,48,24,24CONTROL         "",IDC_BUTTON_BACK,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,100,73,19,18CONTROL         "",IDC_BUTTON_START,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,144,73,19,18CONTROL         "Y",IDC_BUTTON_Y,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,193,33,16,16CONTROL         "X",IDC_BUTTON_X,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,178,48,16,16CONTROL         "A",IDC_BUTTON_A,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,193,63,16,16CONTROL         "B",IDC_BUTTON_B,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,209,48,16,16CONTROL         "Up",IDC_BUTTON_DPAD_UP,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,47,134,19,18CONTROL         "Left",IDC_BUTTON_DPAD_LEFT,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,29,153,19,18CONTROL         "Down",IDC_BUTTON_DPAD_DOWN,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,47,172,19,18CONTROL         "Right",IDC_BUTTON_DPAD_RIGHT,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,65,153,19,18LTEXT           "X: -32767",IDC_STATIC_RIGHT_STICK_X,175,116,50,8,NOT WS_VISIBLELTEXT           "Y: -32767",IDC_STATIC_RIGHT_STICK_Y,175,129,50,8,NOT WS_VISIBLECONTROL         "",IDC_BUTTON_RIGHTSTICK,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,175,140,50,50CONTROL         "Vibration",IDC_CHECK_VIBRATION_LEFT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,194,52,10PUSHBUTTON      "Reset",IDC_BUTTON_RESET,100,212,70,25CONTROL         "Vibration",IDC_CHECK_VIBRATION_RIGHT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,197,194,52,10CONTROL         "None",IDC_RADIO_NONE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,259,12,32,10CONTROL         "Keyboard",IDC_RADIO_KEY,"Button",BS_AUTORADIOBUTTON,358,12,48,10CONTROL         "Mouse",IDC_RADIO_MOUSE,"Button",BS_AUTORADIOBUTTON,296,12,36,10LISTBOX         IDC_LIST_KEYS,380,32,52,203,LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOPLISTBOX         IDC_LIST_MOUSE,260,32,52,203,LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOPLISTBOX         IDC_LIST_MODIFIER,326,32,52,203,LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
END/
//
// DESIGNINFO
//#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGINIDD_DIALOG_MAIN, DIALOGBEGINBOTTOMMARGIN, 242END
END
#endif    // APSTUDIO_INVOKED/
//
// AFX_DIALOG_LAYOUT
//IDD_DIALOG_MAIN AFX_DIALOG_LAYOUT
BEGIN0
END/
//
// Accelerator
//IDR_ACCELERATOR ACCELERATORS
BEGIN"R",            IDC_BUTTON_RESET,       VIRTKEY, CONTROL, NOINVERT
END#endif    // 中文(简体,中国) resources
/#ifndef APSTUDIO_INVOKED
/
//
// Generated from the TEXTINCLUDE 3 resource.
///
#endif    // not APSTUDIO_INVOKED

工程结构

运行效果

源码仓库

FlameCyclone/XboxAssistantEx (gitee.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/423142.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

灰色关联度/模糊聚类/最邻近算法KNN/随机森林RF/极限学习机

一、灰色关联度 简介&#xff1a; 对于两个系统之间的因素&#xff0c;其随时间或不同对象而变化的关联性大小的量度&#xff0c;称为关联度。在系统发展过程中&#xff0c;若两个因素变化的趋势具有一致性&#xff0c;即同步变化程度较高&#xff0c;即可谓二者关联程度较高…

【C++】认识C++(前言)

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:C_小米里的大麦的博客-CSDN博客 &#x1f381;代码托管:C: 探索C编程精髓&#xff0c;打造高效代码仓库 (gitee.com) ⚙️操作环境:Visual Studio 2022 目录 一、本节概述 二、什么是C 三、C发展史 四…

Python画笔案例-044 绘制四米围方

1、绘制 四米围方 通过 python 的turtle 库绘制 四米围方&#xff0c;如下图&#xff1a; 2、实现代码 绘制 四米围方&#xff0c;以下为实现代码&#xff1a; """四米围方.py """ import turtledef draw_mi():"""画米字图形&qu…

关于武汉芯景科技有限公司的IIC缓冲器芯片XJ4307开发指南(兼容LTC4307)

一、芯片引脚介绍 1.芯片引脚 2.引脚描述 二、系统结构图 三、功能描述 1.总线超时&#xff0c;自动断开连接 当 SDAOUT 或 SCLOUT 为低电平时&#xff0c;将启动内部定时器。定时器仅在相应输入变为高电平时重置。如果在 30ms &#xff08;典型值&#xff09; 内没有变为高…

开展文化创新与传承 全球老子圣像评选启动

9月11日&#xff0c;在刚见证了中华社会文化发展基金会老子文化公益基金成立发布会盛典的中华文化园&#xff0c;又迎来了中华社会文化发展基金会领导的亲临指导。本次指导由中华社会文化发展基金会执行副秘书长蒋晔带队&#xff0c;魏欣主任和高凯主任同行&#xff0c;共同考察…

JMeter脚本开发

环境部署 Ubuntu系统 切换到root用户 sudo su 安装上传下载的命令 apt install lrzsz 切换文件目录 cd / 创建文件目录 mkdir java 切换到Java文件夹下 cd java 输入rz回车 选择jdk Linux文件上传 解压安装包 tar -zxvf jdktab键 新建数据库 运行sql文件 选择sql文件即…

微信小程序原生支持TS、LESS、SASS能力探究

文章目录 原生支持开始使用旧项目新建项目TS声明文件更新 功能说明less 使用全局变量sass 使用全局变量 可以参考原文 在之前开发小程序中&#xff0c;无法使用 less/sass 等 css 预编译语言&#xff0c;也无法使用 TS 进行开发&#xff0c;但在最新的编辑器版本中&#xff0c…

Running setup.py install for wxPython did not run successfully.

Running setup.py install for wxPython did not run successfully. 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开…

【Prompt Enhancer】如何优化prompt的内容

背景 在使用LLM的时候&#xff0c;提示词的好坏对模型的输出质量影响很大&#xff0c;提示词又是一个复杂工程&#xff0c;要写出优秀的提示词&#xff0c;需要丰富的经验。正因如此&#xff0c;各类Agent平台都会有自己的提示词增强功能&#xff0c;帮助用户编写提示词。 最…

java项目之基于Spring Boot智能无人仓库管理源码(springboot+vue)

项目简介 智能无人仓库管理实现了以下功能&#xff1a; 基于Spring Boot智能无人仓库管理的主要使用者分为&#xff1a; 管理员的功能有&#xff1a;员工信息的查询管理&#xff0c;可以删除员工信息、修改员工信息、新增员工信息 &#x1f495;&#x1f495;作者&#xff1a…

WebGL系列教程六(纹理映射与立方体贴图)

目录 1 前言2 思考题3 纹理映射介绍4 怎么映射&#xff1f;5 开始绘制5.1 声明顶点着色器和片元着色器5.2 修改顶点的颜色为纹理坐标5.3 指定顶点位置和纹理坐标的值5.4 获取图片成功后进行绘制5.5 效果5.6 完整代码 6 总结 1 前言 上一讲我们讲了如何使用索引绘制彩色立方体&a…

基于SpringBoot+Vue+MySQL的画师约稿平台系统

系统展示 用户界面 画师界面 管理员界面 系统背景 基于SpringBootVueMySQL的画师约稿平台系统的背景&#xff0c;主要源于数字艺术行业的快速发展与画师、客户双方需求的日益增长。在传统的约稿方式中&#xff0c;往往存在沟通效率低下、交易过程不透明等问题&#xff0c;这限制…

C++---string类常见接口

介绍 string类详情>>>https://cplusplus.com/reference/string/string/?kwstring 1. string是表示字符串的字符串类&#xff08;感觉就像一个动态的字符数组&#xff09; 2. 该类的接口与常规容器的接口基本相同&#xff0c;再添加了一些专门用来操作string的常规操作…

Cloudflare Pages 部署 Next.js 应用教程

Cloudflare Pages 部署 Next.js 应用教程 本教程将指导你如何将现有的 Next.js 应用部署到 Cloudflare Pages。 准备工作 安装部署依赖 首先,安装 cloudflare/next-on-pages: npm install --save-dev cloudflare/next-on-pages添加 wrangler.toml 配置文件 在项目根目录创建 …

力扣139-单词拆分(Java详细题解)

题目链接&#xff1a;139. 单词拆分 - 力扣&#xff08;LeetCode&#xff09; 前情提要&#xff1a; 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 最近刚学完背包&#xff0c;所以现在的题解都是以背包问题为基础再来写的。 如果大家不懂背包问题的话&#…

【LoRA】浅谈大模型微调之LoRA技术

在当今的信息时代中&#xff0c;大型语言模型扮演着至关重要的角色&#xff0c;它们在自然语言处理任务中展现出强大的能力。LoRA&#xff0c;英文全称Low-Rank Adaptation of Large Language Models&#xff0c;是一种用于微调大型语言模型的低秩适应技术&#xff0c;由微软的…

Java Enterprise System 体系结构

本章概述了 Java Enterprise System 部署所基于的体系结构概念。 章中描述了一个框架,在此框架内从三维角度对 Java Enterprise System部署体系结构进行了分析,它们分别是:逻辑层、基础结构服务级别和服务质量。这三维在下图中以图解形式显示为正交坐标轴,它们有助于在体系…

jmeter之TPS计算公式

需求&#xff1a; 如何确定环境当中的TPS指标 PV:&#xff08;Page View&#xff09;即页面访问量&#xff0c;每打开一次页面PV计数1&#xff0c;刷新页面也是。PV只统计页面访问次 数。 UV(Unique Visitor),唯一访问用户数&#xff0c;用来衡量真实访问网站的用户数量。 一般…

大模型的第一个杀手级应用场景出来了

大家终于都意识到大模型首先改变的是软件行业自己&#xff0c;而软件的根基是代码生成。代码生成第一波就是AI辅助开发&#xff0c;这个会是大模型第一个杀手级应用。大家苦苦逼问自己的大模型杀手级应用&#xff0c;为什么会是辅助编程&#xff0c;这里说下什么&#xff1a; 必…

vscode 使用git bash,路径分隔符缺少问题

window使用bash --login -i 使用bash时候&#xff0c;在系统自带的terminal里面进入&#xff0c;测试conda可以正常输出&#xff0c;但是在vscode里面输入conda发现有问题 bash: C:\Users\marswennaconda3\Scripts: No such file or directory实际路径应该要为 C:\Users\mars…