编写XBOX控制器实现鼠标键盘输入
1.核心部分, XINPUT输入封装
XInput封装https://mp.csdn.net/mp_blog/creation/editor/1420701282.对话框窗口编写
Win32 对话框封装-CSDN博客https://blog.csdn.net/Flame_Cyclone/article/details/142110008?spm=1001.2014.3001.5501
3.使用到的其他封装
字符串编码转换与常用操作(Win32,C++)_windows字符串编码转换-CSDN博客https://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;
#endif
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.SetAxisThreshold(4096, 4096);
#if 0
obj.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
);
}
);
#endif
obj.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; // 内存DC
HBITMAP 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"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 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
BEGIN
PUSHBUTTON "",IDC_BUTTON_LSB,50,81,8,8,NOT WS_VISIBLE
PUSHBUTTON "",IDC_BUTTON_RSB,196,161,8,8,NOT WS_VISIBLE
CONTROL "LT",IDC_BUTTON_LT,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,7,7,19,183
CONTROL "LB",IDC_BUTTON_LB,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,29,7,33,14
CONTROL "RB",IDC_BUTTON_RB,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,192,7,33,14
CONTROL "RT",IDC_BUTTON_RT,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,230,7,19,183
LTEXT "X: -32767",IDC_STATIC_LEFT_STICK_X,29,31,50,8,NOT WS_VISIBLE
LTEXT "Y: -32767",IDC_STATIC_LEFT_STICK_Y,29,44,50,8,NOT WS_VISIBLE
CONTROL "",IDC_BUTTON_LEFTSTICK,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,29,60,50,50
CONTROL "Guide",IDC_BUTTON_GUIDE,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,119,48,24,24
CONTROL "",IDC_BUTTON_BACK,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,100,73,19,18
CONTROL "",IDC_BUTTON_START,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,144,73,19,18
CONTROL "Y",IDC_BUTTON_Y,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,193,33,16,16
CONTROL "X",IDC_BUTTON_X,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,178,48,16,16
CONTROL "A",IDC_BUTTON_A,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,193,63,16,16
CONTROL "B",IDC_BUTTON_B,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,209,48,16,16
CONTROL "Up",IDC_BUTTON_DPAD_UP,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,47,134,19,18
CONTROL "Left",IDC_BUTTON_DPAD_LEFT,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,29,153,19,18
CONTROL "Down",IDC_BUTTON_DPAD_DOWN,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,47,172,19,18
CONTROL "Right",IDC_BUTTON_DPAD_RIGHT,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,65,153,19,18
LTEXT "X: -32767",IDC_STATIC_RIGHT_STICK_X,175,116,50,8,NOT WS_VISIBLE
LTEXT "Y: -32767",IDC_STATIC_RIGHT_STICK_Y,175,129,50,8,NOT WS_VISIBLE
CONTROL "",IDC_BUTTON_RIGHTSTICK,"Button",BS_OWNERDRAW | NOT WS_VISIBLE | WS_TABSTOP,175,140,50,50
CONTROL "Vibration",IDC_CHECK_VIBRATION_LEFT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,194,52,10
PUSHBUTTON "Reset",IDC_BUTTON_RESET,100,212,70,25
CONTROL "Vibration",IDC_CHECK_VIBRATION_RIGHT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,197,194,52,10
CONTROL "None",IDC_RADIO_NONE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,259,12,32,10
CONTROL "Keyboard",IDC_RADIO_KEY,"Button",BS_AUTORADIOBUTTON,358,12,48,10
CONTROL "Mouse",IDC_RADIO_MOUSE,"Button",BS_AUTORADIOBUTTON,296,12,36,10
LISTBOX IDC_LIST_KEYS,380,32,52,203,LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
LISTBOX IDC_LIST_MOUSE,260,32,52,203,LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
LISTBOX IDC_LIST_MODIFIER,326,32,52,203,LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
END
/
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DIALOG_MAIN, DIALOG
BEGIN
BOTTOMMARGIN, 242
END
END
#endif // APSTUDIO_INVOKED
/
//
// AFX_DIALOG_LAYOUT
//
IDD_DIALOG_MAIN AFX_DIALOG_LAYOUT
BEGIN
0
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)