模拟键盘鼠标按键

来源:互联网 发布:古墓丽影for mac 编辑:程序博客网 时间:2024/05/16 07:21

一、模拟单个按键,如按下键A
用::PostMessage(hWnd,WM_KEYDOWN,'A',0); 在一般情况下可以,即使目标程序在后台运行也可以。
但正如你等下在下面看到的文章所说,在某些程序里第四个参数需要特别注意,否则发送按键将无效。

二、模拟ALT+'A'
向后台程序发送组合键ALT+按键 是可行的。记住,只可以是ALT,不能是Ctrl或Shift
操作如下:发送ALT+'A'
::PostMessage(hWnd,WM_SYSKEYDOWN,'A',1<<29);

三、我现在的做法只能是激活目标窗口使其成为前台窗口后再模拟发送组合按键,如下:
但这个方法有时也不行,因为SetForegroundWindow有时会无法激活窗口
SetForegroundWindow(g_OperaWnd);
keybd_event(VK_CONTROL,0,0,0);
keybd_event(65,0,0,0);
keybd_event(65,0,KEYEVENTF_KEYUP,0);
keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0); 

四、模拟鼠标的行为最好用SendMessage(不要用PostMessage),这样可以把消息直接发送
到目的窗口的窗口处理过程。成功率会高很多。
::SendMessage(GetWnd(),WM_LBUTTONDOWN,NULL,MAKELPARAM(47,11));
::SendMessage(GetWnd(),WM_LBUTTONUP,NULL,MAKELPARAM(40,65));
::SendMessage(GetWnd(),WM_MOUSEMOVE,NULL,MAKELPARAM(40,65));

五、按以下文章所说的,我们不能用PostMessage模拟键盘组合键
http://blogs.msdn.com/b/oldnewthing/archive/2005/05/30/423202.aspx

以上转自:http://www.cnblogs.com/Jnshushi99/archive/2011/09/03/2164617.html


怎么用PostMessage  按下虚拟键 F1

DWORD dwVKFkeyData;
 WORD dwScanCode =MapVirtualKey(VK_F1,0);//VK_F1
 dwVKFkeyData = 1;
 dwVKFkeyData |= dwScanCode<<16;
 dwVKFkeyData |= 0<<24;
 dwVKFkeyData |= 1<<29;
 //按下
 ::PostMessage((HWND)0x203f0,WM_KEYDOWN,VK_F1,dwVKFkeyData);
 //弹起
 dwVKFkeyData |= 3 << 30;
 ::PostMessage((HWND)0x203f0,WM_KEYUP,VK_F1,dwVKFkeyData); 

转自:http://bbs.csdn.net/topics/380091530


PostMessage 向Windows窗口发送Alt组合键

关于向Windows窗口发送Alt组合键的问题,这个真是经典问题啊,在网上找了一下,问的人N多,方法差不多,

但就是没有很好解决问题。

之前找到一个能正确发送的code:(Alt+A)

PostMessage(hWnd,WM_SYSKEYDOWN,VK_MENU,0);

PostMessage(hWnd,WM_SYSKEYDOWN,0x41,0);

Sleep(50);

PostMessage(hWnd,WM_SYSKEYUP,0x41,0);

PostMessage(hWnd,WM_SYSKEYUP,VK_MENU,0);

有人解释说,按下组合键的时候系统是发两条消息的

但是看到Win32 SDK,感觉上就发一次就可以了……

偶然间又看到最后一个参数的说明,有所发现!先看WM_SYSKEYDOWN的help

The WM_SYSKEYDOWN message is posted to the window with the keyboard focus when the user holds down the ALT key and then presses another key. It also occurs when no window currently has the keyboard focus; in this case, the WM_SYSKEYDOWN message is sent to the active window. The window that receives the message can distinguish between these two contexts by checking the context code in the lKeyData parameter. 

WM_SYSKEYDOWN  
nVirtKey = (int) wParam; // virtual-key code 
lKeyData = lParam;       // key data 

Parameters

nVirtKey
Value of wParam. Specifies the virtual-key code of the key being pressed. 

lKeyData
Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table: 

