昨儿装了一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函数声明:
CodeDeclareFunctionMapPhysToLinLib"WinIo.dll"(ByValPhysAddrAsInt32,ByValPhysSizeAsInt32,ByRefPhysMemHandleAsObject)AsInt32DeclareFunctionUnmapPhysicalMemoryLib"WinIo.dll"(ByValPhysMemHandle,ByValLinAddr)AsBooleanDeclareFunctionGetPhysint32Lib"WinIo.dll"(ByValPhysAddrAsInt32,ByRefPhysValAsInt32)AsBooleanDeclareFunctionSetPhysint32Lib"WinIo.dll"(ByValPhysAddrAsInt32,ByValPhysValAsInt32)AsBooleanDeclareFunctionGetPortValLib"WinIo.dll"(ByValPortAddrAsInteger,ByRefPortValAsInt32,ByValbSizeAsByte)AsBooleanDeclareFunctionSetPortValLib"WinIo.dll"(ByValPortAddrAsInteger,ByValPortValAsInt32,ByValbSizeAsByte)AsBooleanDeclareFunctionInitializeWinIoLib"WinIo.dll"()AsBooleanDeclareFunctionShutdownWinIoLib"WinIo.dll"()AsBooleanDeclareFunctionInstallWinIoDriverLib"WinIo.dll"(ByValDriverPathAsString,ByValModeAsInteger)AsBooleanDeclareFunctionRemoveWinIoDriverLib"WinIo.dll"()AsBoolean'---------以上是WINIO函数声明--------DeclareFunctionMapVirtualKeyLib"user32"Alias"MapVirtualKeyA"(ByValwCodeAsInt32,ByValwMapTypeAsInt32)AsInt32'---------以上是WIN32 API函数声明--------
再添加下面五个过程:
CodeSubKBCWait4IBE()'等待键盘缓冲区为空DimdwValAsInt32DoGetPortVal(&H64, dwVal,1)'这句表示从&H64端口读取一个字节并把读出的数据放到变量dwVal中'GetPortVal函数的用法是GetPortVal 端口号,存放读出数据的变量,读入的长度LoopWhile(dwValAnd&H2)End SubPublicConstKBC_KEY_CMD=&H64'键盘命令端口PublicConstKBC_KEY_DATA=&H60'键盘数据端口SubMyKeyDown(ByValvKeyCoadAsInt32)'这个用来模拟按下键,参数vKeyCoad传入按键的虚拟码DimbtScancodeAsInt32
btScancode=MapVirtualKey(vKeyCoad,0)
KBCWait4IBE()'发送数据前应该先等待键盘缓冲区为空SetPortVal(KBC_KEY_CMD,&HD2,1)'发送键盘写入命令'SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度KBCWait4IBE()
SetPortVal(KBC_KEY_DATA, btScancode,1)'写入按键信息,按下键End SubSubMyKeyUp(ByValvKeyCoadAsInt32)'这个用来模拟释放键,参数vKeyCoad传入按键的虚拟码DimbtScancodeAsInt32
btScancode=MapVirtualKey(vKeyCoad,0)
KBCWait4IBE()'等待键盘缓冲区为空SetPortVal(KBC_KEY_CMD,&HD2,1)'发送键盘写入命令KBCWait4IBE()
SetPortVal(KBC_KEY_DATA, (btScancodeOr&H80),1)'写入按键信息,释放键End SubSubMyKeyDownEx(ByValvKeyCoadAsInt32)'模拟扩展键按下,参数vKeyCoad是扩展键的虚拟码DimbtScancodeAsInt32
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 SubSubMyKeyUpEx(ByValvKeyCoadAsInt32)'模拟扩展键弹起DimbtScancodeAsInt32
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, (btScancodeOr&H80),1)'写入按键信息,释放键End Sub
在From_Load事件加载驱动,Form_FormClosing卸载驱动:
CodePrivateSubForm1_Load(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesMyBase.LoadIfInitializeWinIo=FalseThen'用InitializeWinIo函数加载驱动程序,如果成功会返回true,否则返回falseMsgBox("驱动程序加载失败!")Me.Close()EndIfEnd SubPrivateSubForm1_FormClosing(ByValsenderAsObject,ByValeAsSystem.Windows.Forms.FormClosingEventArgs)HandlesMe.FormClosing
ShutdownWinIo()End Sub
调用方法:
CodePrivateSubButton1_Click(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesButton1.Click
MyKeyDown(Keys.NumLock)
MyKeyUp(Keys.NumLock)End Sub
试试看NumLock灯是不是有变化?
将按键改成 Keys.Sleep 就可以休眠了。
里面还有 keybd_event 、PostMessage 的VB6用法。
PS:有网友说要程序,这就奉上。
http://files.cnblogs.com/mx1700/休眠.rar
本文介绍了如何在Python中实现驱动级模拟按键,通过利用WINIO组件读写键盘硬件端口来模拟按键操作,包括按下和释放键的功能。文中提供了具体的VB代码示例,并指出可以通过修改按键为Keys.Sleep来实现休眠功能。
1万+

被折叠的 条评论
为什么被折叠?



