Visual Basic模擬按鍵_第1頁
Visual Basic模擬按鍵_第2頁
Visual Basic模擬按鍵_第3頁
Visual Basic模擬按鍵_第4頁
Visual Basic模擬按鍵_第5頁
已閱讀5頁,還剩16頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、VB模擬按鍵教程 簡單點說,虛擬碼就是我們經(jīng)常可以看到的像VK_A,VK_B這樣的常數(shù),比如鍵A的虛擬碼是65,寫成16進制就是&H41,注意,人們經(jīng)常用16進制來表示虛擬碼。當鍵盤驅動程序把掃描碼轉換為虛擬碼后,會把這個鍵盤操作的掃描碼和虛擬碼還有其它信息一起傳遞給操作系統(tǒng)。然后操作系統(tǒng)則會把這些信息封裝在一個消息中,并把這個鍵盤消息插入到消息列隊。最后,要是不出意外的話,這個鍵盤消息最終會被送到當前的活動窗口那里,活動窗口所在的應用程序接收到這個消息后,就知道鍵盤上哪個鍵被按下,也就可以決定該作出什么響應給用戶了。這個過程可以簡單的如下表示:用戶按下按鍵-鍵盤驅動程序將此

2、事件傳遞給操作系統(tǒng)-操作系統(tǒng)將鍵盤事件插入消息隊列-鍵盤消息被發(fā)送到當前活動窗口明白了這個過程,我們就可以編程實現(xiàn)在其中的某個環(huán)節(jié)來模擬鍵盤操作了。在VB中,有多種方法可以實現(xiàn)鍵盤模擬,我們就介紹幾種比較典型的。1.局部級模擬    從上面的流程可以看出,鍵盤事件是最終被送到活動窗口,然后才引起目標程序響應的。那么最直接的模擬方法就是:直接偽造一個鍵盤消息發(fā)給目標程序。哈哈,這實在是很簡單,windows提供了幾個這樣的API函數(shù)可以實現(xiàn)直接向目標程序發(fā)送消息的功能,常用的有SendMessage和PostMessage,它們的區(qū)別是PostMessage函數(shù)直接

3、把消息仍給目標程序就不管了,而SendMessage把消息發(fā)出去后,還要等待目標程序返回些什么東西才好。這里要注意的是,模擬鍵盤消息一定要用PostMessage函數(shù)才好,用SendMessage是不正確的(因為模擬鍵盤消息是不需要返回值的,不然目標程序會沒反應),切記切記!PostMessage函數(shù)的VB聲明如下:Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As L

4、ong, lParam As Any) As Long參數(shù)hwnd 是你要發(fā)送消息的目標程序上某個控件的句柄,參數(shù)wMsg 是消息的類型,表示你要發(fā)送什么樣的消息,最后wParam 和lParam 這兩個參數(shù)是隨消息附加的數(shù)據(jù),具體內容要由消息決定。再來看看wMsg 這個參數(shù),要模擬按鍵就靠這個了。鍵盤消息常用的有如下幾個:WM_KEYDOWN     表示一個普通鍵被按下WM_KEYUP       表示一個普通鍵被釋放WM_SYSKEYDOWN 表示一個系統(tǒng)鍵被按下,比如Alt鍵WM_SYS

5、KEYUP    表示一個系統(tǒng)鍵被釋放,比如Alt鍵如果你確定要發(fā)送以上幾個鍵盤消息,那么再來看看如何確定鍵盤消息中的wParam 和lParam 這兩個參數(shù)。在一個鍵盤消息中,wParam 參數(shù)的含義較簡單,它表示你要發(fā)送的鍵盤事件的按鍵虛擬碼,比如你要對目標程序模擬按下A鍵,那么wParam 參數(shù)的值就設為VK_A ,至于lParam 這個參數(shù)就比較復雜了,因為它包含了多個信息,一般可以把它設為0,但是如果你想要你的模擬更真實一些,那么建議你還是設置一下這個參數(shù)。那么我們就詳細了解一下lParam 吧。lParam 是一個long類型的參數(shù),它在內存中占4個字

