CInputUtils.h
#pragma once
#include <windows.h>
#include <tchar.h>
#include <string>
#include <map>
#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif
typedef struct _KBDATA_INFO KBDATA_INFO;
typedef struct _KBDATA_INFO {
WORD vkCode;
WORD scanCode;
DWORD flags;
_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
{
return !(*this == r);
}
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->vkCode = r.vkCode;
this->scanCode = r.scanCode;
this->flags = r.flags;
}
} KBDATA_INFO, FAR* LPKBDATA_INFO, * PKBDATA_INFO;
class CInputUtils
{
public:
//
// @brief: 发送按键
// @param: wVk 虚键码
// @param: wScan 扫描码
// @param: bExtended 是否扩展键
// @param: bDown 是否要按下
// @param: bUp 是否要弹起
// @param: bScan 是否扫描码(启用后忽略虚键码)
// @ret: bool 操作成功返回true
static bool Keyboard(WORD wVk, WORD wScan, bool bExtended = false, bool bDown = true, bool bUp = true, bool bScan = false);
//
// @brief: 发送按键
// @param: strKey 按键名
// @param: bDown 是否要按下
// @param: bUp 是否要弹起
// @ret: bool 操作成功返回true
static bool Keyboard(_tstring strKey, bool bDown = true, bool bUp = true);
//
// @brief: 发送字符
// @param: ch 字符
// @ret: bool 操作成功返回true
static bool KeyboardChar(TCHAR ch);
//
// @brief: 发送字符串
// @param: strText 字符
// @ret: bool 操作成功返回true
static bool KeyboardText(_tstring strText);
//
// @brief: 鼠标移动
// @param: x 横坐标
// @param: y 纵坐标
// @param: bAbsolute 是否绝对坐标, 如果为true, 移动到指定坐标, 否则相对于当前坐标进行移动
// @ret: bool 操作成功返回true
static bool MouseMove(LONG x, LONG y, bool bAbsolute = true);
//
// @brief: 鼠标按键
// @param: bLeft 鼠标左键
// @param: bRight 鼠标右键
// @param: bMiddle 鼠标中键
// @param: bDown 按下按键
// @param: bUp 弹起按键
// @ret: bool 操作成功返回true
static bool MouseKey(bool bLeft, bool bRight, bool bMiddle, bool bDown = true, bool bUp = true);
//
// @brief: 鼠标滚轮向前滚动
// @param: nSpeed 速度
// @ret: bool 操作成功返回true
static bool MouseWheelForward(LONG nSpeed = 1);
//
// @brief: 鼠标滚轮向后滚动
// @param: nSpeed 速度
// @ret: bool 操作成功返回true
static bool MouseWheelBackward(LONG nSpeed = 1);
private:
static std::map<_tstring, KBDATA_INFO> m_KeyMap;
static std::map<DWORD, _tstring> m_UsbKeyMap;
};
CInputUtils.cpp
#include "CInputUtils.h"
#include <iostream>
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) },
}; //118个按键
//USB按键映射表
std::map<DWORD, _tstring> CInputUtils::m_UsbKeyMap =
{
{0x04, _T("A")},
{0x05, _T("B")},
{0x06, _T("C")},
{0x07, _T("D")},
{0x08, _T("E")},
{0x09, _T("F")},
{0x0A, _T("G")},
{0x0B, _T("H")},
{0x0C, _T("I")},
{0x0D, _T("J")},
{0x0E, _T("K")},
{0x0F, _T("L")},
{0x10, _T("M")},
{0x11, _T("N")},
{0x12, _T("O")},
{0x13, _T("P")},
{0x14, _T("Q")},
{0x15, _T("R")},
{0x16, _T("S")},
{0x17, _T("T")},
{0x18, _T("U")},
{0x19, _T("V")},
{0x1A, _T("W")},
{0x1B, _T("X")},
{0x1C, _T("Y")},
{0x1D, _T("Z")},
{0x1E, _T("1")},
{0x1F, _T("2")},
{0x20, _T("3")},
{0x21, _T("4")},
{0x22, _T("5")},
{0x23, _T("6")},
{0x24, _T("7")},
{0x25, _T("8")},
{0x26, _T("9")},
{0x27, _T("0")},
{0x28, _T("Enter")},
{0x29, _T("Esc")},
{0x2A, _T("Backspace")},
{0x2B, _T("Tab")},
{0x2C, _T("Space")},
{0x2D, _T("-")},
{0x2E, _T("=")},
{0x2F, _T("[")},
{0x30, _T("]")},
{0x31, _T("\\")},
{0x33, _T(";")},
{0x34, _T("\'")},
{0x35, _T("`")},
{0x36, _T(",")},
{0x37, _T(".")},
{0x38, _T("/")},
{0x39, _T("Caps Lock")},
{0x3A, _T("F1")},
{0x3B, _T("F2")},
{0x3C, _T("F3")},
{0x3D, _T("F4")},
{0x3E, _T("F5")},
{0x3F, _T("F6")},
{0x40, _T("F7")},
{0x41, _T("F8")},
{0x42, _T("F9")},
{0x43, _T("F10")},
{0x44, _T("F11")},
{0x45, _T("F12")},
{0x46, _T("Prnt Scrn")},
{0x47, _T("Scroll Lock")},
{0x48, _T("Pause")},
{0x49, _T("Insert")},
{0x4A, _T("Home")},
{0x4B, _T("Page Up")},
{0x4C, _T("Delete")},
{0x4D, _T("End")},
{0x4E, _T("Page Down")},
{0x4F, _T("Right")},
{0x50, _T("Left")},
{0x51, _T("Down")},
{0x52, _T("Up")},
{0x53, _T("Num Lock")},
{0x54, _T("Num /")},
{0x55, _T("Num *")},
{0x56, _T("Num -")},
{0x57, _T("Num +")},
{0x58, _T("Num Enter")},
{0x59, _T("Num 1")},
{0x5A, _T("Num 2")},
{0x5B, _T("Num 3")},
{0x5C, _T("Num 4")},
{0x5D, _T("Num 5")},
{0x5E, _T("Num 6")},
{0x5F, _T("Num 7")},
{0x60, _T("Num 8")},
{0x61, _T("Num 9")},
{0x62, _T("Num 0")},
{0x63, _T("Num .")},
{0x64, _T("\\(Non-US)")},
{0x65, _T("Appcation")}
};
bool CInputUtils::Keyboard(WORD wVk, WORD wScan, bool bExtended/* = false*/, bool bDown/* = true*/, bool bUp/* = true*/, bool bScan/* = false*/)
{
INPUT inputs[0x02] = { 0 };
UINT uSnedCount = 0;
DWORD dwFlag = 0;
if (bExtended) dwFlag |= KEYEVENTF_EXTENDEDKEY;
if (bScan) dwFlag |= KEYEVENTF_SCANCODE;
if (bDown)
{
inputs[uSnedCount].type = INPUT_KEYBOARD;
inputs[uSnedCount].ki.wVk = wVk;
inputs[uSnedCount].ki.wScan = wScan;
inputs[uSnedCount].ki.dwFlags = dwFlag;
uSnedCount++;
}
if (bUp)
{
inputs[uSnedCount].type = INPUT_KEYBOARD;
inputs[uSnedCount].ki.wVk = wVk;
inputs[uSnedCount].ki.wScan = wScan;
inputs[uSnedCount].ki.dwFlags = dwFlag | KEYEVENTF_KEYUP;
uSnedCount++;
}
UINT uCount = ::SendInput(uSnedCount, inputs, sizeof(INPUT));
return uSnedCount == uCount;
}
bool CInputUtils::Keyboard(_tstring strKey, bool bDown/* = true*/, bool bUp/* = true*/)
{
bool bFind = false;
KBDATA_INFO keyData;
for (const auto& item : m_KeyMap)
{
if (0 == _tcsicmp(item.first.c_str(), strKey.c_str()))
{
keyData = item.second;
bFind = true;
}
}
if (!bFind)
{
return false;
}
INPUT inputs[0x02] = { 0 };
UINT uSnedCount = 0;
if (bDown)
{
inputs[uSnedCount].type = INPUT_KEYBOARD;
inputs[uSnedCount].ki.wVk = keyData.vkCode;
inputs[uSnedCount].ki.wScan = keyData.scanCode;
inputs[uSnedCount].ki.dwFlags = keyData.flags;
uSnedCount++;
}
if (bUp)
{
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;
uSnedCount++;
}
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.wVk = 0;
inputs[0].ki.wScan = ch;
inputs[0].ki.dwFlags = KEYEVENTF_UNICODE;
UINT uCount = ::SendInput(1, inputs, sizeof(INPUT));
return 1 == uCount;
}
bool CInputUtils::KeyboardText(_tstring strText)
{
INPUT inputs[0x01] = { 0 };
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = 0;
inputs[0].ki.dwFlags = KEYEVENTF_UNICODE;
UINT uCount = 0;
for (const auto& item : strText)
{
inputs[0].ki.wScan = item;
uCount = ::SendInput(1, inputs, sizeof(INPUT));
}
return 1 == uCount;
}
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;
if (bAbsolute)
{
inputs[0].mi.dx = (LONG)((double)65535 / (double)dwWidth * x);
inputs[0].mi.dy = (LONG)((double)65535 / (double)dwHeight * y);
}
else
{
inputs[0].mi.dx = x;
inputs[0].mi.dy = y;
}
inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE;
if (bAbsolute)
{
inputs[0].mi.dwFlags |= MOUSEEVENTF_ABSOLUTE;
}
UINT uCount = ::SendInput(1, inputs, sizeof(INPUT));
return 1 == uCount;
}
bool CInputUtils::MouseKey(bool bLeft, bool bRight, bool bMiddle, bool bDown/* = true*/, bool bUp/* = true*/)
{
INPUT inputs[0x06] = { 0 };
UINT uSendCount = 0;
if (bLeft)
{
if (bDown)
{
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
uSendCount++;
}
if (bUp)
{
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_LEFTUP;
uSendCount++;
}
}
if (bRight)
{
if (bDown)
{
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
uSendCount++;
}
if (bUp)
{
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_RIGHTUP;
uSendCount++;
}
}
if (bMiddle)
{
if (bDown)
{
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
uSendCount++;
}
if (bUp)
{
inputs[uSendCount].type = INPUT_MOUSE;
inputs[uSendCount].mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
uSendCount++;
}
}
UINT uCount = ::SendInput(uSendCount, inputs, sizeof(INPUT));
return uSendCount == uCount;
}
bool CInputUtils::MouseWheelForward(LONG nSpeed/* = 1*/)
{
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));
return 1 == uCount;
}
bool CInputUtils::MouseWheelBackward(LONG nSpeed/* = 1*/)
{
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));
return 1 == uCount;
}