Delen via


Hoe te: Muis- en toetsenbordaanslagen simuleren in de code

Windows Forms biedt verschillende opties voor het programmatisch simuleren van muis- en toetsenbordinvoer. Dit onderwerp bevat een overzicht van deze opties.

Muisinvoer simuleren

De beste manier om muisgebeurtenissen te simuleren, is door de OnEventName methode aan te roepen waarmee de muisgebeurtenis wordt gegenereerd die u wilt simuleren. Deze optie is meestal alleen mogelijk binnen aangepaste besturingselementen en formulieren, omdat de methoden voor het genereren van gebeurtenissen zijn beveiligd en niet toegankelijk zijn buiten het besturingselement of formulier. De volgende stappen laten bijvoorbeeld zien hoe u het klikken op de rechtermuisknop in code simuleert.

Om programmatisch met de rechtermuisknop te klikken

  1. Maak een MouseEventArgs waarvan de eigenschap Button is ingesteld op de MouseButtons.Right-waarde.

  2. Roep de methode OnMouseClick aan met deze MouseEventArgs als het argument.

Zie voor meer informatie over aangepaste besturingselementen Ontwikkelen van Windows Forms-besturingselementen tijdens ontwerptijd.

Er zijn andere manieren om muisinvoer te simuleren. U kunt bijvoorbeeld programmatisch een besturingseigenschap instellen die een status vertegenwoordigt die doorgaans wordt ingesteld via muisinvoer (zoals de eigenschap Checked van het besturingselement CheckBox), of u kunt de gedelegeerde die is gekoppeld aan de gebeurtenis die u wilt simuleren, rechtstreeks aanroepen.

Toetsenbordinvoer simuleren

Hoewel u toetsenbordinvoer kunt simuleren met behulp van de hierboven besproken strategieën voor muisinvoer, biedt Windows Forms ook de SendKeys-klasse voor het verzenden van toetsaanslagen naar de actieve toepassing.

Voorzichtigheid

Als uw toepassing is bedoeld voor internationaal gebruik met verschillende toetsenborden, kan het gebruik van SendKeys.Send onvoorspelbare resultaten opleveren en moet worden vermeden.

Notitie

De SendKeys-klasse is bijgewerkt voor .NET Framework 3.0 om het gebruik ervan in te schakelen in toepassingen die worden uitgevoerd op Windows Vista. De verbeterde beveiliging van Windows Vista (ook wel gebruikersaccountbeheer of UAC genoemd) voorkomt dat de vorige implementatie werkt zoals verwacht.

De SendKeys-klasse is vatbaar voor timingproblemen, die sommige ontwikkelaars hebben moeten omzeilen. De bijgewerkte implementatie is nog steeds vatbaar voor timingproblemen, maar is iets sneller en vereist mogelijk wijzigingen in de tijdelijke oplossingen. De SendKeys klasse probeert eerst de vorige implementatie te gebruiken en als dat mislukt, wordt de nieuwe implementatie gebruikt. Als gevolg hiervan kan de SendKeys-klasse zich anders gedragen op verschillende besturingssystemen. Wanneer de SendKeys-klasse bovendien gebruikmaakt van de nieuwe implementatie, wacht de SendWait methode niet totdat berichten worden verwerkt wanneer ze naar een ander proces worden verzonden.

Als uw toepassing afhankelijk is van consistent gedrag, ongeacht het besturingssysteem, kunt u afdwingen dat de SendKeys klasse de nieuwe implementatie gebruikt door de volgende toepassingsinstelling toe te voegen aan uw app.config-bestand.

<appSettings>
 <add key="SendKeys" value="SendInput"/>
</appSettings>

Als u wilt afdwingen dat de SendKeys-klasse de vorige implementatie gebruikt, gebruikt u in plaats daarvan de waarde "JournalHook".

Een toetsaanslag verzenden naar dezelfde toepassing

  1. Roep de methode Send of SendWait van de klasse SendKeys aan. De opgegeven toetsaanslagen worden ontvangen door het actieve beheer van de toepassing. In het volgende codevoorbeeld wordt Send gebruikt om te simuleren dat op de Enter-toets wordt gedrukt wanneer de gebruiker dubbelklikt op het oppervlak van het formulier. In dit voorbeeld wordt ervan uitgegaan dat een Form met één Button-bedieningselement met een tabbladindex van 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 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
    

Een toetsaanslag verzenden naar een andere toepassing

  1. Activeer het toepassingsvenster dat de toetsaanslagen ontvangt en roep vervolgens de methode Send of SendWait aan. Omdat er geen beheerde methode is om een andere toepassing te activeren, moet u systeemeigen Windows-methoden gebruiken om de focus op andere toepassingen af te dwingen. In het volgende codevoorbeeld wordt het aanroepen van het platform gebruikt om de FindWindow- en SetForegroundWindow-methoden aan te roepen om het toepassingsvenster Calculator te activeren. Vervolgens wordt SendWait aangeroepen om een reeks berekeningen uit te geven aan de rekenmachinetoepassing.

    Notitie

    De juiste parameters van de FindWindow-aanroep waarmee de rekenmachinetoepassing wordt gevonden, variëren op basis van uw versie van Windows. Met de volgende code wordt de toepassing Calculator in Windows 7 gevonden. Wijzig in Windows Vista de eerste parameter in SciCalc. U kunt het spy++-hulpprogramma, dat is opgenomen in Visual Studio, gebruiken om de juiste parameters te bepalen.

        // 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
    

Voorbeeld

Het volgende codevoorbeeld is de volledige toepassing voor de vorige codevoorbeelden.

#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

De code compileren

Voor dit voorbeeld is het volgende vereist:

  • Verwijzingen naar de assemblies System, System.Drawing en System.Windows.Forms.

Zie ook