VB 有 SendKeys,C 語言在 Windows 下需調用系統 API 實現模擬鍵盤/鼠標輸入。主要有兩種方式:現代推薦 SendInput,舊式 keybd_event(已棄用但仍廣泛使用)。
#define _WIN32_WINNT 0x0501 // 需 XP 以上
#include <windows.h>
// 模擬按下並釋放一個虛擬鍵
void PressKey(WORD vk) {
INPUT input[2] = {0};
// 按下
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = vk;
// 釋放
input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = vk;
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(2, input, sizeof(INPUT));
}
// 模擬輸入字符串(逐字符發送)
void TypeString(const char *str) {
for (int i = 0; str[i]; i++) {
// 簡化:僅處理 ASCII 可見字符,實際需處理 Shift 組合鍵
INPUT input[2] = {0};
input[0].type = INPUT_KEYBOARD;
input[0].ki.wScan = str[i];
input[0].ki.dwFlags = KEYEVENTF_UNICODE;
input[1] = input[0];
input[1].ki.dwFlags |= KEYEVENTF_KEYUP;
SendInput(2, input, sizeof(INPUT));
Sleep(10); // 適當延遲
}
}
int main() {
Sleep(3000); // 留 3 秒切換到目標窗口
PressKey(VK_RETURN); // 模擬 Enter
TypeString("Hello from C!");
return 0;
}
#include <windows.h>
#define KEYDOWN(vk) (keybd_event(vk, 0, 0, 0), Sleep(50))
#define KEYUP(vk) (keybd_event(vk, 0, KEYEVENTF_KEYUP, 0), Sleep(50))
void PressKeyOld(WORD vk) {
KEYDOWN(vk);
KEYUP(vk);
}
int main() {
Sleep(3000);
PressKeyOld(VK_F5); // 模擬 F5 刷新
return 0;
}
| 特性 | SendInput | keybd_event |
|---|---|---|
| 推薦程度 | ✅ 現代標準 | ❌ 已棄用 |
| 輸入類型 | 鍵盤/鼠標/硬件 | 僅鍵盤 |
| Unicode 支持 | 原生支持 (KEYEVENTF_UNICODE) | 需配合 MapVirtualKey |
| 同步性 | 插入輸入流,按順序處理 | 直接發送,可能繞過某些攔截 |
| 權限要求 | 同桌面進程 | 同桌面進程 |
FindWindow/SetForegroundWindow 定位目標窗口。SetForegroundWindow,否則輸入發送到當前活動窗口。原回答提到“主函數入口 int WINAPI WinMain,選擇控制台 win32 console application”有誤:
int main() 或 int wmain(),項目類型選 “Windows Console Application”。int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int),項目類型選 “Windows Desktop Application”。
gcc simulate_keys.c -o simulate_keys -luser32
// 或 MSVC 項目屬性 -> 鏈接器 -> 輸入 -> 附加依賴項添加 user32.lib
C 語言模擬擊鍵首選 SendInput,功能強、標準化、支持 Unicode。嚴禁用於惡意自動化、遊戲外掛等違規場景。學習重點在於理解 Windows 輸入模型、INPUT 結構體填充、虛擬鍵碼與掃描碼映射、進程間輸入隔離機制。