【发布时间】:2018-08-09 21:55:37
【问题描述】:
我正在尝试通过使用 keybd_event 发送键来模拟键盘,如下所述。
最初从我的窗口加载事件中,我创建了一个后台工作程序并启动它。如果模拟参数处于活动状态,则此后台工作人员会订阅表单按键事件。
我已确保此参数处于活动状态,因此我正确订阅了 winform keypress 事件。
我也有一个按钮来启动键盘的模拟。当单击此按钮“btnSimulateKeyboard_Click”时,我会发送一个字符串,然后将其转换为字节数组,最后在循环中使用 keybd_event 发送每个字节。
我的问题是表单按键事件永远不会被触发。为什么?不是模拟发送密钥的正确方式吗?
namespace My.Apps.WinForms.Test
{
public partial class MyForm: Form
{
#region Constructor
public MyForm()
{
InitializeComponent();
}
#endregion
private void MyForm_Load(object sender, EventArgs e)
{
// Some stuff
_worker = new BackgroundWorker();
_worker.DoWork += new DoWorkEventHandler(_worker _DoWork);
_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker _RunWorkerCompleted);
_worker.ProgressChanged += new ProgressChangedEventHandler(_worker t_ProgressChanged);
_worker.WorkerReportsProgress = true;
_worker.RunWorkerAsync();
}
private void _worker_DoWork(object sender, DoWorkEventArgs e)
{
// Some stuff
// Load parameters
if (simulateKeyboard)
{
this.InitKb();
}
// Some stuff
}
private void InitKb()
{
this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.MyForm_KeyPress);
}
private void MyForm_KeyPress(object sender, KeyPressEventArgs e)
{
// Check key pressed
}
private void btnSimulateKeyboard_Click(object sender, EventArgs e)
{
SimulateKeyboardTest.SendString("abcdefg");
}
}
}
键盘模拟类:
namespace My.Apps.WinForms.Test
{
public static class SimulateKeyboardTest
{
#region DLLs Import
[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
#endregion
#region Constants
public const int KEYEVENTF_EXTENDEDKEY = 0x0001; // Key down flag
public const int KEYEVENTF_KEYUP = 0x0002; // Key up flag
#endregion
#region Public Static Methods
/// <summary>
/// Sends a string.
/// </summary>
/// <param name="strChars">String to send.</param>
public static void SendString(string strChars)
{
byte[] bytChars = Encoding.ASCII.GetBytes(strChars);
for (int i = 0; i < bytChars.Length; i++)
{
KeyPress(bytChars[i]);
KeyUp(bytChars[i]);
}
}
/// <summary>
/// Simulate a key press
/// </summary>
public static void KeyPress(byte keyCode)
{
keybd_event(keyCode, 0, KEYEVENTF_EXTENDEDKEY, 0);
}
/// <summary>
/// Simulate a key release
/// </summary>
public static void KeyUp(byte keyCode)
{
keybd_event(keyCode, 0, KEYEVENTF_KEYUP, 0);
}
#endregion
}
}
【问题讨论】:
-
你不应该在
KeyPress之前打电话给KeyDown吗? AFAIK 正常顺序是KeyDown=>KeyPress=>KeyUp -
发送击键以控制焦点,您刚刚单击的按钮,没有用。一个按钮只响应一个空间,而不是你想要发送的空间,因为它永远不会结束。当您有一个可以获得焦点的控件时,表单永远不会获得 KeyPress 事件。这段代码没有用,也无法猜测它的用途。
-
@HansPassant 那么如何在单击按钮后以编程方式将键发送到 winform 表单按键事件?
-
当您可以直接调用 MyForm_KeyPress() 方法时,您不需要事件。直接调用事件处理程序方法并没有错,尽管您通常倾向于将通用代码移动到另一个方法中。