Value Description
0-15位:指定当前消息的重复次数。其值就是用户按下该键后自动重复的次数,但是重复次数不累积
16-23位:指定其扫描码,其值依赖于OEM厂商
24位:指定该按键是否为扩展按键,所谓扩展按键就是Ctrl,Alt之类的,如果是扩展按键,其值为1,否则为0
25-28位:保留字段,暂时不可用
29位:指定按键时的上下文,其值为1时表示在按键时Alt键被按下,其值为0表示WM_SYSKEYDOWN消息因没有任何窗口有键盘焦点而被发送到当前活动窗口。
30位:指定该按键之前的状态,其值为1时表示该消息发送前,该按键是被按下的,其值为0表示该消息发送前该按键是抬起的。
31位:指定其转换状态,对WM_SYSKEYDOWN消息而言,其值总为0。

之前曾经修改过keyData的16-23位为VK_MENU,第30位参数为1,但没效果

请看位29的说明!!

The value is 1 if the ALT key is down while the key is pressed; 

当值为1时表示ALT键被按下!这不正是我需要的吗?于是把29位设置为1,函数调用变成

PostMessage(hWnd,WM_SYSKEYDOWN,0x41,1<<29);

经过测试,发现这个就是Alt+A的效果!!原来这么简单,但为什么很多人弄得那么复杂,我当时查找的时候也是迷惘啊,浪费了N多小时。

类似有个WM_SYSKEYUP,WM_SYSCHAR(这个不知道干什么用)


转自:http://www.cnblogs.com/willen/archive/2008/10/22/1316523.html



WM_KEYDOWN:

0-15位:指定当前消息的重复次数。其值就是用户按下该键后自动重复的次数,但是重复次数不累积
16-23位:指定其扫描码,其值依赖于OEM厂商
24位:指定该按键是否为扩展按键,所谓扩展按键就是Ctrl,Alt之类的,如果是扩展按键,其值为1,否则为0
25-28位:保留字段,暂时不可用
29位:指定按键时的上下文,其值为1时表示在按键时Alt键被按下,其值为0表示WM_SYSKEYDOWN消息因没有任何窗口有键盘焦点而被发送到当前活动窗口。
30位:指定该按键之前的状态,其值为1时表示该消息发送前,该按键是被按下的,其值为0表示该消息发送前该按键是抬起的。
31位:指定其转换状态,对WM_SYSKEYDOWN消息而言,其值总为0。

Param资讯
  在四个按键讯息(WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN和WM_SYSKEYUP)中,wParam讯息参数含有上面
所讨论的虚拟键码,而lParam讯息参数则含有对了解按键非常有用的其他资讯。lParam的32位分为6个栏位,
如图所示。在Win 3.x中,WPARAM是16位的,而LPARAM是32位的,两者有明显的区别。因为地址通常是32位的,
所以LPARAM被用来传递地址,这个习惯在Win32 API中仍然能够看到。在Win32 API中,WPARAM和LPARAM都是32位,
所以没有什么本质的区别。Windows的消息必须参考帮助文件才能知道具体的含义。如果是你定义的消息,
愿意怎么使这两个参数都行。但是习惯上,我们愿意使用LPARAM传递地址,而WPARAM传递其他参数。

PostMessage模拟后台按键第四参数的初次探究
  最近做游戏挂机的时候,遇到一个问题。PostMessage可以很方便地后台按键,可是第四个参数却随着第三个参数(按键代码,或称虚拟键码)的改变而改变。在普通的程序中,第四个参数赋予零就可以实现按键,但是在游戏中是不行的(可能是游戏会检测吧,个人猜测)

原来 lParam 有特殊的含义,其第0~15位是表示键重复的次数,第16~23位是键的 Scan Code,组合键需要设置第24位。看来问题是在第16~23位的 Scan Code 上了。怎么获取这个 Scan Code 呢?其实很容易,微软给我们提供了一个 API:MapVirtualKey。


如何用postmessage发送组合键shift+f5(即模拟键盘上同时按下shift+f5)


BYTE   key[256] = {0x00};   
key[VK_SHIFT] = 0x80; 
BOOL bOK = SetKeyboardState(key);   
PostMessage(WM_KEYDOWN, VK_F5, 0); 


转自:http://bbs.csdn.net/topics/340010599