先用裡面的InitializeWinIo函式安裝驅動程式,然後就可以用GetPortVal來讀取埠或者用SetPortVal來寫入埠了。好,讓我們來做一個驅動級的鍵盤模擬吧。先把winio的3個檔案複製到你的程式的資料夾下,然後在VB中新建一個工程,新增一個模組,在模組中加入下面的winio函式宣告:
Declare Function MapPhysToLin Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysSize As Long, ByRef PhysMemHandle) As Long
Declare Function UnmapPhysicalMemory Lib "WinIo.dll" (ByVal PhysMemHandle, ByVal LinAddr) As Boolean
Declare Function GetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByRef PhysVal As Long) As Boolean
Declare Function SetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysVal As Long) As Boolean
Declare Function GetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByRef PortVal As Long, ByVal bSize As Byte) As Boolean
Declare Function SetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByVal PortVal As Long, ByVal bSize As Byte) As Boolean
Declare Function InitializeWinIo Lib "WinIo.dll" () As Boolean
Declare Function ShutdownWinIo Lib "WinIo.dll" () As Boolean
Declare Function InstallWinIoDriver Lib "WinIo.dll" (ByVal DriverPath As String, ByVal Mode As Integer) As Boolean
Declare Function RemoveWinIoDriver Lib "WinIo.dll" () As Boolean
" ------------------------------------以上是WINIO函式宣告-------------------------------------------
Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long
"-----------------------------------以上是WIN32 API函式宣告-----------------------------------------
再新增下面這個過程:
Sub KBCWait4IBE() "等待鍵盤緩衝區為空
Dim dwVal As Long
Do
GetPortVal &H64, dwVal, 1
"這句表示從&H64埠讀取一個位元組並把讀出的資料放到變數dwVal中
"GetPortVal函式的用法是GetPortVal 埠號,存放讀出資料的變數,讀入的長度
Loop While (dwVal And &H2)
End Sub
上面的是一個根據KBC規範寫的過程,它的作用是在向鍵盤埠寫入資料前等待一段時間,後面將會用到。
然後再新增如下過程,這2個過程用來模擬按鍵:
Public Const KBC_KEY_CMD = &H64 "鍵盤命令埠
Public Const KBC_KEY_DATA = &H60 "鍵盤資料埠
Sub MyKeyDown(ByVal vKeyCoad As Long)
"這個用來模擬按下鍵,引數vKeyCoad傳入按鍵的虛擬碼
Dim btScancode As Long
btScancode = MapVirtualKey(vKeyCoad, 0)
KBCWait4IBE "傳送資料前應該先等待鍵盤緩衝區為空
SetPortVal KBC_KEY_CMD, &HD2, 1 "傳送鍵盤寫入命令
"SetPortVal函式用於向埠寫入資料,它的用法是SetPortVal 埠號,欲寫入的資料,寫入資料的長度
KBCWait4IBE
SetPortVal KBC_KEY_DATA, btScancode, 1 "寫入按鍵資訊,按下鍵
Sub MyKeyUp(ByVal vKeyCoad As Long)
"這個用來模擬釋放鍵,引數vKeyCoad傳入按鍵的虛擬碼
KBCWait4IBE "等待鍵盤緩衝區為空
SetPortVal KBC_KEY_DATA, (btScancode Or &H80), 1 "寫入按鍵資訊,釋放鍵
定義了上面的過程後,就可以用它來模擬鍵盤輸入了。在窗體模組中新增一個定時器控制元件,然後加入以下程式碼:
Private Sub Form_Load()
If InitializeWinIo = False Then
"用InitializeWinIo函式載入驅動程式,如果成功會返回true,否則返回false
MsgBox "驅動程式載入失敗!"
Unload Me
End If
Timer1.Interval = 3000
Timer1.Enabled = True
Private Sub Form_Unload(Cancel As Integer)
ShutdownWinIo "程式結束時記得用ShutdownWinIo函式解除安裝驅動程式
Private Sub Timer1_Timer()
Dim VK_A As Long = &H41
MyKeyDown VK_A
MyKeyUp VK_A "模擬按下並釋放A鍵
執行上面的程式,就會每隔3秒鐘模擬按下一次A鍵,試試看,怎麼樣,是不是對所有程式都有效果了?
需要注意的問題:
要在VB的除錯模式下使用WINIO,需要把那3個檔案複製到VB的安裝目錄中。
鍵盤上有些鍵屬於擴充套件鍵(比如鍵盤上的方向鍵就是擴充套件鍵),對於擴充套件鍵不應該用上面的MyKeyDown和MyKeyUp過程來模擬,可以使用下面的2個過程來準確模擬擴充套件鍵:
Sub MyKeyDownEx(ByVal vKeyCoad As Long) "模擬擴充套件鍵按下,引數vKeyCoad是擴充套件鍵的虛擬碼
SetPortVal KBC_KEY_DATA, &HE0, 1 "寫入擴充套件鍵標誌資訊
Sub MyKeyUpEx(ByVal vKeyCoad As Long) "模擬擴充套件鍵彈起
還應該注意的是,如果要從擴充套件鍵轉換到普通鍵,那麼普通鍵的KeyDown事件應該傳送兩次。也就是說,如果我想模擬先按下一個擴充套件鍵,再按下一個普通鍵,那麼就應該向埠傳送兩次該普通鍵被按下的資訊。比如,我想模擬先按下左方向鍵,再按下空格鍵這個事件,由於左方向鍵是擴充套件鍵,空格鍵是普通鍵,那麼流程就應該是這樣的:
MyKeyDownEx VK_LEFT "按下左方向鍵
Sleep 200 "延時200毫秒
MyKeyUpEx VK_LEFT "釋放左方向鍵
Sleep 500
MyKeyDown VK_SPACE "按下空格鍵,注意要傳送兩次
MyKeyDown VK_SPACE
Sleep 200
MyKeyUp VK_SPACE "釋放空格鍵
先用裡面的InitializeWinIo函式安裝驅動程式,然後就可以用GetPortVal來讀取埠或者用SetPortVal來寫入埠了。好,讓我們來做一個驅動級的鍵盤模擬吧。先把winio的3個檔案複製到你的程式的資料夾下,然後在VB中新建一個工程,新增一個模組,在模組中加入下面的winio函式宣告:
Declare Function MapPhysToLin Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysSize As Long, ByRef PhysMemHandle) As Long
Declare Function UnmapPhysicalMemory Lib "WinIo.dll" (ByVal PhysMemHandle, ByVal LinAddr) As Boolean
Declare Function GetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByRef PhysVal As Long) As Boolean
Declare Function SetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysVal As Long) As Boolean
Declare Function GetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByRef PortVal As Long, ByVal bSize As Byte) As Boolean
Declare Function SetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByVal PortVal As Long, ByVal bSize As Byte) As Boolean
Declare Function InitializeWinIo Lib "WinIo.dll" () As Boolean
Declare Function ShutdownWinIo Lib "WinIo.dll" () As Boolean
Declare Function InstallWinIoDriver Lib "WinIo.dll" (ByVal DriverPath As String, ByVal Mode As Integer) As Boolean
Declare Function RemoveWinIoDriver Lib "WinIo.dll" () As Boolean
" ------------------------------------以上是WINIO函式宣告-------------------------------------------
Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long
"-----------------------------------以上是WIN32 API函式宣告-----------------------------------------
再新增下面這個過程:
Sub KBCWait4IBE() "等待鍵盤緩衝區為空
Dim dwVal As Long
Do
GetPortVal &H64, dwVal, 1
"這句表示從&H64埠讀取一個位元組並把讀出的資料放到變數dwVal中
"GetPortVal函式的用法是GetPortVal 埠號,存放讀出資料的變數,讀入的長度
Loop While (dwVal And &H2)
End Sub
上面的是一個根據KBC規範寫的過程,它的作用是在向鍵盤埠寫入資料前等待一段時間,後面將會用到。
然後再新增如下過程,這2個過程用來模擬按鍵:
Public Const KBC_KEY_CMD = &H64 "鍵盤命令埠
Public Const KBC_KEY_DATA = &H60 "鍵盤資料埠
Sub MyKeyDown(ByVal vKeyCoad As Long)
"這個用來模擬按下鍵,引數vKeyCoad傳入按鍵的虛擬碼
Dim btScancode As Long
btScancode = MapVirtualKey(vKeyCoad, 0)
KBCWait4IBE "傳送資料前應該先等待鍵盤緩衝區為空
SetPortVal KBC_KEY_CMD, &HD2, 1 "傳送鍵盤寫入命令
"SetPortVal函式用於向埠寫入資料,它的用法是SetPortVal 埠號,欲寫入的資料,寫入資料的長度
KBCWait4IBE
SetPortVal KBC_KEY_DATA, btScancode, 1 "寫入按鍵資訊,按下鍵
End Sub
Sub MyKeyUp(ByVal vKeyCoad As Long)
"這個用來模擬釋放鍵,引數vKeyCoad傳入按鍵的虛擬碼
Dim btScancode As Long
btScancode = MapVirtualKey(vKeyCoad, 0)
KBCWait4IBE "等待鍵盤緩衝區為空
SetPortVal KBC_KEY_CMD, &HD2, 1 "傳送鍵盤寫入命令
KBCWait4IBE
SetPortVal KBC_KEY_DATA, (btScancode Or &H80), 1 "寫入按鍵資訊,釋放鍵
End Sub
定義了上面的過程後,就可以用它來模擬鍵盤輸入了。在窗體模組中新增一個定時器控制元件,然後加入以下程式碼:
Private Sub Form_Load()
If InitializeWinIo = False Then
"用InitializeWinIo函式載入驅動程式,如果成功會返回true,否則返回false
MsgBox "驅動程式載入失敗!"
Unload Me
End If
Timer1.Interval = 3000
Timer1.Enabled = True
End Sub
Private Sub Form_Unload(Cancel As Integer)
ShutdownWinIo "程式結束時記得用ShutdownWinIo函式解除安裝驅動程式
End Sub
Private Sub Timer1_Timer()
Dim VK_A As Long = &H41
MyKeyDown VK_A
MyKeyUp VK_A "模擬按下並釋放A鍵
End Sub
執行上面的程式,就會每隔3秒鐘模擬按下一次A鍵,試試看,怎麼樣,是不是對所有程式都有效果了?
需要注意的問題:
要在VB的除錯模式下使用WINIO,需要把那3個檔案複製到VB的安裝目錄中。
鍵盤上有些鍵屬於擴充套件鍵(比如鍵盤上的方向鍵就是擴充套件鍵),對於擴充套件鍵不應該用上面的MyKeyDown和MyKeyUp過程來模擬,可以使用下面的2個過程來準確模擬擴充套件鍵:
Sub MyKeyDownEx(ByVal vKeyCoad As Long) "模擬擴充套件鍵按下,引數vKeyCoad是擴充套件鍵的虛擬碼
Dim btScancode As Long
btScancode = MapVirtualKey(vKeyCoad, 0)
KBCWait4IBE "等待鍵盤緩衝區為空
SetPortVal KBC_KEY_CMD, &HD2, 1 "傳送鍵盤寫入命令
KBCWait4IBE
SetPortVal KBC_KEY_DATA, &HE0, 1 "寫入擴充套件鍵標誌資訊
KBCWait4IBE "等待鍵盤緩衝區為空
SetPortVal KBC_KEY_CMD, &HD2, 1 "傳送鍵盤寫入命令
KBCWait4IBE
SetPortVal KBC_KEY_DATA, btScancode, 1 "寫入按鍵資訊,按下鍵
End Sub
Sub MyKeyUpEx(ByVal vKeyCoad As Long) "模擬擴充套件鍵彈起
Dim btScancode As Long
btScancode = MapVirtualKey(vKeyCoad, 0)
KBCWait4IBE "等待鍵盤緩衝區為空
SetPortVal KBC_KEY_CMD, &HD2, 1 "傳送鍵盤寫入命令
KBCWait4IBE
SetPortVal KBC_KEY_DATA, &HE0, 1 "寫入擴充套件鍵標誌資訊
KBCWait4IBE "等待鍵盤緩衝區為空
SetPortVal KBC_KEY_CMD, &HD2, 1 "傳送鍵盤寫入命令
KBCWait4IBE
SetPortVal KBC_KEY_DATA, (btScancode Or &H80), 1 "寫入按鍵資訊,釋放鍵
End Sub
還應該注意的是,如果要從擴充套件鍵轉換到普通鍵,那麼普通鍵的KeyDown事件應該傳送兩次。也就是說,如果我想模擬先按下一個擴充套件鍵,再按下一個普通鍵,那麼就應該向埠傳送兩次該普通鍵被按下的資訊。比如,我想模擬先按下左方向鍵,再按下空格鍵這個事件,由於左方向鍵是擴充套件鍵,空格鍵是普通鍵,那麼流程就應該是這樣的:
MyKeyDownEx VK_LEFT "按下左方向鍵
Sleep 200 "延時200毫秒
MyKeyUpEx VK_LEFT "釋放左方向鍵
Sleep 500
MyKeyDown VK_SPACE "按下空格鍵,注意要傳送兩次
MyKeyDown VK_SPACE
Sleep 200
MyKeyUp VK_SPACE "釋放空格鍵