6、節(jié),寫成二進制就是00000000 00000000 00000000 00000000 一共是32位,我們從右向左數(shù),假設最右邊那位為第0位(注意是從0而不是從1開始計數(shù)),最左邊的就是第31位,那么該參數(shù)的的0-15位表示鍵的發(fā)送次數(shù)等擴展信息,16-23位為按鍵的掃描碼,24-31位表示是按下鍵還是釋放鍵。大家一般習慣寫成16進制的,那么就應該是&H00 00 00 00 ,第0-15位一般為&H0001,如果是按下鍵,那么24-31位為&H00,釋放鍵則為&HC0,那么16-23位的掃描碼怎么會得呢?這需要用到一個API函數(shù)MapVirtualKey,這

7、個函數(shù)可以將虛擬碼轉換為掃描碼,或將掃描碼轉換為虛擬碼,還可以把虛擬碼轉換為對應字符的ASCII碼。它的VB聲明如下:Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long參數(shù)wCode 表示待轉換的碼,參數(shù)wMapType 表示從什么轉換為什么,如果是虛擬碼轉掃描碼,則wMapType 設置為0,如果是虛擬掃描碼轉虛擬碼,則wMapType 設置為1,如果是虛擬碼轉AS

8、CII碼,則wMapType 設置為2.相信有了這些,我們就可以構造鍵盤事件的lParam參數(shù)了。下面給出一個構造lParam參數(shù)的函數(shù):Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As LongFunction MakeKeyLparam(ByVal VirtualKey As Long, ByVal flag As Long) As Long'參數(shù)VirtualK

9、ey表示按鍵虛擬碼,flag表示是按下鍵還是釋放鍵,用WM_KEYDOWN和WM_KEYUP這兩個常數(shù)表示    Dim s As String    Dim Firstbyte As String    'lparam參數(shù)的24-31位    If flag = WM_KEYDOWN Then '如果是按下鍵        Firstbyte = "00" &

10、#160;  Else        Firstbyte = "C0"       '如果是釋放鍵    End If    Dim Scancode As Long    '獲得鍵的掃描碼    Scancode = MapVirtualKey(VirtualKey, 0)  &#

11、160; Dim Secondbyte As String   'lparam參數(shù)的16-23位,即虛擬鍵掃描碼    Secondbyte = Right("00" & Hex(Scancode), 2)    s = Firstbyte & Secondbyte & "0001" '0001為lparam參數(shù)的0-15位,即發(fā)送次數(shù)和其它擴展信息    MakeKeyLparam = Val("

12、;&H" & s)End Function這個函數(shù)像這樣調用,比如按下A鍵,那么lParam=MakeKeyLparam(VK_A,WM_KEYDOWN) ,很簡單吧。值得注意的是,即使你發(fā)送消息時設置了lParam參數(shù)的值,但是系統(tǒng)在傳遞消息時仍然可能會根據(jù)當時的情況重新設置該參數(shù),那么目標程序收到的消息中l(wèi)Param的值可能會和你發(fā)送時的有所不同。所以,如果你很懶的話,還是直接把它設為0吧,對大多數(shù)程序不會有影響的,呵呵。    好了,做完以上的事情,現(xiàn)在我們可以向目標程序發(fā)送鍵盤消息了。首先取得目標程序接受這個消息的控件的句柄,比如

13、目標句柄是12345,那么我們來對目標模擬按下并釋放A鍵,像這樣:(為了簡單起見,lParam這個參數(shù)就不構造了,直接傳0)PostMessage 12345,WM_KEYDOWN,VK_A,0&   '按下A鍵PostMessage 12345,WM_UP,VK_A,0&        '釋放A鍵好了,一次按鍵就完成了?,F(xiàn)在你可以迫不及待的打開記事本做實驗,先用FindWindowEx這類API函數(shù)找到記事本程序的句柄,再向它發(fā)送鍵盤消息,期望記事本里能詭異的自動出現(xiàn)字符

14、??墒悄泷R上就是失望了,咦,怎么一點反應也沒有?你欺騙感情啊55555555555555 不是的哦,接著往下看啊。一般目標程序都會含有多個控件,并不是每個控件都會對鍵盤消息作出反應,只有把鍵盤消息發(fā)送給接受它的控件才會得到期望的反應。那記事本來說,它的編輯框其實是個edit類,只有這個控件才對鍵盤事件有反應,如果只是把消息發(fā)給記事本的窗體,那是沒有用的。現(xiàn)在你找出記事本那個編輯框的句柄,比如是54321,那么寫如下代碼:PostMessage 54321,WM_KEYDOWN,VK_F1,0&   '按下F1鍵PostMessage 54321,WM_UP,

15、VK_F1,0&        '釋放F1鍵怎么樣,是不是打開了記事本的“幫助”信息?這說明目標程序已經(jīng)收到了你發(fā)的消息,還不錯吧可以馬上新問題就來了,你想模擬向記事本按下A這個鍵,好在記事本里自動輸入字符,可是,沒有任何反應!這是怎么一回事呢?原來,如果要向目標程序發(fā)送字符,光靠WM_KEYDOWN和WM_UP這兩個事件還不行,還需要一個事件:WM_CHAR,這個消息表示一個字符,程序需靠它看來接受輸入的字符。一般只有A,B,C等這樣的按鍵才有WM_CHAR消息,別的鍵(比如方向鍵和功能鍵)是沒有這個消息的

16、,WM_CHAR消息一般發(fā)生在WM_KEYDOWN消息之后。WM_CHAR消息的lParam參數(shù)的含義與其它鍵盤消息一樣,而它的wParam則表示相應字符的ASCII編碼(可以輸入中文的哦_),現(xiàn)在你可以寫出一個完整的向記事本里自動寫入字符的程序了,下面是一個例子,并附有這些消息常數(shù)的具體值:Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam

17、As Any) As LongDeclare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As LongPublic Const WM_KEYDOWN = &H100Public Const WM_KEYUP = &H101Public Const WM_CHAR = &H102Public Const VK_A = &H41 Function MakeKey

