pb中怎么用keybd_event模拟输出'_'? keybd_event ( asc("_"), 0, 0 , 0 ) 这样为什么不行呢?还望高手解答.

作者&投稿:宫蚀 (若有异议请与网页底部的电邮联系)
keybd_event操作键盘无反应~

把'R'改为82试一试;
或者先获取当前窗口的焦点,可能就行了。

键盘是我们使用计算机的一个很重要的输入设备了,即使在鼠标大行其道的今天,很多程序依然离不开键盘来操作。但是有时候,一些重复性的,很繁琐的键盘操作总会让人疲惫,于是就有了用程序来代替人们按键的方法,这样可以把很多重复性的键盘操作交给程序来模拟,省了很多精力,按键精灵就是这样的一个软件。那么我们怎样才能用VB来写一个程序,达到与按键精灵类似的功能呢?那就让我们来先了解一下windows中响应键盘事件的机制。
当用户按下键盘上的一个键时,键盘内的芯片会检测到这个动作,并把这个信号传送到计算机。如何区别是哪一个键被按下了呢?键盘上的所有按键都有一个编码,称作键盘扫描码。当你按下一个键时,这个键的扫描码就被传给系统。扫描码是跟具体的硬件相关的,同一个键,在不同键盘上的扫描码有可能不同。键盘控制器就是将这个扫描码传给计算机,然后交给键盘驱动程序。键盘驱动程序会完成相关的工作,并把这个扫描码转换为键盘虚拟码。什么是虚拟码呢?因为扫描码与硬件相关,不具有通用性,为了统一键盘上所有键的编码,于是就提出了虚拟码概念。无论什么键盘,同一个按键的虚拟码总是相同的,这样程序就可以识别了。简单点说,虚拟码就是我们经常可以看到的像VK_A,VK_B这样的常数,比如键A的虚拟码是65,写成16进制就是&H41,注意,人们经常用16进制来表示虚拟码。当键盘驱动程序把扫描码转换为虚拟码后,会把这个键盘操作的扫描码和虚拟码还有其它信息一起传递给操作系统。然后操作系统则会把这些信息封装在一个消息中,并把这个键盘消息插入到消息列队。最后,要是不出意外的话,这个键盘消息最终会被送到当前的活动窗口那里,活动窗口所在的应用程序接收到这个消息后,就知道键盘上哪个键被按下,也就可以决定该作出什么响应给用户了。这个过程可以简单的如下表示:
用户按下按键-----键盘驱动程序将此事件传递给操作系统-----操作系统将键盘事件插入消息队列-----键盘消息被发送到当前活动窗口
明白了这个过程,我们就可以编程实现在其中的某个环节来模拟键盘操作了。在VB中,有多种方法可以实现键盘模拟,我们就介绍几种比较典型的。

1.局部级模拟
从上面的流程可以看出,键盘事件是最终被送到活动窗口,然后才引起目标程序响应的。那么最直接的模拟方法就是:直接伪造一个键盘消息发给目标程序。哈哈,这实在是很简单,windows提供了几个这样的API函数可以实现直接向目标程序发送消息的功能,常用的有SendMessage和PostMessage,它们的区别是PostMessage函数直接把消息仍给目标程序就不管了,而SendMessage把消息发出去后,还要等待目标程序返回些什么东西才好。这里要注意的是,模拟键盘消息一定要用PostMessage函数才好,用SendMessage是不正确的(因为模拟键盘消息是不需要返回值的,不然目标程序会没反应),切记切记!PostMessage函数的VB声明如下:
Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
参数hwnd 是你要发送消息的目标程序上某个控件的句柄,参数wMsg 是消息的类型,表示你要发送什么样的消息,最后wParam 和lParam 这两个参数是随消息附加的数据,具体内容要由消息决定。
再来看看wMsg 这个参数,要模拟按键就靠这个了。键盘消息常用的有如下几个:
WM_KEYDOWN 表示一个普通键被按下
WM_KEYUP 表示一个普通键被释放
WM_SYSKEYDOWN 表示一个系统键被按下,比如Alt键
WM_SYSKEYUP 表示一个系统键被释放,比如Alt键
如果你确定要发送以上几个键盘消息,那么再来看看如何确定键盘消息中的wParam 和lParam 这两个参数。在一个键盘消息中,wParam 参数的含义较简单,它表示你要发送的键盘事件的按键虚拟码,比如你要对目标程序模拟按下A键,那么wParam 参数的值就设为VK_A ,至于lParam 这个参数就比较复杂了,因为它包含了多个信息,一般可以把它设为0,但是如果你想要你的模拟更真实一些,那么建议你还是设置一下这个参数。那么我们就详细了解一下lParam 吧。lParam 是一个long类型的参数,它在内存中占4个字节,写成二进制就是00000000 00000000 00000000 00000000 一共是32位,我们从右向左数,假设最右边那位为第0位(注意是从0而不是从1开始计数),最左边的就是第31位,那么该参数的的0-15位表示键的发送次数等扩展信息,16-23位为按键的扫描码,24-31位表示是按下键还是释放键。大家一般习惯写成16进制的,那么就应该是&H00 00 00 00 ,第0-15位一般为&H0001,如果是按下键,那么24-31位为&H00,释放键则为&HC0,那么16-23位的扫描码怎么会得呢?这需要用到一个API函数MapVirtualKey,这个函数可以将虚拟码转换为扫描码,或将扫描码转换为虚拟码,还可以把虚拟码转换为对应字符的ASCII码。它的VB声明如下:
Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long
参数wCode 表示待转换的码,参数wMapType 表示从什么转换为什么,如果是虚拟码转扫描码,则wMapType 设置为0,如果是虚拟扫描码转虚拟码,则wMapType 设置为1,如果是虚拟码转ASCII码,则wMapType 设置为2.相信有了这些,我们就可以构造键盘事件的lParam参数了。下面给出一个构造lParam参数的函数:
Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long
Function MakeKeyLparam(ByVal VirtualKey As Long, ByVal flag As Long) As Long
'参数VirtualKey表示按键虚拟码,flag表示是按下键还是释放键,用WM_KEYDOWN和WM_KEYUP这两个常数表示
Dim s As String
Dim Firstbyte As String 'lparam参数的24-31位
If flag = WM_KEYDOWN Then '如果是按下键
Firstbyte = "00"
Else
Firstbyte = "C0" '如果是释放键
End If
Dim Scancode As Long
'获得键的扫描码
Scancode = MapVirtualKey(VirtualKey, 0)
Dim Secondbyte As String 'lparam参数的16-23位,即虚拟键扫描码
Secondbyte = Right("00" & Hex(Scancode), 2)
s = Firstbyte & Secondbyte & "0001" '0001为lparam参数的0-15位,即发送次数和其它扩展信息
MakeKeyLparam = Val("&H" & s)
End Function
这个函数像这样调用,比如按下A键,那么lParam=MakeKeyLparam(VK_A,WM_KEYDOWN) ,很简单吧。值得注意的是,即使你发送消息时设置了lParam参数的值,但是系统在传递消息时仍然可能会根据当时的情况重新设置该参数,那么目标程序收到的消息中lParam的值可能会和你发送时的有所不同。所以,如果你很懒的话,还是直接把它设为0吧,对大多数程序不会有影响的,呵呵。
好了,做完以上的事情,现在我们可以向目标程序发送键盘消息了。首先取得目标程序接受这个消息的控件的句柄,比如目标句柄是12345,那么我们来对目标模拟按下并释放A键,像这样:(为了简单起见,lParam这个参数就不构造了,直接传0)
PostMessage 12345,WM_KEYDOWN,VK_A,0& '按下A键
PostMessage 12345,WM_UP,VK_A,0& '释放A键
好了,一次按键就完成了。现在你可以迫不及待的打开记事本做实验,先用FindWindowEx这类API函数找到记事本程序的句柄,再向它发送键盘消息,期望记事本里能诡异的自动出现字符。可是你马上就是失望了,咦,怎么一点反应也没有?你欺骗感情啊~~~~~~~~~~55555555555555 不是的哦,接着往下看啊。
一般目标程序都会含有多个控件,并不是每个控件都会对键盘消息作出反应,只有把键盘消息发送给接受它的控件才会得到期望的反应。那记事本来说,它的编辑框其实是个edit类,只有这个控件才对键盘事件有反应,如果只是把消息发给记事本的窗体,那是没有用的。现在你找出记事本那个编辑框的句柄,比如是54321,那么写如下代码:
PostMessage 54321,WM_KEYDOWN,VK_F1,0& '按下F1键
PostMessage 54321,WM_UP,VK_F1,0& '释放F1键
怎么样,是不是打开了记事本的“帮助”信息?这说明目标程序已经收到了你发的消息,还不错吧~~~~~~~~
可以马上新问题就来了,你想模拟向记事本按下A这个键,好在记事本里自动输入字符,可是,没有任何反应!这是怎么一回事呢?
原来,如果要向目标程序发送字符,光靠WM_KEYDOWN和WM_UP这两个事件还不行,还需要一个事件:WM_CHAR,这个消息表示一个字符,程序需靠它看来接受输入的字符。一般只有A,B,C等这样的按键才有WM_CHAR消息,别的键(比如方向键和功能键)是没有这个消息的,WM_CHAR消息一般发生在WM_KEYDOWN消息之后。WM_CHAR消息的lParam参数的含义与其它键盘消息一样,而它的wParam则表示相应字符的ASCII编码(可以输入中文的哦^_^),现在你可以写出一个完整的向记事本里自动写入字符的程序了,下面是一个例子,并附有这些消息常数的具体值:
Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long
Public Const WM_KEYDOWN = &H100
Public Const WM_KEYUP = &H101
Public Const WM_CHAR = &H102
Public Const VK_A = &H41
Function MakeKeyLparam(ByVal VirtualKey As Long, ByVal flag As Long) As Long
Dim s As String
Dim Firstbyte As String 'lparam参数的24-31位
If flag = WM_KEYDOWN Then '如果是按下键
Firstbyte = "00"
Else
Firstbyte = "C0" '如果是释放键
End If
Dim Scancode As Long
'获得键的扫描码
Scancode = MapVirtualKey(VirtualKey, 0)
Dim Secondbyte As String 'lparam参数的16-23位,即虚拟键扫描码
Secondbyte = Right("00" & Hex(Scancode), 2)
s = Firstbyte & Secondbyte & "0001" '0001为lparam参数的0-15位,即发送次数和其它扩展信息
MakeKeyLparam = Val("&H" & s)
End Function
Private 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"),MakeKeyLparam(VK_A,WM_KEYDOWN) '输入字符A
PostMessage hwnd,WM_UP,VK_A,MakeKeyLparam(VK_A,WM_UP) '释放A键
End Sub
这就是通过局部键盘消息来模拟按键。这个方法有一个极大的好处,就是:它可以实现后台按键,也就是说他对你的前台操作不会有什么影响。比如,你可以用这个方法做个程序在游戏中模拟按键来不断地执行某些重复的操作,而你则一边喝茶一边与QQ上的MM们聊得火热,它丝毫不会影响你的前台操作。无论目标程序是否获得焦点都没有影响,这就是后台模拟按键的原理啦~~~~

) '模拟按下"F1"键
Sleep 200 '延时200毫秒
keybd_event(112, 0, KEYEVENTF_KEYUP, 0) '模拟弹起F1键
----------------------------------------------------------------------------------------

模拟键盘或鼠标的响应

我们一般使用:

UINT SendInput(
UINT nInputs, // count of input events
�PINPUT pInputs, // array of input events
int cbSize // size of structure
);

API函数。第一个参数是说明第二个参数的矩阵的维数的,第二个参数包含了响应事件,这个自己填充就可以,最后

是这个结构的大小,非常简单,这是最简单的方法模拟键盘鼠标了,呵呵。注意,这个函数还有个替代函数:

VOID keybd_event(
BYTE bVk, // 虚拟键码
BYTE bScan, // 扫描码
DWORD dwFlags,
ULONG_PTR dwExtraInfo // 附加键状态
);



VOID mouse_event(
DWORD dwFlags, // motion and click options
DWORD dx, // horizontal position or change
DWORD dy, // vertical position or change
DWORD dwData, // wheel movement
ULONG_PTR dwExtraInfo // application-defined information
);

这两个函数非常简单了,我想那些按键精灵就是用的这个吧。上面的是模拟键盘,下面的是模拟鼠标的。这个仅仅是

模拟部分,要和游戏联系起来我们还需要找到游戏的窗口才行,或者包含快捷键,就象按键精灵的那个激活键一样,我们

可以用GetWindow函数来枚举窗口,也可以用Findwindow函数来查找制定的窗口(注意,还有一个FindWindowEx),

FindwindowEx可以找到窗口的子窗口,比如按钮,等什么东西。当游戏切换场景的时候我们可以用FindWindowEx来确定一

些当前窗口的特征,从而判断是否还在这个场景,方法很多了,比如可以GetWindowInfo来确定一些东西,比如当查找不

到某个按钮的时候就说明游戏场景已经切换了,等等办法。有的游戏没有控件在里面,这是对图像做坐标变换的话,这种

方法就要受到限制了。这就需要我们用别的办法来辅助分析了。

附:常用模拟键的键值对照表。

键盘键与虚拟键码对照表

字母和数字键 数字小键盘的键 功能键 其它键
键 键码 键 键码 键 键码 键 键码
A 65 0 96 F1 112 Backspace 8
B 66 1 97 F2 113 Tab 9
C 67 2 98 F3 114 Clear 12
D 68 3 99 F4 115 Enter 13
E 69 4 100 F5 116 Shift 16
F 70 5 101 F6 117 Control 17
G 71 6 102 F7 118 Alt 18
H 72 7 103 F8 119 Caps Lock 20
I 73 8 104 F9 120 Esc 27
J 74 9 105 F10 121 Spacebar 32
K 75 * 106 F11 122 Page Up 33
L 76 + 107 F12 123 Page Down 34
M 77 Enter 108 -- -- End 35
N 78 - 109 -- -- Home 36
O 79 . 110 -- -- Left Arrow 37
P 80 / 111 -- -- Up Arrow 38
Q 81 -- -- -- -- Right Arrow 39
R 82 -- -- -- -- Down Arrow 40
S 83 -- -- -- -- Insert 45
T 84 -- -- -- -- Delete 46
U 85 -- -- -- -- Help 47
V 86 -- -- -- -- Num Lock 144
W 87
X 88
Y 89
Z 90
0 48
1 49
2 50
3 51
4 52
5 53
6 54
7 55
8 56
9 57
另外,虚机团上产品团购,超级便宜


...线束的翻译,多多益善 谢谢啦!KEYA . KEYB .BRAKE . KET GND . 分 ...
取决于用到的线,是CAN线还是LIN线?这两类线束的传递速度是截然不同的。CAN线还分为诊断CAN, 控制CAN,娱乐CAN等。而且不同功能的线束其颜色是不同的,这又取决于你要改装的车型。这是个专业性很强的问题,而你的问题太不具体了。所以很难回答。

