CInputUtils.h
using _tstring = std::wstring;
using _tstring = std::string;
typedef struct _KBDATA_INFO KBDATA_INFO;
typedef struct _KBDATA_INFO {
_KBDATA_INFO() :vkCode(0), scanCode(0), flags(0) {};
_KBDATA_INFO(WORD vk, WORD sc, DWORD f) : vkCode(vk), scanCode(sc), flags(f) {};
_KBDATA_INFO(const _KBDATA_INFO& r) :vkCode(r.vkCode), scanCode(r.scanCode), flags(r.flags) {}
bool operator == (const _KBDATA_INFO& r) const
return (this->scanCode == r.scanCode) && (this->flags & 0x01) == (r.flags & 0x01);
bool operator != (const _KBDATA_INFO& r) const
bool operator < (const _KBDATA_INFO& r) const
if (this->scanCode != r.scanCode) return this->scanCode < r.scanCode;
return (this->flags & 0x01) < (r.flags & 0x01);
void operator=(const _KBDATA_INFO& r)
this->scanCode = r.scanCode;
} KBDATA_INFO, FAR* LPKBDATA_INFO, * PKBDATA_INFO;
static bool Keyboard(WORD wVk, WORD wScan, bool bExtended = false, bool bDown = true, bool bUp = true, bool bScan = false);
static bool Keyboard(_tstring strKey, bool bDown = true, bool bUp = true);
static bool KeyboardChar(TCHAR ch);
static bool KeyboardText(_tstring strText);
static bool MouseMove(LONG x, LONG y, bool bAbsolute = true);
static bool MouseKey(bool bLeft, bool bRight, bool bMiddle, bool bDown = true, bool bUp = true);
static bool MouseWheelForward(LONG nSpeed = 1);
static bool MouseWheelBackward(LONG nSpeed = 1);
static std::map<_tstring, KBDATA_INFO> m_KeyMap;
static std::map m_UsbKeyMap;