18、Lparam(ByVal VirtualKey As Long, ByVal flag As Long) As Long    Dim s As String    Dim Firstbyte As String    'lparam參數(shù)的24-31位    If flag = WM_KEYDOWN Then '如果是按下鍵        Firstbyte = "00"

19、    Else        Firstbyte = "C0"       '如果是釋放鍵    End If    Dim Scancode As Long    '獲得鍵的掃描碼    Scancode = MapVirtualKey(VirtualKey, 0) &

20、#160;  Dim Secondbyte As String   'lparam參數(shù)的16-23位,即虛擬鍵掃描碼    Secondbyte = Right("00" & Hex(Scancode), 2)    s = Firstbyte & Secondbyte & "0001" '0001為lparam參數(shù)的0-15位,即發(fā)送次數(shù)和其它擴展信息    MakeKeyLparam = Va

21、l("&H" & s)End FunctionPrivate Sub Form_Load()    dim hwnd as long    hwnd = XXXXXX 'XXXXX表示記事本編輯框的句柄    PostMessage hwnd,WM_KEYDOWN,VK_A,MakeKeyLparam(VK_A,WM_KEYDOWN) '按下A鍵    PostMessage hwnd,WM_CHAR,ASC("A

22、"),MakeKeyLparam(VK_A,WM_KEYDOWN) '輸入字符A    PostMessage hwnd,WM_UP,VK_A,MakeKeyLparam(VK_A,WM_UP)       '釋放A鍵End Sub這就是通過局部鍵盤消息來模擬按鍵。這個方法有一個極大的好處,就是:它可以實現(xiàn)后臺按鍵,也就是說他對你的前臺操作不會有什么影響。比如,你可以用這個方法做個程序在游戲中模擬按鍵來不斷地執(zhí)行某些重復的操作,而你則一邊喝茶一邊與QQ上的MM們聊得火熱,它絲毫不

23、會影響你的前臺操作。無論目標程序是否獲得焦點都沒有影響,這就是后臺模擬按鍵的原理啦'2.全局級模擬    你會發(fā)現(xiàn),用上面的方法模擬按鍵并不是對所有程序都有效的,有的程序啊,你向它發(fā)了一大堆消息,可是它卻一點反應也沒有。這是怎么回事呢?這就要看具體的情況了,有些程序(特別是一些游戲)出于某些原因,會禁止用戶對它使用模擬按鍵程序,這個怎么實現(xiàn)呢?比如可以在程序中檢查一下,如果發(fā)現(xiàn)自己不是活動窗口,就不接受鍵盤消息?;蛘咦屑殭z查一下收到的鍵盤消息,你會發(fā)現(xiàn)真實的按鍵和模擬的按鍵消息總是有一些小差別,從這些小差別上,目標程序就能判斷出:這是假的!是偽造的!因此,

24、如果用PostMessage發(fā)送局部消息模擬按鍵不成功的話,你可以試一試全局級的鍵盤消息,看看能不能騙過目標程序。模擬全局鍵盤消息常見的可以有以下一些方法:(1) 用API函數(shù)keybd_event,這個函數(shù)可以用來模擬一個鍵盤事件,它的VB聲明為:Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)參數(shù)bVk表示要模擬的按鍵的虛擬碼,bScan表示該按鍵的掃描碼(一般可以傳

25、0),dwFlags表示是按下鍵還是釋放鍵(按下鍵為0,釋放鍵為2),dwExtraInfo是擴展標志,一般沒有用。比如要模擬按下A鍵,可以這樣:Const KEYEVENTF_KEYUP = &H2keybd_event VK_A, 0, 0, 0   '按下A鍵keybd_event VK_A, 0, KEYEVENTF_KEYUP, 0   '釋放A鍵注意有時候按鍵的速度不要太快,否則會出問題,可以用API函數(shù)Sleep來進行延時,聲明如下:Declare Sub Sleep Lib "kernel32"

