模拟键盘输入 : SendMessage, keybd_event, PostKeybdMessage

模拟键盘输入 : SendMessage, keybd_event, PostKeybdMessage

  目的

  最近项目要求在Windows CE下模拟键盘输入,上网搜索了一下,发现有3个API可以用:SendMessage,keybd_event,PostKeybdMessage。

 

  分析

  1. SendMessage

  (1) 模拟输入字符 - ANSI

//  Input a 'a'
::SendMessage(hWnd, WM_CHAR,  ' a ' 0 );

  

  (2) 模拟输入字符 - Unicode

//  Input a '我'
::SendMessage(hWnd, WM_CHAR, L ' ' 0 )

  

  疑问:用SendMessage是直接向目标窗口发消息,很怀疑它是不是真的在“模拟”。

 

  2. keybd_event

  这个API的定义可以在这里找到:http://msdn.microsoft.com/en-us/library/aa453245.aspx

  (1) 模拟输入字符 - ANSI

//  Input a 'a'
::keybd_event( 0x41 0 0 0 );
::keybd_event(
0x41 0 , KEYEVENTF_KEYUP,  0 );

  

  (2) 模拟输入字符 - Unicode

  keybd_event的定义说,第一个参数bVk的取值范围只能是[1, 254],而且Windows CE下的keybd_event并不支持KEYEVENTF_UNICODE,而且我也没办法试出用keybd_event输入Unicode字符的方法。

 

  (3) 模拟输入命令

//  Paste - Ctrl + V
::keybd_event(VK_LCONTROL,  0 0 0 );
::keybd_event(
0x56 0 0 0 );
::keybd_event(
0x56 0 , KEYEVENTF_KEYUP,  0 );
::keybd_event(VK_LCONTROL, 
0 , KEYEVENTF_KEYUP,  0 );

  

   3. PostKeybdMessage

  这个API的定义可以在这里找到:http://msdn.microsoft.com/en-us/library/ms911936.aspx

  (1) 模拟输入字符

复制代码
PostKeybdMessage
LPWSTR lpszBuffer  =  L " 我是iVincentFeng " ;
INT nBufferLength 
=  ::wcslen(lpszBuffer);

UINT
*  lpStateFlags  =   new  UINT[nBufferLength];
UINT
*  lpTextBuffer  =   new  UINT[nBufferLength];
 
for  (INT nIndex  =   0 ; nIndex  <  nBufferLength; nIndex ++ )
{
    lpStateFlags[nIndex] 
=  KeyStateDownFlag;
    lpTextBuffer[nIndex] 
=  (UINT)lpszBuffer[nIndex];
}

::PostKeybdMessage(hWnd, 
0 , lpStateFlags[ 0 ], nLength, lpStateFlags, lpTextBuffer);

delete [] lpStateFlags;
delete [] lpTextBuffer;
复制代码

 

 

  总结

  个人认为

  1. 当需要模拟键盘输入命令时,比如Ctrl + V,选择keybd_event;

  2. 当需要模拟键盘输入一串字符时,选择PostKeybdMessage;

  3. 当需要模拟键盘输入单个字符时,选择keybd_event。

 

  资料

  1. Virtual-Key Codes: http://msdn.microsoft.com/en-us/library/ms927178.aspx


在VB6中,通过`BringWindowToTop`函数将程序窗口调至前台,然后使用`keybd_event`函数模拟按下Enter键进行发送操作。出现接收不到Enter信号的情况可能是由于以下原因之一: 1. 窗口焦点问题:使用`BringWindowToTop`函数将窗口调至前台时,可能会发生焦点切换的问题。如果目标窗口没有正确获取焦点,那么发送的按键消息可能不会被正确接收。你可以尝试在调用`BringWindowToTop`后,使用`SetForegroundWindow`函数将目标窗口设置为活动窗口,以确保它正确获取焦点。 2. 延迟问题:在发送按键消息之前,可能需要适当的延迟一段时间,以确保窗口完全展示在前台并准备好接收按键消息。你可以尝试在调用`BringWindowToTop`后,添加一个适当的延迟(使用`Sleep`函数)来等待窗口准备好接收按键消息。 3. 键盘事件不可靠:`keybd_event`函数是通过模拟键盘事件来发送按键消息的。然而,这种方式并不是完全可靠的,因为它依赖于系统的键盘事件处理机制。有时候可能会出现丢失按键消息的情况,特别是在高负载或系统资源紧张的情况下。你可以尝试使用其他方式发送按键消息,如使用`SendMessage`函数发送`WM_KEYDOWN`和`WM_KEYUP`消息。 请注意,以上是一些可能导致接收不到Enter信号的一般情况,具体问题可能还受到其他因素的影响。如果问题仍然存在,建议进行更详细的调试和排查,例如检查窗口的状态、使用其他方式发送按键消息等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值