Vorgehensweise: Simulieren von Maus- und Tastaturereignissen in Code
Windows Forms stellt mehrere Optionen zur programmgesteuerten Simulation von Maus- und Tastatureingaben bereit. Dieses Thema enthält eine Übersicht über diese Optionen.
Simulieren von Mauseingaben
Die beste Möglichkeit, Mauseingaben zu simulieren, ist ein Aufruf der On
Ereignisname -Methode, die das Mausereignis auslöst, die Sie simulieren möchten. Diese Option wird normalerweise nur in benutzerdefinierten Steuerelementen und Formularen unterstützt, weil die Methoden, die Ereignisse auslösen, geschützt sind und außerhalb des Steuerelements oder Formulars nicht aufgerufen werden können. Die folgenden Schritte veranschaulichen beispielsweise, wie ein Klicken mit der rechten Maustaste in Code simuliert wird.
So klicken Sie programmgesteuert mit der rechten Maustaste
Erstellen Sie eine MouseEventArgs -Instanz, deren Button -Eigenschaft auf den Wert MouseButtons.Right festgelegt wird.
Rufen Sie die OnMouseClick -Methode mit dieser MouseEventArgs -Instanz als Argument auf.
Weitere Informationen zu benutzerdefinierten Steuerelementen finden Sie unter Entwickeln von Windows Forms-Steuerelementen zur Entwurfszeit.
Es gibt weitere Möglichkeiten, Mauseingaben zu simulieren. Beispielsweise können Sie programmgesteuert eine Steuerelementeigenschaft festlegen, die einen Zustand darstellt, der normalerweise per Mauseingabe festgelegt wird (etwa die Checked -Eigenschaft des CheckBox -Steuerelements). Sie können aber auch direkt den Delegaten aufrufen, der mit dem Ereignis verknüpft ist, das Sie simulieren möchten.
Simulieren von Tastatureingaben
Tastatureingaben können mit denselben Strategien simuliert werden, die hier für Mauseingaben erläutert sind. Zusätzlich stellt Windows Forms aber die SendKeys -Klasse bereit, um Tastatureingaben an die aktive Anwendung senden zu können.
Achtung
Wenn Ihre Anwendung für internationale Verwendung mit unterschiedlichen Tastaturen vorgesehen ist, kann ein Verwenden von SendKeys.Send zu unvorhersehbaren Ergebnissen führen und sollte vermieden werden.
Hinweis
Die SendKeys -Klasse wurde für .NET Framework 3.0 aktualisiert, damit sie in Anwendungen verwendet werden kann, die unter Windows Vista ausgeführt werden. Die verbesserte Sicherheit von Windows Vista (Stichwort Benutzerkontensteuerung) verhindert, dass die vorherige Implementierung ordnungsgemäß funktioniert.
Die SendKeys -Klasse ist anfällig für Probleme hinsichtlich der zeitlichen Steuerung, sodass einige Entwickler gezwungen waren, Umgehungslösungen zu finden. Die aktualisierte Implementierung ist immer noch anfällig für Probleme hinsichtlich der zeitlichen Steuerung, ist jedoch etwas schneller und erfordert möglicherweise Änderungen an den Umgehungslösungen. Die SendKeys -Klasse versucht zunächst, die vorherige Implementierung zu verwenden. Schlägt dies fehl, wird die neue Implementierung verwendet. Infolgedessen verhält sich die SendKeys -Klasse unter verschiedenen Betriebssystemen möglicherweise unterschiedlich. Verwendet die SendKeys -Klasse die neue Implementierung, wartet die SendWait -Methode nicht auf zu verarbeitende Nachrichten, wenn diese an einen anderen Prozess gesendet werden.
Ist für Ihre Anwendung ein einheitliches, vom Betriebssystem unabhängiges Verhalten erforderlich, können Sie für die SendKeys -Klasse das Verwenden der neuen Implementierung erzwingen, indem Sie die folgende Anwendungseinstellung in Ihre "app.config"-Datei einfügen.
<appSettings>
<add key="SendKeys" value="SendInput"/>
</appSettings>
Soll die SendKeys -Klasse gezwungen werden, die vorherige Implementierung zu verwenden, geben Sie stattdessen den Wert "JournalHook"
an.
So senden Sie eine Tastatureingabe an dieselbe Anwendung
Rufen Sie die Send - oder die SendWait -Methode der SendKeys -Klasse auf. Die angegebenen Tastatureingaben werden vom aktiven Steuerelement der Anwendung empfangen. Im folgenden Codebeispiel wird Send verwendet, um ein Drücken der EINGABETASTE zu simulieren, wenn der Benutzer auf die Oberfläche des Formulars doppelklickt. Für dieses Beispiel wird ein Form -Objekt mit einem einzelnen Button -Steuerelement angenommen, dessen Aktivierreihenfolge (TabIndex) gleich 0 ist.
// 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 triggers the click // event for the button. This works because the tab stop of // the button is 0. SendKeys::Send("{ENTER}"); }
// 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 a key to the button when the user double-clicks anywhere ' on the form. Private Sub Form1_DoubleClick(ByVal sender As Object, _ ByVal e As EventArgs) Handles Me.DoubleClick ' 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}") End Sub
So senden Sie eine Tastatureingabe an eine andere Anwendung
Aktivieren Sie das Anwendungsfenster, das die Tastatureingaben empfängt, und rufen Sie dann die Send - oder die SendWait -Methode auf. Da keine verwaltete Methode zum Aktivieren einer anderen Anwendung vorhanden ist, müssen Sie systemeigene Windows-Methoden verwenden, um den Fokus auf andere Anwendungen zu erzwingen. Im folgenden Codebeispiel wird ein Plattformaufruf dazu verwendet, die Methoden
FindWindow
undSetForegroundWindow
aufzurufen, um das Anwendungsfenster Rechner zu aktivieren, und dann wird SendWait aufgerufen, um einige Berechnungselemente an Rechner zu senden.Hinweis
Die richtigen Parameter des
FindWindow
-Aufrufs, der nach der Anwendung Rechner sucht, können je nach Windows-Version unterschiedlich sein. Im folgenden Code wird die Anwendung Rechner unter Windows 7 gesucht. Ändern Sie unter Windows Vista den ersten Parameter in "SciCalc". Sie können das zu Visual Studio gehörende Tool Spy++ verwenden, um die richtigen Parameter zu ermitteln.// Get a handle to an application window. public: [DllImport("USER32.DLL", CharSet = CharSet::Unicode)] static IntPtr FindWindow(String^ lpClassName, String^ lpWindowName); public: // Activate an application window. [DllImport("USER32.DLL")] static 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("="); }
// 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("="); }
' Get a handle to an application window. Declare Auto Function FindWindow Lib "USER32.DLL" ( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As IntPtr ' Activate an application window. Declare Auto Function SetForegroundWindow Lib "USER32.DLL" _ (ByVal hWnd As IntPtr) As Boolean ' Send a series of key presses to the Calculator application. Private Sub button1_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles button1.Click ' Get a handle to the Calculator application. The window class ' and window name were obtained using the Spy++ tool. Dim calculatorHandle As IntPtr = FindWindow("CalcFrame", "Calculator") ' Verify that Calculator is a running process. If calculatorHandle = IntPtr.Zero Then MsgBox("Calculator is not running.") Return End If ' Make Calculator the foreground application and send it ' a set of calculations. SetForegroundWindow(calculatorHandle) SendKeys.SendWait("111") SendKeys.SendWait("*") SendKeys.SendWait("11") SendKeys.SendWait("=") End Sub
Beispiel
Das folgende Codebeispiel ist die vollständige Anwendung für die vorherigen Codebeispiele.
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <System.dll>
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Drawing;
using namespace System::Windows::Forms;
namespace SimulateKeyPress
{
public ref class Form1 : public Form
{
public:
Form1()
{
Button^ button1 = gcnew Button();
button1->Location = Point(10, 10);
button1->TabIndex = 0;
button1->Text = "Click to automate Calculator";
button1->AutoSize = true;
button1->Click += gcnew EventHandler(this, &Form1::button1_Click);
this->DoubleClick += gcnew EventHandler(this,
&Form1::Form1_DoubleClick);
this->Controls->Add(button1);
}
// Get a handle to an application window.
public:
[DllImport("USER32.DLL", CharSet = CharSet::Unicode)]
static IntPtr FindWindow(String^ lpClassName, String^ lpWindowName);
public:
// Activate an application window.
[DllImport("USER32.DLL")]
static 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 triggers the click
// event for the button. This works because the tab stop of
// the button is 0.
SendKeys::Send("{ENTER}");
}
};
}
[STAThread]
int main()
{
Application::EnableVisualStyles();
Application::Run(gcnew SimulateKeyPress::Form1());
}
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}");
}
}
}
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Windows.Forms
Namespace SimulateKeyPress
Class Form1
Inherits Form
Private WithEvents button1 As New Button()
<STAThread()> _
Public Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
Public Sub New()
button1.Location = New Point(10, 10)
button1.TabIndex = 0
button1.Text = "Click to automate Calculator"
button1.AutoSize = True
Me.Controls.Add(button1)
End Sub
' Get a handle to an application window.
Declare Auto Function FindWindow Lib "USER32.DLL" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
' Activate an application window.
Declare Auto Function SetForegroundWindow Lib "USER32.DLL" _
(ByVal hWnd As IntPtr) As Boolean
' Send a series of key presses to the Calculator application.
Private Sub button1_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles button1.Click
' Get a handle to the Calculator application. The window class
' and window name were obtained using the Spy++ tool.
Dim calculatorHandle As IntPtr = FindWindow("CalcFrame", "Calculator")
' Verify that Calculator is a running process.
If calculatorHandle = IntPtr.Zero Then
MsgBox("Calculator is not running.")
Return
End If
' Make Calculator the foreground application and send it
' a set of calculations.
SetForegroundWindow(calculatorHandle)
SendKeys.SendWait("111")
SendKeys.SendWait("*")
SendKeys.SendWait("11")
SendKeys.SendWait("=")
End Sub
' Send a key to the button when the user double-clicks anywhere
' on the form.
Private Sub Form1_DoubleClick(ByVal sender As Object, _
ByVal e As EventArgs) Handles Me.DoubleClick
' 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}")
End Sub
End Class
End Namespace
Kompilieren des Codes
Für dieses Beispiel benötigen Sie Folgendes:
- Verweise auf die Assemblys "System", "System.Drawing" und "System.Windows.Forms".
Siehe auch
.NET Desktop feedback