SendKeyEvent 键盘事件发送
概述
SendKeyEvent 是FBro浏览器提供的免费键盘事件发送方法,无需VIP权限即可使用。该方法通过构造 FBroSharpKeyEvent 结构体来模拟键盘输入事件,适用于前台窗口的键盘操作。
与VIP键盘事件的区别
| 特性 | SendKeyEvent (免费) | VIP键盘事件 |
|---|---|---|
| 授权要求 | 免费,无需VIP | 需要VIP授权 |
| 操作范围 | 仅支持前台窗口 | 支持前台和后台操作 |
| 复杂度 | 需要手动构造事件结构体 | 提供便捷的封装方法 |
| 文本输入 | 需要逐字符处理 | 支持直接文本输入 |
| 使用难度 | 相对复杂 | 相对简单 |
基础用法
1. 基本调用结构
csharp
// 创建键盘事件结构体
var keyEvent = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYDOWN,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = 13, // Enter键
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
// 发送键盘事件
browser.SendKeyEvent(keyEvent);2. 发送单个按键
csharp
public void SendSingleKey(IFBroSharpBrowser browser, int keyCode)
{
// 按键按下事件
var keyDownEvent = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYDOWN,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = keyCode,
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(keyDownEvent);
Thread.Sleep(50); // 短暂延迟
// 按键释放事件
var keyUpEvent = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYUP,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = keyCode,
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(keyUpEvent);
}3. 发送组合键
csharp
public void SendCtrlKey(IFBroSharpBrowser browser, int keyCode)
{
// Ctrl+某键的按下事件
var ctrlKeyDown = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYDOWN,
modifiers = FBroSharpEventFlags.EVENTFLAG_CONTROL_DOWN, // Ctrl键修饰符
windows_key_code = keyCode, // 目标键的虚拟键码
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(ctrlKeyDown);
Thread.Sleep(50);
// Ctrl+某键的释放事件
var ctrlKeyUp = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYUP,
modifiers = FBroSharpEventFlags.EVENTFLAG_CONTROL_DOWN, // Ctrl键修饰符
windows_key_code = keyCode, // 目标键的虚拟键码
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(ctrlKeyUp);
}4. 发送字符输入
csharp
public void SendCharacter(IFBroSharpBrowser browser, char character)
{
var charEvent = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_CHAR,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = 0,
native_key_code = 0,
is_system_key = 0,
character = character,
unmodified_character = character,
focus_on_editable_field = 1
};
browser.SendKeyEvent(charEvent);
}数据结构详解
FBroSharpKeyEvent 结构体
csharp
public struct FBroSharpKeyEvent
{
public FBroKeyEventType type; // 键盘事件类型
public FBroSharpEventFlags modifiers; // 修饰键标志
public int windows_key_code; // Windows虚拟键码
public int native_key_code; // 本地键码
public int is_system_key; // 是否为系统键
public char character; // 字符
public char unmodified_character; // 未修饰字符
public int focus_on_editable_field; // 是否焦点在可编辑字段
}字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
type | FBroKeyEventType | 键盘事件类型(按下、释放、字符等) |
modifiers | FBroSharpEventFlags | 修饰键状态(Ctrl、Alt、Shift等) |
windows_key_code | int | Windows虚拟键码 |
native_key_code | int | 本地键码(通常设为0) |
is_system_key | int | 是否为系统键(通常设为0) |
character | char | 要输入的字符(用于KEYEVENT_CHAR类型) |
unmodified_character | char | 未修饰的字符 |
focus_on_editable_field | int | 焦点是否在可编辑字段(0或1) |
FBroKeyEventType 枚举
csharp
public enum FBroKeyEventType
{
KEYEVENT_RAWKEYDOWN, // 按键从"抬起"转为"按下"
KEYEVENT_KEYDOWN, // 按键按下通知
KEYEVENT_KEYUP, // 按键释放通知
KEYEVENT_CHAR // 字符输入通知
}事件类型说明:
| 类型 | 说明 | 使用场景 |
|---|---|---|
KEYEVENT_RAWKEYDOWN | 原始按键按下事件 | 底层按键检测 |
KEYEVENT_KEYDOWN | 按键按下事件 | 功能键、组合键 |
KEYEVENT_KEYUP | 按键释放事件 | 完成按键操作 |
KEYEVENT_CHAR | 字符输入事件 | 文本输入 |
FBroSharpEventFlags 修饰键标志
csharp
public enum FBroSharpEventFlags
{
EVENTFLAG_NONE = 0, // 无修饰键
EVENTFLAG_CAPS_LOCK_ON = 1, // 大写锁定开启
EVENTFLAG_SHIFT_DOWN = 2, // Shift键按下
EVENTFLAG_CONTROL_DOWN = 4, // Ctrl键按下
EVENTFLAG_ALT_DOWN = 8, // Alt键按下
EVENTFLAG_LEFT_MOUSE_BUTTON = 0x10, // 左鼠标按钮
EVENTFLAG_MIDDLE_MOUSE_BUTTON = 0x20, // 中鼠标按钮
EVENTFLAG_RIGHT_MOUSE_BUTTON = 0x40, // 右鼠标按钮
EVENTFLAG_COMMAND_DOWN = 0x80, // Command键按下(Mac)
EVENTFLAG_NUM_LOCK_ON = 0x100, // 数字锁定开启
EVENTFLAG_IS_KEY_PAD = 0x200, // 来自键盘数字键盘
EVENTFLAG_IS_LEFT = 0x400, // 左侧键
EVENTFLAG_IS_RIGHT = 0x800, // 右侧键
EVENTFLAG_ALTGR_DOWN = 0x1000, // AltGr键按下
EVENTFLAG_IS_REPEAT = 0x2000 // 重复按键
}组合键配置说明
对于组合键操作,需要同时配置两个关键参数:
| 组合键 | modifiers参数 | windows_key_code参数 | 示例 |
|---|---|---|---|
| Ctrl+C | EVENTFLAG_CONTROL_DOWN | 67 (C键) | 复制操作 |
| Ctrl+V | EVENTFLAG_CONTROL_DOWN | 86 (V键) | 粘贴操作 |
| Ctrl+A | EVENTFLAG_CONTROL_DOWN | 65 (A键) | 全选操作 |
| Alt+F4 | EVENTFLAG_ALT_DOWN | 115 (F4键) | 关闭窗口 |
| Shift+Tab | EVENTFLAG_SHIFT_DOWN | 9 (Tab键) | 反向切换 |
重要说明:
modifiers字段设置修饰键(Ctrl、Alt、Shift等)windows_key_code字段设置主按键的虚拟键码- 多个修饰键可以通过位运算组合(如:
EVENTFLAG_CONTROL_DOWN | EVENTFLAG_SHIFT_DOWN)
常用按键代码
基础按键
| 按键 | 虚拟键码 | 按键 | 虚拟键码 |
|---|---|---|---|
| Enter | 13 | Space | 32 |
| Tab | 9 | Backspace | 8 |
| Escape | 27 | Delete | 46 |
字母按键(A-Z)
| 按键 | 虚拟键码 | 按键 | 虚拟键码 | 按键 | 虚拟键码 |
|---|---|---|---|---|---|
| A | 65 | J | 74 | S | 83 |
| B | 66 | K | 75 | T | 84 |
| C | 67 | L | 76 | U | 85 |
| D | 68 | M | 77 | V | 86 |
| E | 69 | N | 78 | W | 87 |
| F | 70 | O | 79 | X | 88 |
| G | 71 | P | 80 | Y | 89 |
| H | 72 | Q | 81 | Z | 90 |
| I | 73 | R | 82 |
数字按键(0-9)
| 按键 | 虚拟键码 | 按键 | 虚拟键码 |
|---|---|---|---|
| 0 | 48 | 5 | 53 |
| 1 | 49 | 6 | 54 |
| 2 | 50 | 7 | 55 |
| 3 | 51 | 8 | 56 |
| 4 | 52 | 9 | 57 |
实际应用示例
1. 发送Enter键
csharp
public void PressEnter(IFBroSharpBrowser browser)
{
// 按下Enter键
var keyDown = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYDOWN,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = 13,
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(keyDown);
Thread.Sleep(50);
// 释放Enter键
var keyUp = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYUP,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = 13,
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(keyUp);
}2. 发送Ctrl+C(复制)
csharp
public void CopyText(IFBroSharpBrowser browser)
{
// Ctrl+C按下
var ctrlCDown = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYDOWN,
modifiers = FBroSharpEventFlags.EVENTFLAG_CONTROL_DOWN, // Ctrl键修饰符
windows_key_code = 67, // C键的虚拟键码
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(ctrlCDown);
Thread.Sleep(50);
// Ctrl+C释放
var ctrlCUp = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYUP,
modifiers = FBroSharpEventFlags.EVENTFLAG_CONTROL_DOWN, // Ctrl键修饰符
windows_key_code = 67, // C键的虚拟键码
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(ctrlCUp);
}3. 输入文本字符串
csharp
public void TypeText(IFBroSharpBrowser browser, string text)
{
foreach (char c in text)
{
// 发送字符事件
var charEvent = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_CHAR,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = 0,
native_key_code = 0,
is_system_key = 0,
character = c,
unmodified_character = c,
focus_on_editable_field = 1
};
browser.SendKeyEvent(charEvent);
Thread.Sleep(10); // 模拟打字延迟
}
}4. 综合表单填写示例
csharp
public void FillForm(IFBroSharpBrowser browser)
{
// 输入用户名
TypeText(browser, "username");
// 按Tab键切换到下一个字段
SendSingleKey(browser, 9); // Tab键
Thread.Sleep(100);
// 输入密码
TypeText(browser, "password123");
// 按Enter提交
PressEnter(browser);
}
// 辅助方法:输入文本
private void TypeText(IFBroSharpBrowser browser, string text)
{
foreach (char c in text)
{
var charEvent = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_CHAR,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = 0,
native_key_code = 0,
is_system_key = 0,
character = c,
unmodified_character = c,
focus_on_editable_field = 1
};
browser.SendKeyEvent(charEvent);
Thread.Sleep(10);
}
}
// 辅助方法:发送单个按键
private void SendSingleKey(IFBroSharpBrowser browser, int keyCode)
{
// 按键按下
var keyDown = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYDOWN,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = keyCode,
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(keyDown);
Thread.Sleep(50);
// 按键释放
var keyUp = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYUP,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = keyCode,
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(keyUp);
}封装工具类
为了简化使用,可以创建一个工具类:
csharp
public static class KeyboardHelper
{
/// <summary>
/// 发送单个按键(按下+释放)
/// </summary>
public static void SendKey(IFBroSharpBrowser browser, int keyCode,
FBroSharpEventFlags modifiers = FBroSharpEventFlags.EVENTFLAG_NONE)
{
// 按键按下
var keyDown = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYDOWN,
modifiers = modifiers,
windows_key_code = keyCode,
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(keyDown);
Thread.Sleep(50);
// 按键释放
var keyUp = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_KEYUP,
modifiers = modifiers,
windows_key_code = keyCode,
native_key_code = 0,
is_system_key = 0,
character = '\0',
unmodified_character = '\0',
focus_on_editable_field = 0
};
browser.SendKeyEvent(keyUp);
}
/// <summary>
/// 输入文本字符串
/// </summary>
public static void TypeText(IFBroSharpBrowser browser, string text, int delay = 10)
{
foreach (char c in text)
{
var charEvent = new FBroSharpKeyEvent
{
type = FBroKeyEventType.KEYEVENT_CHAR,
modifiers = FBroSharpEventFlags.EVENTFLAG_NONE,
windows_key_code = 0,
native_key_code = 0,
is_system_key = 0,
character = c,
unmodified_character = c,
focus_on_editable_field = 1
};
browser.SendKeyEvent(charEvent);
Thread.Sleep(delay);
}
}
/// <summary>
/// 发送组合键
/// </summary>
public static void SendCombination(IFBroSharpBrowser browser, int keyCode,
FBroSharpEventFlags modifiers)
{
SendKey(browser, keyCode, modifiers);
}
}使用工具类示例
csharp
// 发送Enter键
KeyboardHelper.SendKey(browser, 13);
// 发送Ctrl+C
KeyboardHelper.SendCombination(browser, 67, FBroSharpEventFlags.EVENTFLAG_CONTROL_DOWN);
// 输入文本
KeyboardHelper.TypeText(browser, "Hello World");
// 发送Tab键
KeyboardHelper.SendKey(browser, 9);最佳实践
- 事件配对:对于功能键,确保发送KEYDOWN和KEYUP事件配对
- 延迟控制:在事件之间添加适当延迟,模拟真实用户操作
- 焦点管理:确保目标元素有焦点后再发送键盘事件
- 字符输入:对于文本输入,使用KEYEVENT_CHAR类型
- 组合键处理:正确设置modifiers标志位
- 错误处理:添加异常捕获和资源清理
注意事项
- 前台限制:SendKeyEvent只能对前台活动窗口生效
- 字符编码:中文等Unicode字符需要逐字符发送KEYEVENT_CHAR事件
- 浏览器响应:某些操作可能需要等待浏览器响应
- 修饰键状态:组合键操作时注意修饰键的正确设置
- 性能考虑:频繁发送事件时注意性能影响
总结
SendKeyEvent方法提供了免费的键盘事件发送功能,虽然使用相对复杂,但为不需要VIP功能的用户提供了基础的键盘操作能力。通过合理封装和使用最佳实践,可以实现有效的键盘自动化操作。