keybd_event()使用方法

keybd_event()使用方法

函数说明

函数功能:keybd_event函数模拟一次击键事件。系统可使用这种模拟的击键事件来产生WM_KEYUPWM_KEYDOWN消息,键盘驱动程序的中断处理程序调用keybd_event函数。在Windows NT中该函数己被使用SendInput来替代它完成操作。

函数原型VOID keybd_eventBYTE bVkBYTE bScanDWORD dwFlagsDWORD dwExtralnfo);

函数参数

bVk:定义一个虚拟键码,键码值必须在1254之间。

bScan:定义该键的硬件扫描码。

dwFlags:定义函数操作的各个方面的一个标志位集。应用程序可使用如下一些预定义常数的组合设置标志位:

  1. KEYEVENTF_EXTENDEDKEY:若指定该值,则扫描码前一个值为OXEO224)的前缀字节。
  2. KEYEVENTF_KEYUP:若指定该值,该键将被释放;若未指定该值,该键将被按下。

dwExtralnfo:定义与击键相关的附加的32位值。

返回值:该函数无返回值。

#include<afx.h>

#include<WinUser.h>

#include<Windows.h>

voidmain()

{

keybd_event(16,0,0,0);    // 按下Shift

keybd_event('A',0,0,0);    // 按下a

Sleep(100);

keybd_event('A',0,KEYEVENTF_KEYUP,0);// 松开a

keybd_event(16,0,KEYEVENTF_KEYUP,0);// 松开Shift

// 构成组合键---->按下Shift的同时按下a,形成A

}

使用说明

尽管keybd_event函数传递一个与OEM相关的硬件扫描码给系统,但应用程序不能用此扫描码。系统在内部将扫描码转换成虚拟键码,并且在传送给应用程序前清除键码的UP/DOWN位。应用程序可以摸拟PRINTSCREEN键的按下来获得一个屏幕快照,并把它存放到剪切板中。若要做到这一点,则要将keybd_eventbVk参数置为VK_SNAPSHOTbScan参数置为0(用以获得全屏快照)或hScan置为1(仅获得活动窗口的快照)。

Windows CEWindowsCE支持dwFlags参数附加的标志位,即使用KEYEVENTF_SILENT标志模拟击键,而不产生敲击的声音。

Windows CE不支持KEYEVENTF_EXTENDEDKEY标志。

适用版本

速查:Windows NT3.1及以上版本;Windows95及以上版本 Windows CE1.0及以上版本;头文件:winuser.h;库文件:user32.lib

详细说明

Windows提供了一个模拟键盘操作的API函数keybd_event(),使用该函数可以模拟相应的键盘动作。keybd_event()函数能触发一个按键事件,也就是说会产生一个WM_KEYDOWNWM_KEYUP消息。该函数原型如下:

VOID keybd_event(

BYTE bVk,                     // virtual-key code

BYTE bScan,                  // hardware scan code

DWORD dwFlags,         // flags specifying various function options

DWORD dwExtraInfo   // additional data associated with keystroke);

从原型可以看出,keybd_event ()共有四个参数:

bVk:按键虚拟键值,如回车键为vk_returnTab键为vk_tab

bScan:为扫描码,一般不用设置,用0代替就行;

dwFlags:为选项标志,如果为keydown则置0即可,如果为keyup则设成"KEYEVENTF_KEYUP"

dwExtraInfo:一般置0即可。

// 例子1:模拟按下'A'

keybd_event(65,0,0,0);

keybd_event(65,0,KEYEVENTF_KEYUP,0);

// 例子2:模拟按下'ALT+F4'

keybd_event(18,0,0,0);

keybd_event(115,0,0,0);

keybd_event(115,0,KEYEVENTF_KEYUP,0);

keybd_event(18,0,KEYEVENTF_KEYUP,0);

实用例程

模拟键盘平时不是很常用,但是当调用某些快捷键执行某项功能时,它真的是那么的方便,看看下面的实现。

1. 显示桌面

很多软件有显示桌面的功能,并且大家的方法都是遍历窗口,然后让它们最小化,其实Windows系统给了一个非常方便的WIN键(就是键盘上在CTRL键和ALT键之间的那个带win标志的按键)。利用它可以轻松的完成显示桌面的功能。

// 显示桌面

keybd_event(VK_LWIN, 0, 0 ,0);

keybd_event('M', 0, 0 ,0);

keybd_event('M', 0, KEYEVENTF_KEYUP ,0);

keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);

其他的操作也类似,比如直接显示“开始”的运行,就把上面的'M'换成'R'即可。

// 显示开始运行

keybd_event(VK_LWIN, 0, 0 ,0);

keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);

直接显示“开始”对话框了。

2. 实现快速全选

很多的时候,比如listctrl实现全选,你可以用listctrl循环设置每一项的状态为选中,多啰嗦的事情。用快捷键试一试CTRLA,其他的快捷键一样的用法。

keybd_event(VK_CONTROL, (BYTE)0, 0 ,0);

keybd_event('A',(BYTE)0, 0 ,0); //此处可以用  'A', (BYTE)65, 'a'不起作用.

keybd_event('A', (BYTE)0, KEYEVENTF_KEYUP,0);

keybd_event(VK_CONTROL, (BYTE)0, KEYEVENTF_KEYUP,0);

3. 执行某些特殊键,比如数字键,大小写键

bool bState=true;              // true为按下NumLockfalse反之

BYTE keyState[256];