26、 (ByVal dwMilliseconds As Long)參數(shù)dwMilliseconds表示延時的時間,以毫秒為單位。那么如果要模擬按下功能鍵怎么做呢?比如要按下Ctrl+C實現(xiàn)拷貝這個功能,可以這樣:keybd_event VK_Ctrl, 0, 0, 0   '按下Ctrl鍵keybd_event VK_C, 0, 0, 0      '按下C鍵Sleep 500            &#

27、39;延時500毫秒keybd_event VK_C, 0, KEYEVENTF_KEYUP, 0   '釋放C鍵keybd_event VK_Ctrl, 0, KEYEVENTF_KEYUP, 0   '釋放Ctrl鍵好了,現(xiàn)在你可以試試是不是可以騙過目標程序了,這個函數(shù)對大部分的窗口程序都有效,可是仍然有一部分游戲對它產(chǎn)生的鍵盤事件熟視無睹,這時候,你就要用上bScan這個參數(shù)了。一般的,bScan都傳0,但是如果目標程序是一些DirectX游戲,那么你就需要正確使用這個參數(shù)傳入掃描碼,用了它可以產(chǎn)生正確的硬件事件消息,以被游戲識別。

28、這樣的話,就可以寫成這樣: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函數(shù)來模擬鍵盤事件。除了這個函數(shù),SendInput函數(shù)也可以模擬全局鍵盤事件。SendInput可以直接把一條消息插入到消息隊列中,算是比較底層的了。它的VB聲明如下:Declare Function SendInput Lib "

29、;user32.dll" (ByVal nInputs As Long, pInputs As GENERALINPUT, ByVal cbSize As Long) As Long參數(shù): nlnprts:定義plnputs指向的結構的數(shù)目。plnputs:指向INPUT結構數(shù)組的指針。每個結構代表插人到鍵盤或鼠標輸入流中的一個事件。cbSize:定義INPUT結構的大小。若cbSize不是INPUT結構的大小,則函數(shù)調用失敗。返回值:函數(shù)返回被成功地插人鍵盤或鼠標輸入流中的事件的數(shù)目。若要獲得更多的錯誤信息,可以調用GetlastError函數(shù)。備注:Sendlnput函數(shù)將INP

30、UT結構中的事件順序地插入鍵盤或鼠標的輸入流中。這些事件與用戶插入的(用鼠標或鍵盤)或調用keybd_event,mouse_event,或另外的Sendlnput插人的鍵盤或鼠標的輸入流不兼容。嗯,這個函數(shù)用起來蠻復雜的,因為它的參數(shù)都是指針一類的東西。要用它來模擬鍵盤輸入,先要構造一組數(shù)據(jù)結構,把你要模擬的鍵盤消息裝進去,然后傳給它。為了方便起見,把它做在一個過程里面,要用的時候直接調用好了,代碼如下:Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As GENERA

31、LINPUT, ByVal cbSize As Long) As LongDeclare 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 ByteEnd TypeType KEYBDINPUTwVk As IntegerwScan As IntegerdwFla

