keybd_event(win32 api)键盘事件 模拟键盘

Win32API中提供了 keybd_event 函数

Syntax
VOID WINAPI keybd_event(
   _In_ BYTE      bVk,
   _In_ BYTE      bScan,
   _In_ DWORD     dwFlags,
   _In_ ULONG_PTR dwExtraInfo
);


Demonstration:
#include <windows.h>
#include <stdio.h>
 
void SendKey(const char ch) {
    DWORD sc, shift;
    unsigned char vkey;
    sc = OemKeyScan(ch);
    shift = sc >> 16;
    vkey = MapVirtualKey(sc & 0xffff, 1);
    if (shift)
        keybd_event(VK_SHIFT, 0, 0, 0);
 
    keybd_event(vkey, 0, 0, 0);
    keybd_event(vkey, 0, KEYEVENTF_KEYUP, 0);
 
    if (shift)
        keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
}
 
void SendKeyString(const char *str) {
    DWORD sc, shift;
    unsigned char vkey;
    int i;
    for (i = 0; str[i] != '\0'; i++) {
        sc = OemKeyScan(str[i]);
        shift = sc >> 16;
        vkey = MapVirtualKey(sc & 0xffff, 1);
        if (shift)
            keybd_event(VK_SHIFT, 0, 0, 0);
 
        keybd_event(vkey, 0, 0, 0);
        keybd_event(vkey, 0, KEYEVENTF_KEYUP, 0);
 
        if (shift)
            keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
    }
}
 
int main() {
    // hello world text to send
    // load text from a file in practise
    const char *text =
    "#include <stdio.h>\n"
    "int main() {\n"
    "\tprintf(\"Hello world!\\n\");\n"
    "\treturn 0;\n"
    "}\n";
 
    // count down for 3 sec
    // after 3 sec, this program will simulate keyboard events
    // prepared to choose the target window to send text
    
    putchar('\a');
    Sleep(1000);
    putchar('\a');
    Sleep(1000);
    putchar('\a');
    Sleep(1000);
 
    SendKeyString(text);
    return 0;
}


微软表示这个函数已经被废弃了,推荐用SendInput 来代替它。本人亲测以上代码在记事本窗口中成功输入,但是切换到云桌面窗口无效,估计是因为云桌面为了键盘响应的效率,直接使用了底层的键盘驱动程序。我尝试修改过传入bScan(扫描码)但不奏效,估计改用SendInput也不会成功。

为了更好地支持底层键盘输入,可以考虑WinIO库或者使用按键精灵软件。

Parameters
bVk [in]
Type: BYTE

A virtual-key code. The code must be a value in the range 1 to 254. For a complete list, see Virtual Key Codes.

bScan [in]
Type: BYTE

A hardware scan code for the key.

dwFlags [in]
Type: DWORD

Controls various aspects of function operation. This parameter can be one or more of the following values.

Value    Meaning
KEYEVENTF_EXTENDEDKEY
0x0001
If specified, the scan code was preceded by a prefix byte having the value 0xE0 (224).

KEYEVENTF_KEYUP
0x0002
If specified, the key is being released. If not specified, the key is being depressed.

dwExtraInfo [in]
Type: ULONG_PTR

An additional value associated with the key stroke.

参数 类型及说明 
bVk Byte 定义一个虚据拟键码。键码值必须在1~254之间。
bScan Byte 键的OEM扫描码 (一般置零)
dwFlags Long 零;或设为下述两个标志之一 
KEYEVENTF_EXTENDEDKEY 指出是一个扩展键,而且在前面冠以0xE0代码 
KEYEVENTF_KEYUP 模拟松开一个键 
dwExtraInfo Long 通常不用的一个值。api函数GetMessageExtraInfo可取得这个值。允许使用的值取决于特定的驱动程序

备注:尽管keybd_event传递一个与OEM相关的硬件扫描码给系统,但应用程序不能用 此扫描码。系统在内部将扫描码转换成虚拟键码,并且在传送给应用程序前清除键码的UP/down位。应用程序可以摸拟PRINTSCREEN键的按下来获 得一个屏幕快照,并把它存放到剪切板中。若要做到这一点,则要将keybd_event的bVk参数置为VK_SNAPSHOT,bScan参数置为 0(用以获得全屏快照)或hScan置为1(仅获得活动窗口的快照)。Windows CE:WindowsCE支持dwFlags参数附加的标志位。即使用KEYEVENTF_SILENT标志模拟击键,而不产生敲击的声音。 Windows CE不支持KEYEVENTF_EXTENDEDKEY标志。
//鼠标点击,移动事件
void MouseMove(DWORD dx, DWORD dy)
{
	int width = GetSystemMetrics(SM_CXSCREEN);
	int height = GetSystemMetrics(SM_CYSCREEN);

	double cx = 65535.0 / width;
	double cy = 65535.0 / height;

	dx = dx * cx;
	dy = dy * cy;

	mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, dx, dy, 0, 0);
}

void MouseMoveR(DWORD dx, DWORD dy)
{
	int width = GetSystemMetrics(SM_CXSCREEN);
	int height = GetSystemMetrics(SM_CYSCREEN);

	double cx = 65535.0 / width;
	double cy = 65535.0 / height;

	dx = dx * cx;
	dy = dy * cy;

	mouse_event(MOUSEEVENTF_MOVE, dx, dy, 0, 0);
}

void MouseClickL()
{
	mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
	mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值