WM_KEYDOWN和WM_KEYUP的使用

通过这两个消息可以模拟键盘事件。

相关函数:

MapVirtualKey: The MapVirtualKey function translates (maps) a virtual-key code into a scan code or character value, or translates a scan code into a virtual-key code.

VkKeyScan: The VkKeyScan function translates a character to the corresponding virtual-key code and shift state for the current keyboard.

PostMessage,SetForegroundWindow

 

WM_KEYDOWN和WM_KEYUP的 wParam就是虚拟键码,MSDN上可以查到,也可以通过VkKeyScan将一个字符转换成虚拟键码和shift状态的结合。

lParam的0到15位为该键在键盘上的重复次数,经常设为1,即按键1次;16至23位为键盘的扫描码,通过MapVirtualKey配合其参数可以得到;24位为扩展键,即某些右ALT和CTRL;29、30、31位按照说明设置即可(第30位对于keydown在和shift等结合的时候通常要设置为1)。

 

Specification of WM_KEYDOWN:

wParam

Specifies the virtual-key code of the nonsystem key.
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.
0-15
Specifies the repeat count for the current message. The value is the number of times the keystroke is autorepeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.
16-23
Specifies the scan code. The value depends on the OEM.
24
Specifies whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
25-28
Reserved; do not use.
29
Specifies the context code. The value is always 0 for a  WM_KEYDOWN message.
30
Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is zero if the key is up.
31
Specifies the transition state. The value is always zero for a  WM_KEYDOWN message.
Specification of WM_KEYUP: wParam
Specifies the virtual-key code of the nonsystem key.
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.
0-15
Specifies the repeat count for the current message. The value is the number of times the keystroke is autorepeated as a result of the user holding down the key. The repeat count is always one for a  WM_KEYUP message.
16-23
Specifies the scan code. The value depends on the OEM.
24
Specifies whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
25-28
Reserved; do not use.
29
Specifies the context code. The value is always 0 for a  WM_KEYUP message.
30
Specifies the previous key state. The value is always 1 for a  WM_KEYUP message.
31
Specifies the transition state. The value is always 1 for a  WM_KEYUP message.

Examples:

 

复制代码
  
  
1 char ch = ...; 2 SHORT tmp = VkKeyScan(ch); 3 WPARAM wParam = tmp & 0xFF ; 4 LPARAM lParam = 1 ; 5 lParam += MapVirtualKey(wParam, MAPVK_VK_TO_VSC) << 16 ; 6   bool shift = (tmp & 0x0100 ) == 0x0100 ? true : false ; 7   // 未考虑SHIFT,大小写的区分需通过SHIFT,注意设置第29位,可用Spy++捕获消息查看,此处只作备忘 8   PostMessage(h_wnd, WM_KEYDOWN, wParam, lParam); 9 lParam += 1 << 30 ; 10 lParam += 1 << 31 ; 11 PostMessage(h_wnd, WM_KEYUP, wParam, lParam);
复制代码

 

C++实现代码:
LPARAM lParam = 1;
lParam += MapVirtualKey(VK_1, MAPVK_VK_TO_VSC) << 16;
::PostMessage(hWnd,WM_KEYDOWN,VK_1,lParam);
lParam += 1 << 30;
lParam += 1 << 31;
::PostMessage(hWnd,WM_KEYUP,VK_1,lParam);

用keybd_event实现:

 

复制代码
  
  
1 char ch = ...; 2 SHORT tmp = VkKeyScan(ch); 3 BYTE vk = tmp & 0xFF ; 4 bool shift = (tmp & 0x0100 ) == 0x0100 ? true : false ; 5 if (shift) { 6 keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC), 0 , 0 ); 7 } 8 keybd_event(vk, MapVirtualKey(vk, MAPVK_VK_TO_VSC), 0 , 0 ); 9 keybd_event(vk, MapVirtualKey(vk, MAPVK_VK_TO_VSC), KEYEVENTF_KEYUP, 0 ); 10 if (shift) { 11 keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC), KEYEVENTF_KEYUP, 0 ); 12 }
复制代码
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
m_hWnd = 0表示微信主窗口的句柄不存在。在这段代码,如果m_hWnd的值为0,则需要通过FindWindowExA函数来查找微信主窗口的句柄。如果FindWindowExA函数返回的句柄值为0,可能是因为没有找到相应的窗口。以下是可能的问题和解决方法: 1. 确认微信主窗口已经打开。如果微信主窗口还未打开,那么FindWindowExA函数无法找到相应的窗口,并返回0。需要确保微信已经启动,并且主窗口已经显示出来。 2. 确认窗口类名和窗口名是否正确。如果窗口类名或窗口名不正确,FindWindowExA函数也无法找到相应的窗口,并返回0。需要根据实际情况修改代码的窗口类名和窗口名。 3. 确认代码是否正确。如果以上几种情况都确认无误,可能是代码本身存在问题。可以检查代码的变量名、函数名等是否正确,以及代码是否存在语法错误等问题。可以借助IDE等工具进行排查。 可以在代码添加一些调试信息,例如输出窗口类名、窗口名和句柄值等,以便更好地进行排查。例如: ```vb.net Public Sub OpenChatWindow(ByVal name As String) Debug.Print("m_hWnd = " & m_hWnd) If m_hWnd = 0 Then m_hWnd = FindWindowExA(0, 0, "WeChatMainWndForStore", vbNullString) Debug.Print("FindWindowExA returned " & m_hWnd) End If If m_hWnd <> 0 Then Dim hEdit As Long hEdit = FindWindowExA(m_hWnd, 0, "Edit", vbNullString) Debug.Print("FindWindowExA returned " & hEdit) If hEdit <> 0 Then SendMessageA hEdit, WM_SETTEXT, 0, ByVal name & vbNullChar PostMessageA hEdit, WM_KEYDOWN, VK_RETURN, 0 PostMessageA hEdit, WM_KEYUP, VK_RETURN, 0 End If End If End Sub ``` 在上述代码,添加了Debug.Print语句用于输出调试信息。可以通过调试窗口查看输出的信息,以便更好地进行排查。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值