在 VC++ 開發中,自動化模擬用戶輸入(如按鍵、點擊、拖拽)是常見需求。本文提供一個封裝良好、功能完整的 mk 類,涵蓋鍵盤按鍵組合、滑鼠單擊/雙擊/右鍵/拖拽等核心操作,並支援自定義延遲,適合自動化測試、巨集腳本或輔助工具開發。
#if !defined(AFX_MK_H__B024D48F_090A_4F6F_A199_32996DF699B3__INCLUDED_)
#define AFX_MK_H__B024D48F_090A_4F6F_A199_32996DF699B3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
#include <winable.h>
class mk
{
public:
mk();
// 鍵盤操作
static void Key(BYTE k, int mSeconds = 0); // 單鍵
static void Key2(BYTE k1, BYTE k2, int mSeconds = 0); // 兩鍵組合
static void Key3(BYTE k1, BYTE k2, BYTE k3, int mSeconds = 0); // 三鍵組合
// 滑鼠操作
static void Click(int x, int y, int mSeconds = 0); // 左鍵單擊
static void RClick(int x, int y, int mSeconds = 0); // 右鍵單擊
static void DClick(int x, int y, int mSeconds = 0); // 雙擊
static void CtrlClick(int x, int y, int mSeconds = 0); // Ctrl+單擊
static void Drag(int x1, int y1, int x2, int y2, int mSeconds = 0); // 拖拽
virtual ~mk();
};
#endif
void mk::Click(int x, int y, int mSeconds)
{
SetCursorPos(x, y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
Sleep(mSeconds);
}
void mk::DClick(int x, int y, int mSeconds)
{
SetCursorPos(x, y);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
Sleep(mSeconds);
}
void mk::Drag(int x1, int y1, int x2, int y2, int mSeconds)
{
SetCursorPos(x1, y1);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
SetCursorPos(x2, y2);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
Sleep(mSeconds);
}
void mk::Key2(BYTE k1, BYTE k2, int mSeconds)
{
INPUT input[4];
memset(input, 0, sizeof(input));
input[0].type = input[1].type = input[2].type = input[3].type = INPUT_KEYBOARD;
input[0].ki.wVk = input[3].ki.wVk = k1;
input[1].ki.wVk = input[2].ki.wVk = k2;
input[2].ki.dwFlags = input[3].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(4, input, sizeof(INPUT));
Sleep(mSeconds);
}
關鍵點:使用 SendInput 而非舊式 keybd_event,可正確處理組合鍵(如 Ctrl+C)並在現代 Windows 版本上更穩定。需包含 winable.h 並連結 user32.lib。
// 模擬 Ctrl+S 存檔
mk::Key2(VK_CONTROL, 'S', 100);
// 滑鼠拖拽選取區域
mk::Drag(100, 100, 300, 300, 50);
// 連續輸入字串
for (char c : "Hello") mk::Key(c, 20);
SetCursorPos 基準)。mSeconds 可防止操作過快導致目標程式無法響應。