32、gs As Longtime As LongdwExtraInfo As LongEnd TypeConst INPUT_KEYBOARD = 1Sub MySendKey(bkey As Long)'參數(shù)bkey傳入要模擬按鍵的虛擬碼即可模擬按下指定鍵Dim GInput(0 To 1) As GENERALINPUTDim KInput As KEYBDINPUTKInput.wVk = bkey '你要模擬的按鍵KInput.dwFlags = 0 '按下鍵標志GInput(0).dwType = INPUT_KEYBOARDCopyMemory GInput(0

33、).xi(0), KInput, Len(KInput) '這個函數(shù)用來把內存中KInput的數(shù)據(jù)復制到GInputKInput.wVk = bkey KInput.dwFlags = KEYEVENTF_KEYUP ' 釋放按鍵GInput(1).dwType = INPUT_KEYBOARD ' 表示該消息為鍵盤消息CopyMemory GInput(1).xi(0), KInput, Len(KInput)'以上工作把按下鍵和釋放鍵共2條鍵盤消息加入到GInput數(shù)據(jù)結構中SendInput 2, GInput(0), Len(GInput(0) 

34、;   '把GInput中存放的消息插入到消息列隊End Sub    除了以上這些,用全局鉤子也可以模擬鍵盤消息。如果你對windows中消息鉤子的用法已經(jīng)有所了解,那么你可以通過設置一個全局HOOK來模擬鍵盤消息,比如,你可以用WH_JOURNALPLAYBACK這個鉤子來模擬按鍵。WH_JOURNALPLAYBACK是一個系統(tǒng)級的全局鉤子,它和WH_JOURNALRECORD的功能是相對的,常用它們來記錄并回放鍵盤鼠標操作。WH_JOURNALRECORD鉤子用來將鍵盤鼠標的操作忠實地記錄下來,記錄下來的信息可以保存到文件中,而W

35、H_JOURNALPLAYBACK則可以重現(xiàn)這些操作。當然亦可以單獨使用WH_JOURNALPLAYBACK來模擬鍵盤操作。你需要首先聲明SetWindowsHookEx函數(shù),它可以用來安裝消息鉤子: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_JOURNA

36、LPLAYBACK這個鉤子,然后你需要自己寫一個鉤子函數(shù),在系統(tǒng)調用它時,把你要模擬的事件傳遞給鉤子參數(shù)lParam所指向的EVENTMSG區(qū)域,就可以達到模擬按鍵的效果。不過用這個鉤子模擬鍵盤事件有一個副作用,就是它會鎖定真實的鼠標鍵盤,不過如果你就是想在模擬的時候不會受真實鍵盤操作的干擾,那么用用它倒是個不錯的主意。3.驅動級模擬    如果上面的方法你都試過了,可是你發(fā)現(xiàn)目標程序卻仍然頑固的不接受你模擬的消息,寒還好,我還剩下最后一招,這就是驅動級模擬:直接讀寫鍵盤的硬件端口!    有一些使用DirectX接口的游戲程序,它們

37、在讀取鍵盤操作時繞過了windows的消息機制,而使用DirectInput.這是因為有些游戲對實時性控制的要求比較高,比如賽車游戲,要求以最快速度響應鍵盤輸入。而windows消息由于是隊列形式的,消息在傳遞時會有不少延遲,有時1秒鐘也就傳遞十幾條消息,這個速度達不到游戲的要求。而DirectInput則繞過了windows消息,直接與鍵盤驅動程序打交道,效率當然提高了不少。因此也就造成,對這樣的程序無論用PostMessage或者是keybd_event都不會有反應,因為這些函數(shù)都在較高層。對于這樣的程序,只好用直接讀寫鍵盤端口的方法來模擬硬件事件了。要用這個方法來模擬鍵盤,需要先了解一下

38、鍵盤編程的相關知識。在DOS時代,當用戶按下或者放開一個鍵時,就會產(chǎn)生一個鍵盤中斷(如果鍵盤中斷是允許的),這樣程序會跳轉到BIOS中的鍵盤中斷處理程序去執(zhí)行。打開windows的設備管理器,可以查看到鍵盤控制器由兩個端口控制。其中&H60是數(shù)據(jù)端口,可以讀出鍵盤數(shù)據(jù),而&H64是控制端口,用來發(fā)出控制信號。也就是,從&H60號端口可以讀此鍵盤的按鍵信息,當從這個端口讀取一個字節(jié),該字節(jié)的低7位就是按鍵的掃描碼,而高1位則表示是按下鍵還是釋放鍵。當按下鍵時,最高位為0,稱為通碼,當釋放鍵時,最高位為1,稱為斷碼。既然從這個端口讀數(shù)據(jù)可以獲得按鍵信息,那么向這個端口寫入數(shù)

39、據(jù)就可以模擬按鍵了!用過QbASIC4.5的朋友可能知道,QB中有個OUT命令可以向指定端口寫入數(shù)據(jù),而INP函數(shù)可以讀取指定端口的數(shù)據(jù)。那我們先看看如果用QB該怎么寫代碼:假如你想模擬按下一個鍵,這個鍵的掃描碼為&H50,那就這樣OUT &H64,&HD2   '把數(shù)據(jù)&HD2發(fā)送到&H64端口。這是一個KBC指令,表示將要向鍵盤寫入數(shù)據(jù)OUT &H60,&H50   '把掃描碼&H50發(fā)送到&H60端口,表示模擬按下掃描碼為&H50的這個鍵那么要釋放這個鍵

40、呢?像這樣,發(fā)送該鍵的斷碼:OUT &H64,&HD2   '把數(shù)據(jù)&HD2發(fā)送到&H64端口。這是一個KBC指令,表示將要向鍵盤寫入數(shù)據(jù)OUT &H60,(&H50 OR &H80)   '把掃描碼&H50與數(shù)據(jù)&H80進行或運算,可以把它的高位置1,得到斷碼,表示釋放這個鍵    好了,現(xiàn)在的問題就是在VB中如何向端口寫入數(shù)據(jù)了。因為在windows中,普通應用程序是無權操作端口的,于是我們就需要一個驅動程序來幫助我們實現(xiàn)。在這里我們

41、可以使用一個組件WINIO來完成讀寫端口操作。什么是WINIO?WINIO是一個全免費的、無需注冊的、含源程序的WINDOWS2000端口操作驅動程序組件(可以到上去下載)。它不僅可以操作端口,還可以操作內存;不僅能在VB下用,還可以在DELPHI、VC等其它環(huán)境下使用,性能特別優(yōu)異。下載該組件,解壓縮后可以看到幾個文件夾,其中Release文件夾下的3個文件就是我們需要的,這3個文件是WinIo.sys(用于win xp下的驅動程序),WINIO.VXD(用于win 98下的驅動程序),WinIo.dll(封裝函數(shù)的動態(tài)鏈接庫),我們只需要調用WinIo.dll中的函數(shù),然后WinIo.dl

42、l就會安裝并調用驅動程序來完成相應的功能。值得一提的是這個組件完全是綠色的,無需安裝,你只需要把這3個文件復制到與你的程序相同的文件夾下就可以使用了。用法很簡單,先用里面的InitializeWinIo函數(shù)安裝驅動程序,然后就可以用GetPortVal來讀取端口或者用SetPortVal來寫入端口了。好,讓我們來做一個驅動級的鍵盤模擬吧。先把winio的3個文件拷貝到你的程序的文件夾下,然后在VB中新建一個工程,添加一個模塊,在模塊中加入下面的winio函數(shù)聲明:Declare Function MapPhysToLin Lib "WinIo.dll" (ByVal Phy

43、sAddr As Long, ByVal PhysSize As Long, ByRef PhysMemHandle) As LongDeclare Function UnmapPhysicalMemory Lib "WinIo.dll" (ByVal PhysMemHandle, ByVal LinAddr) As BooleanDeclare Function GetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByRef PhysVal As Long) As BooleanDeclare Fu

