#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
using namespace std;
const string CONFIG_FILE = "key_config.txt";
const string DEFAULT_KEY = "F8";
// 虚拟键码映射表
const unordered_map<string, SHORT> vkMap = {
{"A", 0x41}, {"B", 0x42}, {"C", 0x43}, {"D", 0x44}, {"E", 0x45},
{"F", 0x46}, {"G", 0x47}, {"H", 0x48}, {"I", 0x49}, {"J", 0x4A},
{"K", 0x4B}, {"L", 0x4C}, {"M", 0x4D}, {"N", 0x4E}, {"O", 0x4F},
{"P", 0x50}, {"Q", 0x51}, {"R", 0x52}, {"S", 0x53}, {"T", 0x54},
{"U", 0x55}, {"V", 0x56}, {"W", 0x57}, {"X", 0x58}, {"Y", 0x59},
{"Z", 0x5A},
{"0", 0x30}, {"1", 0x31}, {"2", 0x32}, {"3", 0x33}, {"4", 0x34},
{"5", 0x35}, {"6", 0x36}, {"7", 0x37}, {"8", 0x38}, {"9", 0x39},
{"F1", VK_F1}, {"F2", VK_F2}, {"F3", VK_F3}, {"F4", VK_F4},
{"F5", VK_F5}, {"F6", VK_F6}, {"F7", VK_F7}, {"F8", VK_F8},
{"F9", VK_F9}, {"F10", VK_F10}, {"F11", VK_F11}, {"F12", VK_F12},
{"SPACE", VK_SPACE}, {"ENTER", VK_RETURN}, {"ESC", VK_ESCAPE},
{"LEFT", VK_LEFT}, {"RIGHT", VK_RIGHT}, {"UP", VK_UP}, {"DOWN", VK_DOWN},
{"CTRL", VK_CONTROL}, {"ALT", VK_MENU}, {"SHIFT", VK_SHIFT},
{"TAB", VK_TAB}, {"CAPSLOCK", VK_CAPITAL}, {"BACKSPACE", VK_BACK}
};
// 获取键名对应的虚拟键码
SHORT GetKeyCode(const string& keyName) {
auto it = vkMap.find(keyName);
if (it != vkMap.end()) {
return it->second;
}
return 0;
}
// 获取虚拟键码对应的键名
string GetKeyName(SHORT vkCode) {
for (const auto& pair : vkMap) {
if (pair.second == vkCode) {
return pair.first;
}
}
return "";
}
// 初始化配置文件
void InitConfigFile() {
ofstream file(CONFIG_FILE);
if (file.is_open()) {
file << DEFAULT_KEY;
file.close();
}
}
// 读取配置的键名
string ReadConfigKey() {
ifstream file(CONFIG_FILE);
string keyName;
if (file.is_open()) {
file >> keyName;
file.close();
}
return keyName.empty() ? DEFAULT_KEY : keyName;
}
// 保存键名到配置文件
void SaveConfigKey(const string& keyName) {
ofstream file(CONFIG_FILE);
if (file.is_open()) {
file << keyName;
file.close();
}
}
// 等待用户按键并返回键名
string WaitForUserKeyPress() {
cout << "请按下要设置的键 (按ESC取消)...\n";
string lastKey;
while (true) {
if (_kbhit()) {
int ch = _getch();
// 处理功能键
if (ch == 0 || ch == 0xE0) {
int ext = _getch();
SHORT vkCode = MapVirtualKey(ext, MAPVK_VSC_TO_VK);
lastKey = GetKeyName(vkCode);
if (!lastKey.empty()) {
cout << "检测到按键: " << lastKey << endl;
}
}
// 处理普通键
else {
SHORT vkCode = MapVirtualKey(ch, MAPVK_VSC_TO_VK);
lastKey = GetKeyName(vkCode);
if (!lastKey.empty()) {
cout << "检测到按键: " << lastKey << endl;
}
// ESC键取消
if (vkCode == VK_ESCAPE) {
return "";
}
}
// 等待按键释放
while (_kbhit()) {
_getch();
}
// 返回最后一个有效按键
if (!lastKey.empty()) {
return lastKey;
}
}
Sleep(10);
}
}
// 模拟按键按下
void SimulateKeyPress(SHORT vkCode) {
INPUT input[2] = { {0}, {0} };
// 按下键
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = vkCode;
// 释放键
input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = vkCode;
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(2, input, sizeof(INPUT));
}
// 串口监听函数
void MonitorSerialPort(SHORT vkCode) {
HANDLE hSerial = CreateFile("COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSerial == INVALID_HANDLE_VALUE) {
cout << "无法打开串口COM3\n";
return;
}
// 配置串口
DCB dcb = { 0 };
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(hSerial, &dcb)) {
cout << "获取串口状态失败\n";
CloseHandle(hSerial);
return;
}
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcb)) {
cout << "设置串口状态失败\n";
CloseHandle(hSerial);
return;
}
cout << "开始监听串口 (按ESC退出)...\n";
cout << "当串口开关按下时将模拟按下: " << GetKeyName(vkCode) << endl;
char buffer;
DWORD bytesRead;
bool running = true;
while (running) {
if (ReadFile(hSerial, &buffer, 1, &bytesRead, NULL) && bytesRead > 0) {
if (buffer == '1') { // 假设串口发送'1'表示开关按下
SimulateKeyPress(vkCode);
}
}
// 检查是否按下ESC键
if (_kbhit() && _getch() == 27) {
running = false;
}
Sleep(10);
}
CloseHandle(hSerial);
}
// 主菜单
void ShowMainMenu(const string& currentKey) {
system("cls");
cout << "===== 串口按键模拟器 =====\n";
cout << "当前配置按键: " << currentKey << "\n\n";
cout << "1. 更改按键配置\n";
cout << "2. 开始监听串口\n";
cout << "3. 退出程序\n";
cout << "请选择: ";
}
int main() {
// 初始化配置文件
ifstream testFile(CONFIG_FILE);
if (!testFile.good()) {
InitConfigFile();
}
testFile.close();
string currentKey = ReadConfigKey();
bool running = true;
while (running) {
ShowMainMenu(currentKey);
int choice;
cin >> choice;
switch (choice) {
case 1: { // 更改按键配置
string newKey = WaitForUserKeyPress();
if (!newKey.empty()) {
cout << "要将按键配置更改为 " << newKey << " 吗? (Y/N): ";
char confirm;
cin >> confirm;
if (toupper(confirm) == 'Y') {
SaveConfigKey(newKey);
currentKey = newKey;
cout << "按键配置已更新\n";
}
} else {
cout << "取消更改\n";
}
break;
}
case 2: // 开始监听串口
MonitorSerialPort(GetKeyCode(currentKey));
break;
case 3: // 退出程序
running = false;
break;
default:
cout << "无效选择\n";
break;
}
cout << "按任意键继续...";
_getch();
}
return 0;
}
最新发布