首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 實現模擬鍵盤鼠標操作:核心 API 詳解與應用示例

     編輯:程式設計疑難解答

核心 Windows API

在 Windows 平台下,C++ 模擬鍵盤鼠標輸入主要依賴兩個核心 API 函數:

1. mouse_event - 鼠標事件模擬

void mouse_event(
  DWORD dwFlags,      // 動作標志:移動、點擊、滾輪等
  DWORD dx,           // X 軸絕對位置或相對移動量
  DWORD dy,           // Y 軸絕對位置或相對移動量
  DWORD dwData,       // 滾輪移動量
  ULONG_PTR dwExtraInfo // 額外信息
);

常用標志組合:

  • `MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP` = 左鍵單擊
  • `MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP` = 右鍵單擊
  • `MOUSEEVENTF_MOVE` = 移動鼠標
  • `MOUSEEVENTF_ABSOLUTE` = 使用絕對座標(0-65535 映射屏幕分辨率)

2. keybd_event - 鍵盤事件模擬

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

推薦使用 `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 字符發送

注意事項與最佳實踐

  1. 權限問題:目標窗口若以管理員權限運行,模擬程序也需提權
  2. 輸入丟失:發送間隔加入 `Sleep(10-50ms)` 確保系統處理完畢
  3. 座標系統:多顯示器環境下絕對座標計算需考慮虛擬屏幕範圍
  4. 防檢測:部分軟件檢測 `SendInput` 注入,可嘗試驅動級方案(如 Interception 驅動)

總結:`SendInput` 是現代首選方案,兼容性好、功能全。簡單場景可用 `keybd_event`/`mouse_event`,但微軟已標記為舊版 API。實際項目中建議封裝通用輸入類,統一管理延時、錯誤重試、座標轉換等邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved