用VB模拟带有修饰键的组合键

来源:互联网 发布:中国移动手机oa软件 编辑:程序博客网 时间:2024/05/15 23:51
向任意应用程序(包括后台的)发送任意按键消息(包括普通字符键、功能键、Shift/Control/Alt加任意按键的组合键),以实现自动执行特定功能,是一个用途很广、很有实用价值的功能,但加任意组合键这个问题却不得其解。查了很多资料和网上网友的解决方案,有些能起到一定作用,但也有许多方案经试验证实不可行。尤其是关于发送 Shift/Control/Alt 加任意按键的组合键这个问题,没有发现一个可行的方案。


例如以下代码并不能向指定Window(hwnd)发送 Ctrl+C:
PostMessage hwnd,WM_KEYDOWN,VK_CONTROL,&H001D0001   '按下Ctrl键
PostMessage hwnd,WM_KEYDOWN,VK_C,&H002E0001         '按下C键
PostMessage hwnd,WM_KEYUP,VK_C,&HC02E0001           '释放C键
PostMessage hwnd,WM_KEYUP,VK_CONTROL,&HC01D0001     '释放Ctrl键


上例只能发送一个小写字母c。


以下代码虽可以模拟 Ctrl+C 按键,但却不能向指定的后台窗口发送:
keybd_event VK_Ctrl, 0, 0, 0 '按下Ctrl键
keybd_event VK_C, 0, 0, 0 '按下C键
Sleep 500 '延时500毫秒
keybd_event VK_C, 0, KEYEVENTF_KEYUP, 0 '释放C键
keybd_event VK_Ctrl, 0, KEYEVENTF_KEYUP, 0 '释放Ctrl键


要实现向任意应用程序窗口发送模拟的按键,在不需激活该应用程序使其获得输入焦点的情况下,首先必须取得要接收按键的窗口句柄,这要用到Windows API FindWindow 及 FindWindowEx,首先用 FindWindow 取得应用程序顶层(Top Level)窗口的句柄,然后再用 FindWindowEx 取得要接收按键的子窗口或控件的句柄,因为应用程序顶层窗口不一定就是接受按键的窗口(如“notepad.exe”记事本程序,实际接受按键的窗口是记事本主窗口下的Edit控件),可以通过ClassID或Caption来查找。假设目标窗口的句柄已取得(hwnd),然后要用PostMessage向该窗口发送按键消息,对于普通字符键,直接用WM_CHAR消息最简单,如下:
PostMessage hwnd, WM_CHAR, Asc("A"), 0   ' 发送一个 A 字符


对于非普通字符按键,如功能键、方向键等,要用 WM_KEYDOWN、WM_KEYUP 消息,如下:
PostMessage hwnd, WM_KEYDOWN, VK_ESCAPE, &H00010001  ' 模拟按下 Esc 键
PostMessage hwnd, WM_KEYUP, VK_ESCAPE, &HC0010001    ' 模拟抬起 Esc 键


以上最后一个参数(lParam)低16位(0001)表示按键一次,高8位00表示按下,C0表示抬起,次高8位(01)表示该键的扫描码,可用 API MapVirtualKey(VirtualKey, 0)取得(注意:扫描码在各系统可能会不同,实际应用MapVirtualKey取得)。


下面要讲Shift/Ctrl/Alt修饰键与其它按键的组合怎样发送,对于Shift和Ctrl用以下方式(用到 API keybd_event):


keybd_event VK_SHIFT, MapVirtualKey(VK_SHIFT, 0), 0, 0  ' 模拟按下SHIFT键,MapVirtualKey(VK_SHIFT, 0)是为了取得SHIFT的扫描码
PostMessage hwnd, WM_KEYDOWN, VK_A, &H001E0001 ' 按下 A 键,SHIFT+A产生一个大写A字符
PostMessage hwnd, WM_KEYUP, VK_A, &HC01E0001   ' 释放 A 键
keybd_event VK_SHIFT, MapVirtualKey(VK_SHIFT, 0), KEYEVENTF_KEYUP, 0    ' 释放 SHIFT 键


以上VK_SHIFT(扫描码2A)换成VK_CONTROL(扫描码1D)就可以实现Ctrl组合键,VK_A(扫描码1E)也可以换成任意功能键,如VK_F4(扫描码3E)。




对于Alt修饰键比较特别,它属于系统按键,要用 WM_SYSKEYDOWN/WM_SYSKEYUP 消息,如下:


PostMessage hwnd, WM_SYSKEYDOWN, VK_F4, &H003E0001 Or &H20000000 ' 模拟按下 Alt+F4
PostMessage hwnd, WM_SYSKEYUP, VK_F4, &HC03E0001 Or &H20000000   ' 模拟抬起 Alt+F4  '&H20000000 为lParam 的第29位,置 1 表示 Alt 键被按下