模拟任意按键(驱动级)

昨儿装了一XP的离开模式补丁,愕然发现自己的键盘没有Sleep键……
无奈开始着手写一个模拟按键的小程序,就这么一个小东西算是难住我了。
先后试了 SendKeys 、keybd_event 、PostMessage 都就不能模拟Sleep键,别的都行。

最后终于baidu到了方法~ 奉上。

驱动级模拟:直接读写键盘的硬件端口

在这里我们可以使用一个组件WINIO来完成读写端口操作。什么是WINIO?WINIO是一个全免费的、无需注册的、含源程序的WINDOWS2000 端口操作驱动程序组件(可以到http://www.internals.com/上 去下载)。它不仅可以操作端口,还可以操作内存;不仅能在VB下用,还可以在DELPHI、VC等其它环境下使用,性能特别优异。下载该组件,解压缩后可 以看到几个文件夹,其中Release文件夹下的3个文件就是我们需要的,这3个文件是WinIo.sys(用于win xp下的驱动程 序),WINIO.VXD(用于win 98下的驱动程序),WinIo.dll(封装函数的动态链接库),我们只需要调用WinIo.dll中的函数, 然后WinIo.dll就会安装并调用驱动程序来完成相应的功能。值得一提的是这个组件完全是绿色的,无需安装,你只需要把这3个文件复制到与你的程序相 同的文件夹下就可以使用了。用法很简单,先用里面的InitializeWinIo函数安装驱动程序,然后就可以用GetPortVal来读取端口或者用 SetPortVal来写入端口了。好,让我们来做一个驱动级的键盘模拟吧。先把winio的3个文件拷贝到你的程序的文件夹下,然后在VB中新建一个工 程,添加一个模块,在模块中加入下面的winio函数声明:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
    Declare Function MapPhysToLin Lib "WinIo.dll" (ByVal PhysAddr As Int32, ByVal PhysSize As Int32, ByRef PhysMemHandle As ObjectAs Int32
    
Declare Function UnmapPhysicalMemory Lib "WinIo.dll" (ByVal PhysMemHandle, ByVal LinAddr) As Boolean
    
Declare Function GetPhysint32 Lib "WinIo.dll" (ByVal PhysAddr As Int32, ByRef PhysVal As Int32) As Boolean
    
Declare Function SetPhysint32 Lib "WinIo.dll" (ByVal PhysAddr As Int32, ByVal PhysVal As Int32) As Boolean
    
Declare Function GetPortVal Lib "WinIo.dll" (ByVal PortAddr As IntegerByRef PortVal As Int32, ByVal bSize As ByteAs Boolean
    
Declare Function SetPortVal Lib "WinIo.dll" (ByVal PortAddr As IntegerByVal PortVal As Int32, ByVal bSize As ByteAs 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 StringByVal Mode As IntegerAs Boolean
    
Declare Function RemoveWinIoDriver Lib "WinIo.dll" () As Boolean
'---------以上是WINIO函数声明--------
    Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Int32, ByVal wMapType As Int32) As Int32
'---------以上是WIN32 API函数声明--------

再添加下面五个过程: 

ContractedBlock.gif ExpandedBlockStart.gif Code
    Sub KBCWait4IBE()    '等待键盘缓冲区为空
        Dim dwVal As Int32
        
Do
            GetPortVal(
&H64, dwVal, 1)
            
'这句表示从&H64端口读取一个字节并把读出的数据放到变量dwVal中
            'GetPortVal函数的用法是GetPortVal 端口号,存放读出数据的变量,读入的长度
        Loop While (dwVal And &H2)
    
End Sub


    
Public Const KBC_KEY_CMD = &H64     '键盘命令端口
    Public Const KBC_KEY_DATA = &H60    '键盘数据端口

    
Sub MyKeyDown(ByVal vKeyCoad As Int32)
        
'这个用来模拟按下键,参数vKeyCoad传入按键的虚拟码
        Dim btScancode As Int32
        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 Int32)
        
'这个用来模拟释放键,参数vKeyCoad传入按键的虚拟码
        Dim btScancode As Int32
        btScancode 
= MapVirtualKey(vKeyCoad, 0)

        KBCWait4IBE()    
'等待键盘缓冲区为空
        SetPortVal(KBC_KEY_CMD, &HD2, 1)   '发送键盘写入命令
        KBCWait4IBE()
        SetPortVal(KBC_KEY_DATA, (btScancode 
Or &H80), 1)   '写入按键信息,释放键

    
End Sub

    
Sub MyKeyDownEx(ByVal vKeyCoad As Int32)    '模拟扩展键按下,参数vKeyCoad是扩展键的虚拟码
        Dim btScancode As Int32
        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 Int32)    '模拟扩展键弹起
        Dim btScancode As Int32
        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


在From_Load事件加载驱动,Form_FormClosing卸载驱动:

ContractedBlock.gif ExpandedBlockStart.gif Code
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        
If InitializeWinIo = False Then
            
'用InitializeWinIo函数加载驱动程序,如果成功会返回true,否则返回false
            MsgBox("驱动程序加载失败!")
            
Me.Close()
        
End If
    
End Sub

    
Private Sub Form1_FormClosing(ByVal sender As ObjectByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        ShutdownWinIo()
    
End Sub

调用方法:

ContractedBlock.gif ExpandedBlockStart.gif Code
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MyKeyDown(Keys.NumLock)
        MyKeyUp(Keys.NumLock)
    
End Sub


试试看NumLock灯是不是有变化?

将按键改成 Keys.Sleep 就可以休眠了。

原文地址:http://hi.baidu.com/skyue4me/blog/item/bbf913588d57e584810a180d.html

里面还有 keybd_event 、PostMessage 的VB6用法。

PS:有网友说要程序,这就奉上。

http://files.cnblogs.com/mx1700/休眠.rar

转载于:https://www.cnblogs.com/mx1700/articles/1263787.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值