44、nction SetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysVal As Long) As BooleanDeclare Function GetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByRef PortVal As Long, ByVal bSize As Byte) As BooleanDeclare Function SetPortVal Lib "WinIo.dll" (ByVal

45、PortAddr As Integer, ByVal PortVal As Long, ByVal bSize As Byte) As BooleanDeclare Function InitializeWinIo Lib "WinIo.dll" () As BooleanDeclare Function ShutdownWinIo Lib "WinIo.dll" () As BooleanDeclare Function InstallWinIoDriver Lib "WinIo.dll" (ByVal DriverPath As

46、String, ByVal Mode As Integer) As BooleanDeclare Function RemoveWinIoDriver Lib "WinIo.dll" () As Boolean' -以上是WINIO函數(shù)聲明-Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long'-以上是WIN32 API函數(shù)聲明-再添

47、加下面這個過程:Sub KBCWait4IBE()   '等待鍵盤緩沖區(qū)為空Dim dwVal As LongDoGetPortVal &H64, dwVal, 1'這句表示從&H64端口讀取一個字節(jié)并把讀出的數(shù)據(jù)放到變量dwVal中'GetPortVal函數(shù)的用法是GetPortVal 端口號,存放讀出數(shù)據(jù)的變量,讀入的長度Loop While (dwVal And &H2)End Sub上面的是一個根據(jù)KBC規(guī)范寫的過程,它的作用是在向鍵盤端口寫入數(shù)據(jù)前等待一段時間,后面將會用到。然后再添加如下過程,這2個過程用來模擬按鍵

