Практическое руководство. Имитация событий мыши и клавиатуры в коде
В Windows Forms предоставляется несколько возможностей для программной имитации ввода данных с помощью мыши и клавиатуры. В этом разделе приведен обзор этих возможностей.
Имитация ввода с помощью мыши
Наилучшим способом имитации событий мыши является вызов метода On
EventName , в результате чего происходит событие мыши, которое требуется имитировать. Этот вариант обычно возможен только в пределах пользовательских элементов управления и форм, так как методы, которые вызывают события, защищены и недоступны вне элемента управления или формы. Например, ниже показано, как имитировать нажатие правой кнопки мыши в коде.
Чтобы нажать правую кнопку мыши программными средствами, выполните указанные ниже действия.
Создайте объект MouseEventArgs и установите для его свойства Button значение MouseButtons.Right .
Вызовите метод OnMouseClick с этим объектом MouseEventArgs в качестве аргумента.
Дополнительные сведения о пользовательских элементах управления см. в разделе Создание элементов управления Windows Forms во время разработки.
Существуют другие способы имитировать ввод с помощью мыши. Например, можно программно установить свойство элемента управления, которое представляет состояние, обычно устанавливаемое с помощью ввода мыши (например, свойство Checked элемента управления CheckBox ), или напрямую вызвать делегат, связанный с событием, которое нужно имитировать.
Имитация ввода с клавиатуры
Хотя ввод данных с клавиатуры можно имитировать с помощью подходов, описанных выше для ввода с помощью мыши, Windows Forms также предоставляет класс SendKeys для отправки нажатий клавиш в активное приложение.
Caution
Если приложение предназначено для международного использования с различными клавиатурами, применение метода SendKeys.Send может иметь непредсказуемые результаты и его следует избегать.
Note
Класс SendKeys был обновлен в .NET Framework 3.0, что позволило использовать его в приложениях, работающих в Windows Vista. Усиленная система безопасности Windows Vista (известная как контроль учетных записей или UAC) не позволяет предыдущей реализации работать должным образом.
Класс SendKeys подвержен проблемам со временем, которые пришлось решать некоторым разработчикам. Обновленная реализация по-прежнему подвержена этим проблемам, но она работает немного быстрее, поэтому существующие решения может потребоваться переработать. Класс SendKeys сначала пытается использовать предыдущую реализацию, и если это не удается, использует новую реализацию. В результате класс SendKeys может работать по-разному в разных операционных системах. Кроме того, при использовании новой реализации класса SendKeys метод SendWait не будет дожидаться обработки сообщений, если они отправляются другому процессу.
Если необходимо обеспечить согласованное поведение приложения независимо от операционной системы, можно заставить класс SendKeys использовать новую реализацию, добавив указанный ниже параметр приложения в файл app.config.
<appSettings>
<add key="SendKeys" value="SendInput"/>
</appSettings>
Для принудительного использования классом SendKeys предыдущей реализации задайте значение "JournalHook"
.
Отправка нажатия клавиши в то же приложение
Вызовите метод Send или SendWait класса SendKeys . Указанные нажатия клавиш будут получены активным элементом управления приложения. В примере кода ниже метод Send используется для имитации нажатия клавиши ВВОД, когда пользователь дважды щелкает по поверхности формы. В этом примере используется форма Form с одним элементом управления Button , имеющим индекс перехода по клавише TAB, равный 0.
// Send a key to the button when the user double-clicks anywhere // on the form. private void Form1_DoubleClick(object sender, EventArgs e) { // Send the enter key to the button, which raises the click // event for the button. This works because the tab stop of // the button is 0. SendKeys.Send("{ENTER}"); }
Отправка нажатия клавиши в другое приложение
Активируйте окно приложения, которое будет получать нажатия клавиш, а затем вызовите метод Send или SendWait . Из-за отсутствия управляемого метода активации другого приложения необходимо использовать собственные методы Windows для принудительной установки фокуса на другие приложения. В примере кода ниже с помощью вызова неуправляемого кода вызываются методы
FindWindow
иSetForegroundWindow
для активации окна приложения "Калькулятор", а затем вызывается метод SendWait для проведения ряда вычислений в этом приложении.Note
Параметры вызова
FindWindow
для определения положения Калькулятора зависят от версии Windows. Приведенный ниже код находит Калькулятор в Windows 7. В Windows Vistaизмените первый параметр на SciCalc. Для определения нужных параметров можно использовать средство Spy++, входящее в состав Visual Studio.// Get a handle to an application window. [DllImport("USER32.DLL", CharSet = CharSet.Unicode)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); // Activate an application window. [DllImport("USER32.DLL")] public static extern bool SetForegroundWindow(IntPtr hWnd); // Send a series of key presses to the Calculator application. private void button1_Click(object sender, EventArgs e) { // Get a handle to the Calculator application. The window class // and window name were obtained using the Spy++ tool. IntPtr calculatorHandle = FindWindow("CalcFrame","Calculator"); // Verify that Calculator is a running process. if (calculatorHandle == IntPtr.Zero) { MessageBox.Show("Calculator is not running."); return; } // Make Calculator the foreground application and send it // a set of calculations. SetForegroundWindow(calculatorHandle); SendKeys.SendWait("111"); SendKeys.SendWait("*"); SendKeys.SendWait("11"); SendKeys.SendWait("="); }
Пример
В примере ниже полностью представлено приложение для предыдущих примеров кода.
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
namespace SimulateKeyPress
{
class Form1 : Form
{
private Button button1 = new Button();
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
{
button1.Location = new Point(10, 10);
button1.TabIndex = 0;
button1.Text = "Click to automate Calculator";
button1.AutoSize = true;
button1.Click += new EventHandler(button1_Click);
this.DoubleClick += new EventHandler(Form1_DoubleClick);
this.Controls.Add(button1);
}
// Get a handle to an application window.
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName,
string lpWindowName);
// Activate an application window.
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
// Send a series of key presses to the Calculator application.
private void button1_Click(object sender, EventArgs e)
{
// Get a handle to the Calculator application. The window class
// and window name were obtained using the Spy++ tool.
IntPtr calculatorHandle = FindWindow("CalcFrame","Calculator");
// Verify that Calculator is a running process.
if (calculatorHandle == IntPtr.Zero)
{
MessageBox.Show("Calculator is not running.");
return;
}
// Make Calculator the foreground application and send it
// a set of calculations.
SetForegroundWindow(calculatorHandle);
SendKeys.SendWait("111");
SendKeys.SendWait("*");
SendKeys.SendWait("11");
SendKeys.SendWait("=");
}
// Send a key to the button when the user double-clicks anywhere
// on the form.
private void Form1_DoubleClick(object sender, EventArgs e)
{
// Send the enter key to the button, which raises the click
// event for the button. This works because the tab stop of
// the button is 0.
SendKeys.Send("{ENTER}");
}
}
}
Компиляция кода
Для этого примера требуются:
- ссылки на сборки System, System.Drawing и System.Windows.Forms.
Сведения о выполнении сборки этого примера из командной строки для Visual Basic или Visual C#, см. в разделе построение из командной строки или командной строки создания с помощью csc.exe. Можно также сборке этого примера в Visual Studio путем вставки кода в новый проект.