向任意应用程序(包括后台的)发送任意按键消息

来源:互联网 发布:sqlserver 添加注释 编辑:程序博客网 时间:2024/06/06 06:51

转载链接:http://blog.csdn.net/wangjieest/article/details/6958039


        向任意应用程序(包括后台的)发送任意按键消息(包括普通字符键、功能键、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键
                keybd_event VK_C, 0, KEYEVENTF_KEYUP, 0 '释放C键
                keybd_event VK_Ctrl, 0, KEYEVENTF_KEYUP, 0 '释放Ctrl键
        难道真的没有解决这个问题的办法吗?我想这个应该是可以做到的呀!后来经过反复的研究Windows的消息机制和键盘输入系统调用的资料,终于找到了解决方案,并经试验成功证实。自己也是曾经受困于此,终得其解,不敢独享,现拿出来献给广大同需此求的朋友,也让这个问题不再是少数“高手”们独享的秘籍。
        要实现向任意应用程序窗口发送模拟的按键,在不需激活该应用程序使其获得输入焦点的情况下,首先必须取得要接收按键的窗口句柄,这要用到Windows API FindWindow 及 FindWindowEx,首先用 FindWindow 取得应用程序顶层(Top Level)窗口的句柄,然后再用 FindWindowEx 取得要接收按键的子窗口或控件的句柄,因为应用程序顶层窗口不一定就是接受按键的窗口(如“NotePad.exe”记事本程序,实际接受按键的窗口是Notepad主窗口下的Edit控件),可以通过ClassID或Caption来查找。假设目标窗口的句柄已取得(hwnd),然后要用PostMessage向该窗口发送按键消息,对于普通字符键,直接用WM_CHAR消息最简单,如下:
                PostMessage hwnd, WM_CHAR, Asc("A"), 0   ' 发送一个 A 字符
        对于非普通字符按键,如功能键、方向键等,要用 WM_KEYDOWN、WM_KEYUP 消息,如下:
                PostMessage hWndMsg, WM_KEYDOWN, VK_ESCAPE, &H00010001  ' 模拟按下 Esc 键
                PostMessage hWndMsg, WM_KEYUP, VK_ESCAPE, &HC0010001    ' 模拟抬起 Esc 键
        以上最后一个参数(lParam)低16位(0001)表示按键一次,高8位00表示按下,C0表示抬起,次高8位(01)表示该键的扫描码,可用 API MapVirtualKey(VirtualKey, 0)取得(注意:扫描码在各系统可能会不同,在此以具体数值示例,实际应用MapVirtualKey取得)。
        下面要讲Shift/Control/Alt修饰键与其它按键的组合怎样发送,对于Shift和Control用以下方式(用到 API keybd_event):
                keybd_event VK_SHIFT, &H2A, 0, 0  ' 模拟按下SHIFT键,&H2A是VK_SHIFT的扫描码
                PostMessage hWndMsg, WM_KEYDOWN, VK_A, &H001E0001 ' 模拟按下 A 键,SHIFT+A产生一个大写A字符
                PostMessage hWndMsg, WM_KEYUP, VK_A, &HC01E0001   ' 模拟抬起 A 键
                keybd_event VK_SHIFT, &H2A, KEYEVENTF_KEYUP, 0    ' 模拟抬起 SHIFT 键
        以上VK_SHIFT(扫描码2A)换成VK_CONTROL(扫描码1D)就可以实现Ctrl组合键,VK_A(扫描码1E)也可以换成任意功能键,如VK_F4(扫描码3E)。
        对于Alt修饰键比较特别,它属于系统按键,要用 WM_SYSKEYDOWN/WM_SYSKEYUP 消息,如下:
                PostMessage hWndMsg, WM_SYSKEYDOWN, VK_F4, &H003E0001 Or &H20000000 ' 模拟按下 Alt+F4
                PostMessage hWndMsg, WM_SYSKEYUP, VK_F4, &HC03E0001 Or &H20000000   '  模拟抬起 Alt+F4
                           ' &H20000000 为 context code 位,置 1 表示 Alt 键被按下

        至此,大功告成!祝各位心情愉快!

原创粉丝点击