向任意應用程式(包括後臺的)傳送任意按鍵訊息

wangjieest發表於2011-11-10
向任意應用程式(包括後臺的)傳送任意按鍵訊息(包括普通字元鍵、功能鍵、Shift/Control/Alt加任意按鍵的組合鍵),以實現自動執行特定功能,是一個用途很廣、很有實用價值的功能,很多人都受困於此,不得其解,本人也遇到這種需求並受阻。剛開始查了很多資料和網上網友的解決方案,有些能起到一定作用,但也有許多方案經試驗證實不可行。尤其是關於傳送 Shift/Control/Alt 加任意按鍵的組合鍵這個問題,沒有發現一個可行的方案,例如以下程式碼並不能向指定Window(hwnd)傳送 Ctrl+C:
    PostMessage hwnd,WM_KEYDOWN,VK_CONTROL,&H001D0001   '按下Ctrl鍵
    PostMessage hwnd,WM_KEYDOWN,VK_C,&H002E0001         '按下C鍵
    PostMessage hwnd,WM_KEYUP,VK_C,&HC02E0001           '釋放C鍵
    PostMessage hwnd,WM_KEYUP,VK_CONTROL,&HC01D0001     '釋放Ctrl鍵
上例只能傳送一個小寫字母c。
以下程式碼雖可以模擬 Ctrl+C 按鍵,但卻不能向指定的後臺視窗傳送:
    keybd_event VK_Ctrl, 0, 0, 0 '按下Ctrl鍵
    keybd_event VK_C, 0, 0, 0 '按下C鍵
    keybd_event VK_C, 0, KEYEVENTF_KEYUP, 0 '釋放C鍵
    keybd_event VK_Ctrl, 0, KEYEVENTF_KEYUP, 0 '釋放Ctrl鍵
難道真的沒有解決這個問題的辦法嗎?我想這個應該是可以做到的呀!後來經過反覆的研究Windows的訊息機制和鍵盤輸入系統呼叫的資料,終於找到了解決方案,並經試驗成功證實。自己也是曾經受困於此,終得其解,不敢獨享,現拿出來獻給廣大同需此求的朋友,也讓這個問題不再是少數“高手”們獨享的祕籍。
要實現向任意應用程式視窗傳送模擬的按鍵,在不需啟用該應用程式使其獲得輸入焦點的情況下,首先必須取得要接收按鍵的視窗控制程式碼,這要用到Windows API FindWindow 及 FindWindowEx,首先用 FindWindow 取得應用程式頂層(Top Level)視窗的控制程式碼,然後再用 FindWindowEx 取得要接收按鍵的子視窗或控制元件的控制程式碼,因為應用程式頂層視窗不一定就是接受按鍵的視窗(如“NotePad.exe”記事本程式,實際接受按鍵的視窗是Notepad主視窗下的Edit控制元件),可以通過ClassID或Caption來查詢。假設目標視窗的控制程式碼已取得(hwnd),然後要用PostMessage向該視窗傳送按鍵訊息,對於普通字元鍵,直接用WM_CHAR訊息最簡單,如下:
    PostMessage hwnd, WM_CHAR, Asc("A"), 0   ' 傳送一個 A 字元
對於非普通字元按鍵,如功能鍵、方向鍵等,要用 WM_KEYDOWN、WM_KEYUP 訊息,如下:
    PostMessage hWndMsg, WM_KEYDOWN, VK_ESCAPE, &H00010001  ' 模擬按下 Esc 鍵
    PostMessage hWndMsg, WM_KEYUP, VK_ESCAPE, &HC0010001    ' 模擬抬起 Esc 鍵
以上最後一個引數(lParam)低16位(0001)表示按鍵一次,高8位00表示按下,C0表示抬起,次高8位(01)表示該鍵的掃描碼,可用 API MapVirtualKey(VirtualKey, 0)取得(注意:掃描碼在各系統可能會不同,在此以具體數值示例,實際應用MapVirtualKey取得)。
下面要講Shift/Control/Alt修飾鍵與其它按鍵的組合怎樣傳送,對於Shift和Control用以下方式(用到 API keybd_event):
    keybd_event VK_SHIFT, &H2A, 0, 0  ' 模擬按下SHIFT鍵,&H2A是VK_SHIFT的掃描碼
    PostMessage hWndMsg, WM_KEYDOWN, VK_A, &H001E0001 ' 模擬按下 A 鍵,SHIFT+A產生一個大寫A字元
    PostMessage hWndMsg, WM_KEYUP, VK_A, &HC01E0001   ' 模擬抬起 A 鍵
    keybd_event VK_SHIFT, &H2A, KEYEVENTF_KEYUP, 0    ' 模擬抬起 SHIFT 鍵
以上VK_SHIFT(掃描碼2A)換成VK_CONTROL(掃描碼1D)就可以實現Ctrl組合鍵,VK_A(掃描碼1E)也可以換成任意功能鍵,如VK_F4(掃描碼3E)。
對於Alt修飾鍵比較特別,它屬於系統按鍵,要用 WM_SYSKEYDOWN/WM_SYSKEYUP 訊息,如下:
    PostMessage hWndMsg, WM_SYSKEYDOWN, VK_F4, &H003E0001 Or &H20000000 ' 模擬按下 Alt+F4
    PostMessage hWndMsg, WM_SYSKEYUP, VK_F4, &HC03E0001 Or &H20000000   '  模擬抬起 Alt+F4
                           ' &H20000000 為 context code 位,置 1 表示 Alt 鍵被按下

至此,大功告成!祝各位心情愉快!

相關文章