2.全域性級模擬
你會發現,用上面的方法模擬按鍵並不是對所有程式都有效的,有的程式啊,你向它發了一大堆訊息,可是它卻一點反應也沒有。這是怎麼回事呢?這就要看具體的情況了,有些程式(特別是一些遊戲)出於某些原因,會禁止使用者對它使用模擬按鍵程式,這個怎麼實現呢?比如可以在程式中檢查一下,如果發現自己不是活動視窗,就不接受鍵盤訊息。或者仔細檢查一下收到的鍵盤訊息,你會發現真實的按鍵和模擬的按鍵訊息總是有一些小差別,從這些小差別上,目標程式就能判斷出:這是假的!是偽造的!!因此,如果用postmessage傳送區域性訊息模擬按鍵不成功的話,你可以試一試全域性級的鍵盤訊息,看看能不能騙過目標程式。
模擬全域性鍵盤訊息常見的可以有以下一些方法:
(1) 用api函式keybd_event,這個函式可以用來模擬乙個鍵盤事件,它的vb宣告為:
declare sub keybd_event lib "user32" (byval bvk as byte, byval bscan as byte, byval dwflags as long, byval dwextrainfo as long)
引數bvk表示要模擬的按鍵的偽程式碼,bscan表示該按鍵的掃瞄碼(一般可以傳0),dwflags表示是按下鍵還是釋放鍵(按下鍵為0,釋放鍵為2),dwextrainfo是擴充套件標誌,一般沒有用。比如要模擬按下a鍵,可以這樣:
const keyeventf_keyup = &h2
keybd_event vk_a, 0, 0, 0 '按下a鍵
keybd_event vk_a, 0, keyeventf_keyup, 0 '釋放a鍵
注意有時候按鍵的速度不要太快,否則會出問題,可以用api函式sleep來進行延時,宣告如下:
declare sub sleep lib "kernel32" (byval dwmilliseconds as long)
引數dwmilliseconds表示延時的時間,以毫秒為單位。
那麼如果要模擬按下功能鍵怎麼做呢?比如要按下ctrl+c實現拷貝這個功能,可以這樣:
keybd_event vk_ctrl, 0, 0, 0 '按下ctrl鍵
keybd_event vk_c, 0, 0, 0 '按下c鍵
sleep 500 '延時500毫秒
keybd_event vk_c, 0, keyeventf_keyup, 0 '釋放c鍵
keybd_event vk_ctrl, 0, keyeventf_keyup, 0 '釋放ctrl鍵
好了,現在你可以試試是不是可以騙過目標程式了,這個函式對大部分的視窗程式都有效,可是仍然有一部分遊戲對它產生的鍵盤事件熟視無睹,這時候,你就要用上bscan這個引數了。一般的,bscan都傳0,但是如果目標程式是一些directx遊戲,那麼你就需要正確使用這個引數傳入掃瞄碼,用了它可以產生正確的硬體事件訊息,以被遊戲識別。這樣的話,就可以寫成這樣:
keybd_event vk_a, mapvirtualkey(vk_a, 0), 0, 0 '按下a鍵
keybd_event vk_a, mapvirtualkey(vk_a, 0), keyeventf_keyup, 0 '釋放a鍵
以上就是用keybd_event函式來模擬鍵盤事件。除了這個函式,sendinput函式也可以模擬全域性鍵盤事件。sendinput可以直接把一條訊息插入到訊息佇列中,算是比較底層的了。它的vb宣告如下:
declare function sendinput lib "user32.dll" (byval ninputs as long, pinputs as generalinput, byval cbsize as long) as long
引數:
nlnprts:定義plnputs指向的結構的數目。
plnputs:指向input結構陣列的指標。每個結構代表插人到鍵盤或滑鼠輸入流中的乙個事件。
cbsize:定義input結構的大小。若cbsize不是input結構的大小,則函式呼叫失敗。
返回值:函式返回被成功地插人鍵盤或滑鼠輸入流中的事件的數目。若要獲得更多的錯誤資訊,可以呼叫getlasterror函式。
備註:sendlnput函式將input結構中的事件順序地插入鍵盤或滑鼠的輸入流中。這些事件與使用者插入的(用滑鼠或鍵盤)或呼叫keybd_event,mouse_event,或另外的sendlnput插人的鍵盤或滑鼠的輸入流不相容。
嗯,這個函式用起來蠻複雜的,因為它的引數都是指標一類的東西。要用它來模擬鍵盤輸入,先要構造一組資料結構,把你要模擬的鍵盤訊息裝進去,然後傳給它。為了方便起見,把它做在乙個過程裡面,要用的時候直接呼叫好了,**如下:
declare function sendinput lib "user32.dll" (byval ninputs as long, pinputs as generalinput, byval cbsize as long) as long
declare sub copymemory lib "kernel32" alias "rtlmovememory" (pdst as any, psrc as any, byval bytelen as long)
type generalinput
dwtype as long
xi(0 to 23) as byte
end type
type keybdinput
wvk as integer
wscan as integer
dwflags as long
time as long
dwextrainfo as long
end type
const input_keyboard = 1
sub mysendkey(bkey as long)
'引數bkey傳入要模擬按鍵的偽程式碼即可模擬按下指定鍵
dim ginput(0 to 1) as generalinput
dim kinput as keybdinput
kinput.wvk = bkey '你要模擬的按鍵
kinput.dwflags = 0 '按下鍵標誌
ginput(0).dwtype = input_keyboard
copymemory ginput(0).xi(0), kinput, len(kinput) '這個函式用來把記憶體中kinput的資料複製到ginput
kinput.wvk = bkey
kinput.dwflags = keyeventf_keyup ' 釋放按鍵
ginput(1).dwtype = input_keyboard ' 表示該訊息為鍵盤訊息
copymemory ginput(1).xi(0), kinput, len(kinput)
'以上工作把按下鍵和釋放鍵共2條鍵盤訊息加入到ginput資料結構中
sendinput 2, ginput(0), len(ginput(0)) '把ginput中存放的訊息插入到訊息列隊
end sub
除了以上這些,用全域性鉤子也可以模擬鍵盤訊息。如果你對windows中訊息鉤子的用法已經有所了解,那麼你可以通過設定乙個全域性hook來模擬鍵盤訊息,比如,你可以用wh_journalplayback這個鉤子來模擬按鍵。wh_journalplayback是乙個系統級的全域性鉤子,它和wh_journalrecord的功能是相對的,常用它們來記錄並回放鍵盤滑鼠操作。wh_journalrecord鉤子用來將鍵盤滑鼠的操作忠實地記錄下來,記錄下來的資訊可以儲存到檔案中,而wh_journalplayback則可以重現這些操作。當然亦可以單獨使用wh_journalplayback來模擬鍵盤操作。你需要首先宣告setwindowshookex函式,它可以用來安裝訊息鉤子:
declare function setwindowshookex lib "user32" alias "setwindowshookexa" (byval idhook as long,byval lpfn as long, byval hmod as long, byval dwthreadid as long) as long
先安裝wh_journalplayback這個鉤子,然後你需要自己寫乙個鉤子函式,在系統呼叫它時,把你要模擬的事件傳遞給鉤子引數lparam所指向的eventmsg區域,就可以達到模擬按鍵的效果。不過用這個鉤子模擬鍵盤事件有乙個***,就是它會鎖定真實的滑鼠鍵盤,不過如果你就是想在模擬的時候不會受真實鍵盤操作的干擾,那麼用用它倒是個不錯的主意。
模擬鍵盤按鍵
模擬全域性按鍵可以用keybd event,sendinput來完成,下面是模擬一次caps lock 按鍵時兩個api函式的實現方法 keybd event keybd event vk capital,0,keyeventf extendedkey 0,0 key down keybd even...
模擬鍵盤按鍵
textbox1.focus sendkeys.send v 模擬鍵盤按鍵ctrl v 貼上 鍵 backspace 或或break caps lock del或delete 或向下鍵 endenter 或 esc help home ins或insert 或向左鍵 num lock page do...
手機鍵盤 模擬
題目描述 按照手機鍵盤輸入字母的方式,計算所花費的時間 如 a,b,c都在 1 鍵上,輸入a只需要按一次,輸入c需要連續按三次。如果連續兩個字元不在同乙個按鍵上,則可直接按,如 ad需要按兩下,kz需要按6下 如果連續兩字元在同乙個按鍵上,則兩個按鍵之間需要等一段時間,如ac,在按了a之後,需要等一...