在 Windows 平台下,C++ 模擬鍵盤鼠標輸入主要依賴兩個核心 API 函數:
void mouse_event(
DWORD dwFlags, // 動作標志:移動、點擊、滾輪等
DWORD dx, // X 軸絕對位置或相對移動量
DWORD dy, // Y 軸絕對位置或相對移動量
DWORD dwData, // 滾輪移動量
ULONG_PTR dwExtraInfo // 額外信息
);
常用標志組合:
void keybd_event(
BYTE bVk, // 虛擬鍵碼
BYTE bScan, // 掃描碼(通常為 0)
DWORD dwFlags, // KEYEVENTF_KEYUP 表示釋放鍵
ULONG_PTR dwExtraInfo
);
常用虛擬鍵碼:`VK_RETURN` (Enter)、`VK_TAB`、`VK_CONTROL`、`VK_MENU` (Alt)、`VK_LWIN` (Win鍵) 等。
推薦使用 `SendInput`,它是更底層、更可靠的輸入注入 API,支持鍵盤、鼠標、硬件輸入統一封裝:
UINT SendInput(
UINT nInputs, // 輸入事件數量
LPINPUT pInputs, // INPUT 結構體數組
int cbSize // INPUT 結構體大小
);
#include
#include
void SimulateWinPause() {
// 方法 1:組合鍵 Win + Pause/Break
INPUT inputs[4] = {};
// 按下 Win 鍵
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_LWIN;
// 按下 Pause 鍵
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = VK_PAUSE;
// 釋放 Pause 鍵
inputs[2].type = INPUT_KEYBOARD;
inputs[2].ki.wVk = VK_PAUSE;
inputs[2].ki.dwFlags = KEYEVENTF_KEYUP;
// 釋放 Win 鍵
inputs[3].type = INPUT_KEYBOARD;
inputs[3].ki.wVk = VK_LWIN;
inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(4, inputs, sizeof(INPUT));
}
void SimulateMouseClick(int x, int y) {
// 移動到絕對座標並左鍵點擊
INPUT inputs[3] = {};
// 移動鼠標(絕對座標需配合 MOUSEEVENTF_ABSOLUTE)
inputs[0].type = INPUT_MOUSE;
inputs[0].mi.dx = (x * 65535) / GetSystemMetrics(SM_CXSCREEN);
inputs[0].mi.dy = (y * 65535) / GetSystemMetrics(SM_CYSCREEN);
inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
// 按下左鍵
inputs[1].type = INPUT_MOUSE;
inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
// 釋放左鍵
inputs[2].type = INPUT_MOUSE;
inputs[2].mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(3, inputs, sizeof(INPUT));
}
int main() {
// 示例:打開系統屬性
SimulateWinPause();
// 或:模擬點擊桌面圖標(需根據實際座標調整)
// SimulateMouseClick(100, 100);
return 0;
}
| 場景 | 關鍵技術點 |
|---|---|
| 自動化測試 | 結合圖像識別(OpenCV)定位元素座標 |
| 遊戲輔助/腳本 | 需繞過 DirectX/Hook 檢測,考慮驅動級模擬 |
| 跨進程輸入 | 使用 `AttachThreadInput` 關聯目標線程 |
| 文本輸入 | 組合鍵處理、輸入法狀態管理、Unicode 字符發送 |
總結:`SendInput` 是現代首選方案,兼容性好、功能全。簡單場景可用 `keybd_event`/`mouse_event`,但微軟已標記為舊版 API。實際項目中建議封裝通用輸入類,統一管理延時、錯誤重試、座標轉換等邏輯。