CInputUtils.cpp
std::map<_tstring, KBDATA_INFO> CInputUtils::m_KeyMap =
{ _T("Esc"), KBDATA_INFO(0x1B, 0x01, 0)},
{ _T("F1"), KBDATA_INFO(0x70, 0x3B, 0)},
{ _T("F2"), KBDATA_INFO(0x71, 0x3C, 0)},
{ _T("F3"), KBDATA_INFO(0x72, 0x3D, 0)},
{ _T("F4"), KBDATA_INFO(0x73, 0x3E, 0)},
{ _T("F5"), KBDATA_INFO(0x74, 0x3F, 0)},
{ _T("F6"), KBDATA_INFO(0x75, 0x40, 0)},
{ _T("F7"), KBDATA_INFO(0x76, 0x41, 0)},
{ _T("F8"), KBDATA_INFO(0x77, 0x42, 0)},
{ _T("F9"), KBDATA_INFO(0x78, 0x43, 0)},
{ _T("F10"), KBDATA_INFO(0x79, 0x44, 0)},
{ _T("F11"), KBDATA_INFO(0x7A, 0x57, 0)},
{ _T("F12"), KBDATA_INFO(0x7B, 0x58, 0)},
{ _T("F15"), KBDATA_INFO(0x7E, 0x66, 0)},
{ _T("F16"), KBDATA_INFO(0x7F, 0x67, 0)},
{ _T("F17"), KBDATA_INFO(0x80, 0x68, 0)},
{ _T("`"), KBDATA_INFO(0xC0, 0x29, 0)},
{ _T("1"), KBDATA_INFO(0x31, 0x02, 0)},
{ _T("2"), KBDATA_INFO(0x32, 0x03, 0)},
{ _T("3"), KBDATA_INFO(0x33, 0x04, 0)},
{ _T("4"), KBDATA_INFO(0x34, 0x05, 0)},
{ _T("5"), KBDATA_INFO(0x35, 0x06, 0)},
{ _T("6"), KBDATA_INFO(0x36, 0x07, 0)},
{ _T("7"), KBDATA_INFO(0x37, 0x08, 0)},
{ _T("8"), KBDATA_INFO(0x38, 0x09, 0)},
{ _T("9"), KBDATA_INFO(0x39, 0x0A, 0)},
{ _T("0"), KBDATA_INFO(0x30, 0x0B, 0)},
{ _T("-"), KBDATA_INFO(0xBD, 0x0C, 0)},
{ _T("="), KBDATA_INFO(0xBB, 0x0D, 0)},
{ _T("Backspace"), KBDATA_INFO(0x08, 0x0E, 0)},
{ _T("LCtrl"), KBDATA_INFO(0xA2, 0x1D, 0)},
{ _T("RCtrl"), KBDATA_INFO(0xA3, 0x1D, 1)},
{ _T("LAlt"), KBDATA_INFO(0xA4, 0x38, 0)},
{ _T("RAlt"), KBDATA_INFO(0xA5, 0x38, 1)},
{ _T("LWin"), KBDATA_INFO(0x5B, 0x5B, 1)},
{ _T("RWin"), KBDATA_INFO(0x5C, 0x5C, 1)},
{ _T("LShift"), KBDATA_INFO(0xA0, 0x2A, 0)},
{ _T("RShift"), KBDATA_INFO(0xA1, 0x36, 1)},
{ _T("Appcation"), KBDATA_INFO(0x5D, 0x5D, 1)},
{ _T("Tab"), KBDATA_INFO(0x09, 0x0F, 0)},
{ _T("Space"), KBDATA_INFO(0x20, 0x39, 0)},
{ _T("Enter"), KBDATA_INFO(0x0d, 0x1C, 0)},
{ _T("["), KBDATA_INFO(0xDB, 0x1A, 0)},
{ _T("]"), KBDATA_INFO(0xDD, 0x1B, 0)},
{ _T("\\"), KBDATA_INFO(0xDC, 0x2B, 0)},
{ _T(";"), KBDATA_INFO(0xBA, 0x27, 0)},
{ _T("\'"), KBDATA_INFO(0xDE, 0x28, 0)},
{ _T(","), KBDATA_INFO(0xBC, 0x33, 0)},
{ _T("."), KBDATA_INFO(0xBE, 0x34, 0)},
{ _T("/"), KBDATA_INFO(0xBF, 0x35, 0)},
{ _T("A"), KBDATA_INFO('A', 0x1E, 0)},
{ _T("B"), KBDATA_INFO('B', 0x30, 0)},
{ _T("C"), KBDATA_INFO('C', 0x2E, 0)},
{ _T("D"), KBDATA_INFO('D', 0x20, 0)},
{ _T("E"), KBDATA_INFO('E', 0x12, 0)},
{ _T("F"), KBDATA_INFO('F', 0x21, 0)},
{ _T("G"), KBDATA_INFO('G', 0x22, 0)},
{ _T("H"), KBDATA_INFO('H', 0x23, 0)},
{ _T("I"), KBDATA_INFO('I', 0x17, 0)},
{ _T("J"), KBDATA_INFO('J', 0x24, 0)},
{ _T("K"), KBDATA_INFO('K', 0x25, 0)},
{ _T("L"), KBDATA_INFO('L', 0x26, 0)},
{ _T("M"), KBDATA_INFO('M', 0x32, 0)},
{ _T("N"), KBDATA_INFO('N', 0x31, 0)},
{ _T("O"), KBDATA_INFO('O', 0x18, 0)},
{ _T("P"), KBDATA_INFO('P', 0x19, 0)},
{ _T("Q"), KBDATA_INFO('Q', 0x10, 0)},
{ _T("R"), KBDATA_INFO('R', 0x13, 0)},
{ _T("S"), KBDATA_INFO('S', 0x1F, 0)},
{ _T("T"), KBDATA_INFO('T', 0x14, 0)},
{ _T("U"), KBDATA_INFO('U', 0x16, 0)},
{ _T("V"), KBDATA_INFO('V', 0x2F, 0)},
{ _T("W"), KBDATA_INFO('W', 0x11, 0)},
{ _T("X"), KBDATA_INFO('X', 0x2D, 0)},
{ _T("Y"), KBDATA_INFO('Y', 0x15, 0)},
{ _T("Z"), KBDATA_INFO('Z', 0x2C, 0)},
{ _T("Up"), KBDATA_INFO(0x26, 0x48, 1)},
{ _T("Down"), KBDATA_INFO(0x28, 0x50, 1)},
{ _T("Left"), KBDATA_INFO(0x25, 0x4B, 1)},
{ _T("Right"), KBDATA_INFO(0x27, 0x4D, 1)},
{ _T("Num Up"), KBDATA_INFO(0x26, 0x48, 0)},
{ _T("Num Down"), KBDATA_INFO(0x28, 0x50, 0)},
{ _T("Num Left"), KBDATA_INFO(0x25, 0x4B, 0)},
{ _T("Num Right"), KBDATA_INFO(0x27, 0x4D, 0)},
{ _T("Insert"), KBDATA_INFO(0x2d, 0x52, 1)},
{ _T("Home"), KBDATA_INFO(0x24, 0x47, 1)},
{ _T("Page Up"), KBDATA_INFO(0x21, 0x49, 1)},
{ _T("Delete"), KBDATA_INFO(0x2E, 0x53, 1) },
{ _T("End"), KBDATA_INFO(0x23, 0x4F, 1)},
{ _T("Page Down"), KBDATA_INFO(0x22, 0x51, 1)},
{ _T("Prnt Scrn"), KBDATA_INFO(0x2C, 0x37, 1)},
{ _T("Scroll Lock"), KBDATA_INFO(0x91, 0x46, 0)},
{ _T("Num Lock"), KBDATA_INFO(0x90, 0x45, 1)},
{ _T("Caps Lock"), KBDATA_INFO(0x14, 0x3A, 0) },
{ _T("Pause"), KBDATA_INFO(0x13, 0x45, 1)},
{ _T("Num 0"), KBDATA_INFO(0x60, 0x52, 0) },
{ _T("Num 1"), KBDATA_INFO(0x61, 0x4F, 0) },
{ _T("Num 2"), KBDATA_INFO(0x62, 0x50, 0) },
{ _T("Num 3"), KBDATA_INFO(0x63, 0x51, 0) },
{ _T("Num 4"), KBDATA_INFO(0x64, 0x4B, 0) },
{ _T("Num 5"), KBDATA_INFO(0x65, 0x4C, 0) },
{ _T("Num 6"), KBDATA_INFO(0x66, 0x4D, 0) },
{ _T("Num 7"), KBDATA_INFO(0x67, 0x47, 0) },
{ _T("Num 8"), KBDATA_INFO(0x68, 0x48, 0) },
{ _T("Num 9"), KBDATA_INFO(0x69, 0x49, 0) },
{ _T("Num Home"), KBDATA_INFO(0x24, 0x47, 0) },
{ _T("Num End"), KBDATA_INFO(0x23, 0x4F, 0) },
{ _T("Num Page Up"), KBDATA_INFO(0x21, 0x49, 0) },
{ _T("Num Page Down"), KBDATA_INFO(0x22, 0x51, 0) },
{ _T("Clear"), KBDATA_INFO(0x0C, 0x4C, 0) },
{ _T("Num /"), KBDATA_INFO(0x6f, 0x35, 1) },
{ _T("Num *"), KBDATA_INFO(0x6A, 0x37, 0) },
{ _T("Num -"), KBDATA_INFO(0x6D, 0x4A, 0) },
{ _T("Num +"), KBDATA_INFO(0x6B, 0x4E, 0) },
{ _T("Num Enter"), KBDATA_INFO(0x0B, 0x1C, 1) },
{ _T("Num Del"), KBDATA_INFO(0x2E, 0x53, 0) },
{ _T("Num Insert"), KBDATA_INFO(0x2D, 0x52, 0) },
{ _T("Num ."), KBDATA_INFO(0x6E, 0x53, 0) },
std::map CInputUtils::m_UsbKeyMap =
{0x47, _T("Scroll Lock")},
{0x64, _T("\\(Non-US)")},
bool CInputUtils::Keyboard(WORD wVk, WORD wScan, bool bExtended, bool bDown, bool bUp, bool bScan)
INPUT inputs[0x02] = { 0 };
if (bExtended) dwFlag |= KEYEVENTF_EXTENDEDKEY;
if (bScan) dwFlag |= KEYEVENTF_SCANCODE;
inputs[uSnedCount].type = INPUT_KEYBOARD;
inputs[uSnedCount].ki.wVk = wVk;
inputs[uSnedCount].ki.wScan = wScan;
inputs[uSnedCount].ki.dwFlags = dwFlag;
inputs[uSnedCount].type = INPUT_KEYBOARD;
inputs[uSnedCount].ki.wVk = wVk;
inputs[uSnedCount].ki.wScan = wScan;
inputs[uSnedCount].ki.dwFlags = dwFlag | KEYEVENTF_KEYUP;
UINT uCount = ::SendInput(uSnedCount, inputs, sizeof(INPUT));
return uSnedCount == uCount;
bool CInputUtils::Keyboard(_tstring strKey, bool bDown, bool bUp)
for (const auto& item : m_KeyMap)
if (0 == _tcsicmp(item.first.c_str(), strKey.c_str()))
INPUT inputs[0x02] = { 0 };
inputs[uSnedCount].type = INPUT_KEYBOARD;
inputs[uSnedCount].ki.wVk = keyData.vkCode;
inputs[uSnedCount].ki.wScan = keyData.scanCode;
inputs[uSnedCount].ki.dwFlags = keyData.flags;
inputs[uSnedCount].type = INPUT_KEYBOARD;
inputs[uSnedCount].ki.wVk = keyData.vkCode;
inputs[uSnedCount].ki.wScan = keyData.scanCode;
inputs[uSnedCount].ki.dwFlags = keyData.flags | KEYEVENTF_KEYUP;
UINT uCount = ::SendInput(uSnedCount, inputs, sizeof(INPUT));
return uSnedCount == uCount;
bool CInputUtils::KeyboardChar(TCHAR ch)
INPUT inputs[0x01] = { 0 };
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.dwFlags = KEYEVENTF_UNICODE;
UINT uCount = ::SendInput(1, inputs, sizeof(INPUT));
bool CInputUtils::KeyboardText(_tstring strText)
INPUT inputs[0x01] = { 0 };
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.dwFlags = KEYEVENTF_UNICODE;
for (const auto& item : strText)
inputs[0].ki.wScan = item;
uCount = ::SendInput(1, inputs, sizeof(INPUT));
bool CInputUtils::MouseMove(LONG x, LONG y, bool bAbsolute)
LONG dwWidth = ::GetSystemMetrics(SM_CXSCREEN);
LONG dwHeight = ::GetSystemMetrics(SM_CYSCREEN);
INPUT inputs[0x01] = { 0 };
inputs[0].type = INPUT_MOUSE;
inputs[0].mi.dx = (LONG)((double)65535 / (double)dwWidth * x);
inputs[0].mi.dy = (LONG)((double)65535 / (double)dwHeight * y);
inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE;
inputs[0].mi.dwFlags |= MOUSEEVENTF_ABSOLUTE;
UINT uCount = ::SendInput(1, inputs, sizeof(INPUT));
bool CInputUtils::MouseKey(bool bLeft, bool bRight, bool bMiddle, bool bDown, bool bUp)
INPUT inputs[0x06] = { 0 };
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_LEFTUP;
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_RIGHTUP;
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
UINT uCount = ::SendInput(uSendCount, inputs, sizeof(INPUT));
return uSendCount == uCount;
bool CInputUtils::MouseWheelForward(LONG nSpeed)
INPUT inputs[0x01] = { 0 };
inputs[0].type = INPUT_MOUSE;
inputs[0].mi.dwFlags = MOUSEEVENTF_WHEEL;
inputs[0].mi.mouseData = WHEEL_DELTA * nSpeed;
UINT uCount = ::SendInput(1, inputs, sizeof(INPUT));
bool CInputUtils::MouseWheelBackward(LONG nSpeed)
INPUT inputs[0x01] = { 0 };
inputs[0].type = INPUT_MOUSE;
inputs[0].mi.dwFlags = MOUSEEVENTF_WHEEL;
inputs[0].mi.mouseData = 0 - (WHEEL_DELTA * nSpeed);
UINT uCount = ::SendInput(1, inputs, sizeof(INPUT));