48、:Public Const KBC_KEY_CMD = &H64    '鍵盤命令端口Public Const KBC_KEY_DATA = &H60   '鍵盤數(shù)據(jù)端口Sub MyKeyDown(ByVal vKeyCoad As Long)   '這個用來模擬按下鍵,參數(shù)vKeyCoad傳入按鍵的虛擬碼Dim btScancode As LongbtScancode = MapVirtualKey(vKeyCoad, 0)    KBCWait4IBE

49、   '發(fā)送數(shù)據(jù)前應該先等待鍵盤緩沖區(qū)為空    SetPortVal KBC_KEY_CMD, &HD2, 1     '發(fā)送鍵盤寫入命令'SetPortVal函數(shù)用于向端口寫入數(shù)據(jù),它的用法是SetPortVal 端口號,欲寫入的數(shù)據(jù),寫入數(shù)據(jù)的長度    KBCWait4IBE    SetPortVal KBC_KEY_DATA, btScancode, 1 '寫入按鍵信息,按下鍵 

50、60;  End SubSub MyKeyUp(ByVal vKeyCoad As Long)   '這個用來模擬釋放鍵,參數(shù)vKeyCoad傳入按鍵的虛擬碼Dim btScancode As LongbtScancode = MapVirtualKey(vKeyCoad, 0)    KBCWait4IBE   '等待鍵盤緩沖區(qū)為空    SetPortVal KBC_KEY_CMD, &HD2, 1 '發(fā)送鍵盤寫入命令  

51、0; KBCWait4IBE    SetPortVal KBC_KEY_DATA, (btScancode Or &H80), 1 '寫入按鍵信息,釋放鍵End Sub定義了上面的過程后,就可以用它來模擬鍵盤輸入了。在窗體模塊中添加一個定時器控件,然后加入以下代碼:Private Sub Form_Load()If InitializeWinIo = False Then   '用InitializeWinIo函數(shù)加載驅動程序,如果成功會返回true,否則返回false    MsgBox

52、 "驅動程序加載失敗!"    Unload MeEnd IfTimer1.Interval=3000Timer1.Enabled=TrueEnd SubPrivate Sub Form_Unload(Cancel As Integer)ShutdownWinIo '程序結束時記得用ShutdownWinIo函數(shù)卸載驅動程序End SubPrivate Sub Timer1_Timer()Dim VK_A as Long = &H41 MyKeyDown VK_A    MyKeyUp VK_A&#

53、160;   '模擬按下并釋放A鍵End Sub/quote運行上面的程序,就會每隔3秒鐘模擬按下一次A鍵,試試看,怎么樣,是不是對所有程序都有效果了?需要注意的問題:要在VB的調試模式下使用WINIO,需要把那3個文件拷貝到VB的安裝目錄中。鍵盤上有些鍵屬于擴展鍵(比如鍵盤上的方向鍵就是擴展鍵),對于擴展鍵不應該用上面的MyKeyDown和MyKeyUp過程來模擬,可以使用下面的2個過程來準確模擬擴展鍵:Sub MyKeyDownEx(ByVal vKeyCoad As Long)   '模擬擴展鍵按下,參數(shù)vKeyCoad是擴展鍵的虛擬碼Dim btScancode As LongbtScancode = MapVirtualKey(vKeyCoad, 0)    KBCWait4IBE&#

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論