相關函數解釋
GetAsyncKeyState 是 Windows API 中的一個函數,用于判斷某個虛擬鍵是否被按下。GetAsyncKeyState(VK_ESCAPE) 專門用于檢測 Esc 鍵的狀態。下面為你詳細介紹其用法:
函數原型
cpp
SHORT GetAsyncKeyState(
? int vKey
);
參數
vKey:虛擬鍵碼,對于 Esc 鍵,使用 VK_ESCAPE 作為參數。
返回值
返回一個 SHORT 類型的值,其含義如下:
最高位(第 15 位)為 1 時,表示該鍵當前處于按下狀態;為 0 時,表示該鍵當前處于釋放狀態。
最低位(第 0 位)為 1 時,表示該鍵在最近一次調用 GetAsyncKeyState 之后被按下過;為 0 時,表示該鍵在最近一次調用之后沒有被按下過。
示例代碼
以下是一個簡單的 C++ 示例,展示了如何使用 GetAsyncKeyState(VK_ESCAPE) 來檢測 Esc 鍵的狀態:
cpp
#include <iostream>
#include <windows.h>
int main() {std::cout << "Press the Esc key to exit..." << std::endl;while (true) {// 檢測 Esc 鍵的狀態SHORT state = GetAsyncKeyState(VK_ESCAPE);// 檢查最高位是否為 1,即 Esc 鍵是否被按下if (state & 0x8000) {std::cout << "Esc key is pressed. Exiting..." << std::endl;break;}// 可以在這里添加其他代碼,處理其他任務Sleep(10); // 短暫休眠,減少 CPU 占用}return 0;}
代碼解釋
引入必要的頭文件:windows.h 包含了 GetAsyncKeyState 函數的聲明,iostream 用于輸入輸出操作。
進入循環:在 while (true) 循環中不斷檢測 Esc 鍵的狀態。
檢測 Esc 鍵狀態:調用 GetAsyncKeyState(VK_ESCAPE) 函數獲取 Esc 鍵的狀態,并將結果存儲在 state 變量中。
檢查最高位:使用按位與運算符 & 檢查 state 的最高位是否為 1。如果為 1,則表示 Esc 鍵被按下,輸出提示信息并退出循環。
短暫休眠:使用 Sleep(10) 函數讓程序暫停 10 毫秒,減少 CPU 占用。
注意事項
GetAsyncKeyState 是異步的,它返回的是調用時鍵的狀態,而不是在某個特定消息處理過程中的狀態。
由于該函數是異步的,可能會出現按鍵抖動的問題。在實際應用中,可以根據需要添加防抖處理。
虛擬鍵碼 ?對應值 對應鍵
對應鍵值
VK_LBUTTON ?1 鼠標左鍵VK_RBUTTON ?2 鼠標右鍵VK_CANCEL 3 CancelVK_MBUTTON ?4 鼠標中鍵VK_XBUTTON1 5VK_XBUTTON2 6VK_BACK 8 BackspaceVK_TAB ?9 TabVK_CLEAR ?12 ?Clear13 ?EnterVK_SHIFT ?16 ?ShiftVK_CONTROL ?17 ?CtrlVK_MENU 18 ?AltVK_PAUSE ?19 ?PauseVK_CAPITAL ?20 ?Caps LockVK_KANA 21 ?VK_HANGUL 21 ?VK_JUNJA ?23 ?VK_FINAL ?24 ?VK_HANJA ?25 ?VK_KANJI ?25*VK_ESCAPE 27 ?EscVK_CONVERT ?28 ?VK_NONCONVERT 29 ?VK_ACCEPT 30 ?VK_MODECHANGE 31 ?VK_SPACE ?32 ?SpaceVK_PRIOR ?33 ?Page UpVK_NEXT 34 ?Page DownVK_END ?35 ?EndVK_HOME 36 ?HomeVK_LEFT 37 ?Left ArrowVK_UP 38 ?Up ArrowVK_RIGHT ?39 ?Right ArrowVK_DOWN 40 ?Down ArrowVK_SELECT 41 ?SelectVK_PRINT ?42 ?PrintVK_EXECUTE ?43 ?ExecuteVK_SNAPSHOT 44 ?SnapshotVK_INSERT 45 ?InsertVK_DELETE 46 ?DeleteVK_HELP 47 ?Help48 ?049 ?150 ?251 ?352 ?453 ?554 ?655 ?756 ?857 ?965 ?A66 ?B67 ?C68 ?D69 ?E70 ?F71 ?G72 ?H73 ?I74 ?J75 ?K76 ?L77 ?M78 ?N79 ?O80 ?P81 ?Q82 ?R83 ?S84 ?T85 ?U86 ?V87 ?W88 ?X89 ?Y90 ?ZVK_LWIN 91 ?VK_RWIN 92 ?VK_APPS 93 ?VK_SLEEP ?95 ?VK_NUMPAD0 ?96 ?小鍵盤 0VK_NUMPAD1 ?97 ?小鍵盤 1VK_NUMPAD2 ?98 ?小鍵盤 2VK_NUMPAD3 ?99 ?小鍵盤 3VK_NUMPAD4 ?100 小鍵盤 4VK_NUMPAD5 ?101 小鍵盤 5VK_NUMPAD6 ?102 小鍵盤 6VK_NUMPAD7 ?103 小鍵盤 7VK_NUMPAD8 ?104 小鍵盤 8VK_NUMPAD9 ?105 小鍵盤 9VK_MULTIPLY 106 小鍵盤 *VK_ADD ?107 小鍵盤 +VK_SEPARATOR ?108 小鍵盤 EnterVK_SUBTRACT 109 小鍵盤 -VK_DECIMAL ?110 小鍵盤 .VK_DIVIDE 111 小鍵盤 /VK_F1 112 F1VK_F2 113 F2VK_F3 114 F3VK_F4 115 F4VK_F5 116 F5VK_F6 117 F6VK_F7 118 F7VK_F8 119 F8VK_F9 120 F9VK_F10 ?121 F10VK_F11 ?122 F11VK_F12 ?123 F12VK_F13 ?124VK_F14 ?125VK_F15 ?126VK_F16 ?127VK_F17 ?128VK_F18 ?129VK_F19 ?130VK_F20 ?131VK_F21 ?132VK_F22 ?133VK_F23 ?134VK_F24 ?135VK_NUMLOCK ?144 Num LockVK_SCROLL 145 ScrollVK_LSHIFT 160VK_RSHIFT 161VK_LCONTROL 162VK_RCONTROL 163VK_LMENU ?164VK_RMENU ?165VK_BROWSER_BACK 166VK_BROWSER_FORWARD ?167VK_BROWSER_REFRESH ?168VK_BROWSER_STOP 169VK_BROWSER_SEARCH 170VK_BROWSER_FAVORITES ?171VK_BROWSER_HOME 172VK_VOLUME_MUTE ?173 VolumeMuteVK_VOLUME_DOWN ?174 VolumeDownVK_VOLUME_UP ?175 VolumeUpVK_MEDIA_NEXT_TRACK 176VK_MEDIA_PREV_TRACK 177VK_MEDIA_STOP 178VK_MEDIA_PLAY_PAUSE 179VK_LAUNCH_MAIL ?180VK_LAUNCH_MEDIA_SELECT ?181VK_LAUNCH_APP1 ?182VK_LAUNCH_APP2 ?183VK_OEM_1 ?186 ; :VK_OEM_PLUS 187 = +VK_OEM_COMMA ?188VK_OEM_MINUS ?189 - _VK_OEM_PERIOD 190VK_OEM_2 ?191 / ?VK_OEM_3 ?192 ` ~VK_OEM_4 ?219 [ {VK_OEM_5 ?220 \VK_OEM_6 ?221 ] }VK_OEM_7 ?222 引號VK_OEM_8 ?223VK_OEM_102 ?226VK_PACKET 231VK_PROCESSKEY 229VK_ATTN 246VK_CRSEL ?247VK_EXSEL ?248VK_EREOF ?249VK_PLAY 250VK_ZOOM 251VK_NONAME 252VK_PA1 ?253VK_OEM_CLEAR ?254
代碼塊
模擬按鍵而實際使用模擬按鍵只需按下和放下(有時需要在這兩個操作之中放入延時)#include<stdio.h>;#include<windows.h>keybd_event(122, 0, 0, 0);keybd_event(122, 0, KEYEVENTF_KEYUP, 0);組合鍵keybd_event(VK_LWIN, 0, 0 ,0);keybd_event('R', 0, 0 ,0);keybd_event('R', 0, KEYEVENTF_KEYUP ,0);keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);以及上述這四行用于win + 各種鍵的組合鍵!!
鼠標操作
POINT p;
? SetCursorPos(1577, 346);
? mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
鼠標滑動操作
#include <windows.h>#include <stdio.h>#include<unistd.h>#include<conio.h>#include <math.h>int zx(int x1,int y1,int x2,int y2){POINT p;int x;SetConsoleTitle("5082.txt");usleep(200000);SetCursorPos(x1, y1);mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);usleep(200000);SetCursorPos(x2,y2);mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);}int main(){zx(1577,346,1125,685);zx(1135,304,1557,801);return 0;}
若keybd_event函數已被系統棄用,則使用SendInput函數
SendInput 函數是 Windows API 中的一個重要函數,用于模擬用戶輸入事件,包括鍵盤和鼠標操作。它比舊的 keybd_event 和 mouse_event 函數更強大、更可靠,并且在現代 Windows 系統中被推薦使用。下面將對 SendInput 函數進行詳細介紹。
函數原型
c
UINT SendInput(
? UINT ? ?cInputs,
? LPINPUT pInputs,
? int ? ? cbSize
);
參數說明
cInputs
類型:UINT
描述:pInputs 數組中 INPUT 結構體的數量,即要模擬的輸入事件的數量。
pInputs
類型:LPINPUT(指向 INPUT 結構體數組的指針)
描述:一個指向 INPUT 結構體數組的指針,每個 INPUT 結構體代表一個輸入事件,如鍵盤按鍵、鼠標移動或鼠標點擊等。
cbSize
類型:int
描述:INPUT 結構體的大小,通常使用 sizeof(INPUT) 來獲取。
返回值
類型:UINT
描述:函數返回實際插入到輸入隊列中的輸入事件的數量。如果返回值與 cInputs 不相等,則表示出現了錯誤。可以使用 GetLastError 函數來獲取具體的錯誤代碼。
INPUT 結構體
INPUT 結構體用于描述一個輸入事件,其定義如下:
c
typedef struct tagINPUT {
? DWORD type;
? union {
? ? MOUSEINPUT ? ?mi;
? ? KEYBDINPUT ? ?ki;
? ? HARDWAREINPUT hi;
? };
} INPUT, *PINPUT, *LPINPUT;
type:指定輸入事件的類型,可以是以下值之一:
INPUT_MOUSE:表示鼠標事件。
INPUT_KEYBOARD:表示鍵盤事件。
INPUT_HARDWARE:表示硬件事件,通常很少使用。
聯合部分:根據 type 的值,使用不同的結構體來描述具體的輸入事件。
MOUSEINPUT:用于描述鼠標事件,如鼠標移動、鼠標點擊等。
KEYBDINPUT:用于描述鍵盤事件,如按鍵按下、按鍵釋放等。
HARDWAREINPUT:用于描述硬件事件。
示例代碼
模擬鍵盤按鍵
c
#include <windows.h>
#include <stdio.h>
重點就在于這兩個函數的使用
// 模擬按鍵按下
// 模擬按鍵按下
void pressKey(WORD keyCode) {INPUT input = {0};input.type = INPUT_KEYBOARD;input.ki.wVk = keyCode;SendInput(1, &input, sizeof(INPUT));}// 模擬按鍵釋放void releaseKey(WORD keyCode) {INPUT input = {0};input.type = INPUT_KEYBOARD;input.ki.wVk = keyCode;input.ki.dwFlags = KEYEVENTF_KEYUP;SendInput(1, &input, sizeof(INPUT));}int main() {// 按下 'A' 鍵pressKey('A');// 等待一段時間Sleep(500);// 釋放 'A' 鍵releaseKey('A');return 0;}模擬鼠標點擊c#include <windows.h>#include <stdio.h>int main() {INPUT input = {0};input.type = INPUT_MOUSE;input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;// 按下鼠標左鍵SendInput(1, &input, sizeof(INPUT));Sleep(500);input.mi.dwFlags = MOUSEEVENTF_LEFTUP;// 釋放鼠標左鍵SendInput(1, &input, sizeof(INPUT));return 0;}
注意事項
權限問題:在某些情況下,模擬輸入事件可能需要管理員權限,特別是在系統受保護的區域或應用程序中。
兼容性:SendInput 函數在現代 Windows 系統中具有良好的兼容性,但在一些特殊環境或虛擬機中可能會受到限制。
錯誤處理:在使用 SendInput 函數時,建議檢查返回值并使用 GetLastError 函數來處理可能的錯誤。