电路中原理图KEY、POWER、GND、RESET、ACC、ILL、MUTE、IR、BATT(B...
KEY 钥匙,密码 、POWER电源、 GND、 地线或0线 RESET复位、 ACC、 ACC”档位是“不发动车可以给车内部分电器供电” ILL、 MUTE、 弱音器;闭止音 IR、 红外线 BATT(B+)、 (电池 MIC 麦克风

假设有两张表A和B,A表有两个字段:Key_A和Value_A;B表有两个字段:Key_B...
A=B.Key_B 2.insert into a select * from b 3.select * from a where Key_A not in (select Key_b from b)4. select a.* from a,b where a.Key_A=b.Key_b and a.Value_A=b.Value_b 5.update a set a.Value_A=b.Value_A from a,b where A.Key_A=B.Key_B ...

怎么用vb实现老板键功能呢
'如果要隐藏窗口,直接使用 form.hide即可 '如果窗口已经被隐藏,那么直接使用form.show即可 End Function --- 在启动窗体中加入以下事件 Dim HotKeyEnabled(12) As Boolean Dim HotKey As Byte Public Sub CleanUp()For HotKey = 1 To 12 If HotKeyEnabled(HotKey) = True Then Call DeleteHot...

keytoy怎么用
3. 保存并应用设置:完成按键修改后,用户需要点击保存按钮以保存更改。之后,可以选择将更改应用到系统中。需要注意的是,某些更改可能需要重新启动计算机才能生效。在使用KeyTweak时,用户还需要注意一些事项。首先,确保在修改按键功能前备份原有的键盘设置,以防出现问题。其次,对于一些特殊的按键组合或...

vb字串怎么变成变量?例如:b="a1" a1="c" 我想要把"a1"通过什么函数变成...
写好了,如下:Private Type POINTAPI key As String value As String End Type Private getB() As POINTAPI Public index As Integer Public Function getValue(ByVal key As String) As String For i = 0 To UBound(getB)If getB(i).key = key Then getValue = getB(i).value Exit ...

python 把一个字典key的值加到另一个字典的key的值中?
import openpyxla = {'A': [2136, 1888, 2102, 1911, 1966], 'B': [123, 698, 2564]}b = {'A': [2136, 1695, 2102, 1888]}for key in a.keys():for bkey in b.keys():if bkey == key:for i in b[bkey]:a[key].append(i)print(a)格式如上,注意对齐 ...

MySQL优化之key索引的使用mysql中key索引
MySQL是目前应用最广泛的开源数据库之一,而索引是MySQL中非常重要的组成部分之一。在大型的数据库中,如果没有正确的索引设计和使用,数据库的性能将大大降低。其中,key索引是MySQL中常用的一种索引类型,本文将介绍如何正确地使用key索引来优化MySQL查询性能。1. 理解key索引 在MySQL中,key索引又称为B...

电路中原理图KEY、POWER、GND、RESET、ACC、ILL、MUTE、IR、BATT(B...
KEY钥匙,密码 、POWER电源、GND、地线或0线 RESET复位、ACC、ACC”档位是“不发动车可以给车内部分电器供电”ILL、MUTE、弱音器;闭止音 IR、红外线 BATT(B+)、(电池 MIC麦克风

JAVA 开发中页面怎么读取钥匙key信息?
var result = FTUCtrl.SetCertResult_Ex,直接就获取到了key,当然控件的实现那是控件的事,它可能是由其他诸如VC类的底层语言开发的控件(比如ocx控件),可由其他语言调用。设计到安全性能,控件在读取key的时候应该是有自己的一套加密算法。你只要调用控件提供的js方法就能得到key值。当然客户端在使用时...

哈尔滨市17087262215: PB 代码模拟按键 如何使用API函数keybd - event -
万贡奥普: 应该不需要API函数,你新增一个事件keydown,选中event_id中的Pbm_keydown

哈尔滨市17087262215: pb中如何用回车键代替tab键在窗体上转移控件焦点,我是pb新手,希望各位高手指教 -
万贡奥普: 先编辑控件的TabOrder顺序,然后在 global external functions 中定义一个API: Subroutine keybd_event(int bVk,int bScan,ulong dwFlags,ulong dwExtraInfo) LIBRARY "user32.dll" 在窗口的key()事件中写如下代码: If key = KeyEnter! Or Key ...

哈尔滨市17087262215: PB datawindow 设置了TAB顺序,但有一列光标跳不过
万贡奥普: 首先你设置的TAB序正确性,然后在数据窗口中自定事件:event ID:PBM_dwnkey 事件中设置: //回车键及下箭头键下移焦点 If key = KeyEnter! Or Key = KeyDownArrow! Then keybd_event ( 9, 0, 0, 0 ) // 按下tab keybd_event ( 9, 0, 2, 0 ) // 释放tab Return 0 End If 还有就是你要跳转到的列不能是计算列,它的前一列没有设置其他列为当前列.

哈尔滨市17087262215: 如何用代码实现按Home键的效果 -
万贡奥普: 用 VK_HOME 0x24 调用 函数:void keybd_event(BYTE bVirtualKey, BYTE bScanCode,DWORD dwFlags, DWORD dwExtraInfo); 例如 键按下:keybd_event(VK_HOME, 0x24, 0, 0); 键抬起:keybd_event(VK_HOME, 0x24, KEYEVENTF_KEYUP, 0); 头文件和库:#include #include #pragma comment (lib, "User32.lib")

哈尔滨市17087262215: 如何在VB中用PostMessage向指定窗口发送带有修饰键的组合键? -
万贡奥普: 向任意应用程序(包括后台的)发送任意按键消息(包括普通字符键、功能键、Shift/Control/Alt加任意按键的组合键),以实现自动执行特定功能,是一个用途很广、很有实用价值的功能,很多人都受困于此,不得其解,本人也遇到这种需求并...

哈尔滨市17087262215: keybd - event 释放键 -
万贡奥普: 我刚开始学的时候在某个源代码上也是这样,运行后不释放的.现在我知道怎么弄了,你应该这样:keybd_event vbkeyshift,0,0,0 keybd_event vbkeyshift,0,2,2'注释:我试过了,最后一个2写其它值也可以 要不你可以在声明部分定义 KEYEVENTF_KEYUP 常量,可以使用这个语句定义:Const KEYEVENTF_KEYUP=2

哈尔滨市17087262215: 如何在程序中虚拟键盘按键
万贡奥普: DWORD dwFlags, // flags specifying various function options用keybd_event :VOID keybd_event( BYTE bVk, // virtual-key code BYTE bScan, // hardware scan code DWORD dwExtraInfo // additional data associated with keystroke );

哈尔滨市17087262215: vc++ sendmessage() key - event()如何使用 -
万贡奥普: keybd_event专门用于模仿键盘按键第二个:SendMessage根据窗口句柄发送一个消息给窗口函数定义:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);第一个参数是窗口句柄,第二参数个是消息类...

哈尔滨市17087262215: C#中怎么调用API函数keyboard - event函数?介绍一下用法? -
万贡奥普: [DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)] private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);...private void button1_Click( object sender, EventArgs e ) { const byte VK_F...

哈尔滨市17087262215: 键盘的按键在VB代码里怎么表示 -
万贡奥普: (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表示要模拟...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网