GetKeyboardState((LPBYTE)&keyState);

if( (bState && !(keyState[VK_NUMLOCK] & 1)) ||

 (!bState && (keyState[VK_NUMLOCK] & 1)) )

{

// Simulate a key press

keybd_event( VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0 );

// Simulate a key release

keybd_event( VK_NUMLOCK, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);

}

4. 实现CTRLALTDELETE三键一起按下

keybd_event(VK_CONTROL, 0, 0 ,0);

keybd_event(VK_MENU,0, 0 ,0);

keybd_event(VK_DELETE,0, 0 ,0);

keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP ,0);

keybd_event(VK_MENU,0, KEYEVENTF_KEYUP ,0);

keybd_event(VK_DELETE,0, KEYEVENTF_KEYUP ,0);

这样不会成功,因为这几个键是操作系统直接截获执行的,而模拟键盘只能发向应用程序,所以这种方法不行的(想显示锁定对话框,用LockWorkStation();

5. Window2000/NT/XP已经不提倡用这个函数了,上面的方法只是为了让大家开阔一下思路,怎么替代?

// Window2000/NT/XP下用这个代替,包含"winable.h"

INPUT input[4];

memset(input, 0, sizeof(input));

input[0].type = input[1].type = input[2].type = input[3].type = INPUT_KEYBOARD;

input[0].ki.wVk  = input[3].ki.wVk = VK_LWIN;

input[1].ki.wVk  = input[2].ki.wVk = 'R';

//接下来释放它,这一点很重要。

input[2].ki.dwFlags = input[3].ki.dwFlags = KEYEVENTF_KEYUP;

input[0].ki.time = input[1].ki.time = input[2].ki.time = input[3].ki.time = GetTickCount();

SendInput(4, input, sizeof(INPUT));

感觉比那个有点啰嗦。

WIN键部分快捷键

WIN+D=快速的切到桌面,再次点击返回;

WIN+E=快速打开资源管理器;

WIN+R=“运行

WIN+M=全部视窗最小化;

WIN+Shift+M=取消全部视窗最小化;

WIN+F1=Help

WIN+F=“寻找”;

WIN+Ctrl+F=显示“查找电脑”;

WIN+Tab=切换工作列的程式;

WIN+Break=显示系统内容。

SendMessage、PostMessage、keybd_event区别

首先你会发现keybd_event函数中是没有窗口句柄作为参数的,那是因为keybd_event是全局模拟按键的,只对前台窗口(即当前的活动窗口)才可以,但是如果模拟的按键正好也是某个窗口的全局热键消息,那该窗口也能接收到的。

SendMessagePostMessage是对指定句柄窗口都起作用的,对于做一些外挂是非常有用的。例如可以做成这样的效果:即用SendMessage/PostMessage在某一个窗口模拟动作,而同时自己可以在其他窗口做其他事情,互不影响!

但是有一点要注意,很多人在模拟键盘消息的时候,都会忘记模拟WM_KEYUP的消息。

还有一点就是PostMessage中的窗口句柄参数,可以设置为HWND_BROADCAST,即广播,但不要理所当然地认为是对所有的窗口都起作用。它只对系统的顶层窗口起作用,子窗口是收不到这个消息的!

还要注意的是SendMessage是没有HWND_BROADCAST参数的,那是因为,SendMessage总是等发送的消息在对应的窗口消息队列中处理完毕后才返回的(这是一种负责的行为),细想一下就知道为什么SendMessage没有HWND_BROADCAST参数了!

个人认为:

  1. 当需要模拟键盘输入命令时,比如Ctrl + V,选择keybd_event
  2. 当需要模拟键盘输入一串字符时,选择PostKeybdMessage
  3. 当需要模拟键盘输入单个字符时,选择keybd_event

// 实例

SendMessage(Button.Handle, WM_LBUTTONDOWN, 0, 0);   //鼠标左键按下 

SendMessage(Button.Handle, WM_LBUTTONUP, 0, 0);   //鼠标左键抬起

SendMessage(Edit.Handle, WM_SETTEXT, 255, Integer(PChar('abc')));   //传递文本

SendMessage(Edit.Handle, WM_Char, Wparam('Q'), 2);   // 传递字符

SendMessage(Button.Handle, BM_SETSTYLE, BS_RADIOBUTTON, 1);   //改变Button风格

SendMessage(ComboBox.Handle, CB_SETDROPPEDWIDTH, 300, 0);   //改变CBDownWidth

WM_CUTWM_COPYWM_PASTE剪切,复制,粘帖 

实现任意组合键:

keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), 0, 0);

keybd_event(ord('V'), MapVirtualKey(ord('V'), 0), 0, 0);

keybd_event(ord('V'), MapVirtualKey(ord('V'), 0), KEYEVENTF_KEYUP, 0); 

keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), KEYEVENTF_KEYUP, 0);

模拟鼠标按下事件:

::PostMessage(hwd0,WM_MOUSEMOVE, MK_LBUTTON, MAKELONG(x,y));

::PostMessage(hwd0,WM_LBUTTONDOWN,MK_LBUTTON,MAKELPARAM(x,y));

::PostMessage(hwd0,WM_LBUTTONUP,MK_LBUTTON,MAKELPARAM(x,y));

模拟键盘按下事件

keybd_event(VK_TAB,0,0,0);

keybd_event(VK_TAB,0,KEYEVENTF_KEYUP,0);

你可能感兴趣的:(Visual,C++,软件开发)