Sdílet prostřednictvím


Postupy: Simulace událostí myši a klávesnice v kódu

Windows Forms nabízí několik možností pro programovou simulaci vstupu myši a klávesnice. Toto téma obsahuje přehled těchto možností.

Simulace vstupu myši

Nejlepší způsob, jak simulovat události myši, je volat metodu OnEventName, která vyvolá událost myši, kterou chcete simulovat. Tato možnost je obvykle možná pouze v rámci vlastních ovládacích prvků a formulářů, protože metody, které vyvolávají události jsou chráněné a nelze k němu přistupovat mimo ovládací prvek nebo formulář. Například následující kroky ukazují, jak simulovat kliknutí pravého tlačítka myši v kódu.

Programové kliknutí na pravé tlačítko myši

  1. Vytvořte MouseEventArgs, jejíž vlastnost Button je nastavena na hodnotu MouseButtons.Right.

  2. Volejte metodu OnMouseClick s tímto MouseEventArgs jako argumentem.

Další informace o vlastních ovládacích prvcích naleznete v tématu Vývoj ovládacích prvků Windows Forms v době návrhu.

Existují i další způsoby simulace vstupu myši. Můžete například programově nastavit vlastnost ovládacího prvku, který představuje stav, který je obvykle nastaven prostřednictvím vstupu myši (například Checked vlastnost ovládacího prvku CheckBox) nebo můžete přímo volat delegáta, který je připojen k události, kterou chcete simulovat.

Simulace vstupu klávesnice

I když můžete simulovat vstup pomocí klávesnice pomocí výše uvedených strategií pro vstup myši, Windows Forms také poskytuje SendKeys třídu pro odesílání klávesových úhorů do aktivní aplikace.

Opatrnost

Pokud je vaše aplikace určená pro mezinárodní použití s celou řadou klávesnic, může použití SendKeys.Send přinést nepředvídatelné výsledky a mělo by se jim vyhnout.

Poznámka

Třída SendKeys byla aktualizována pro rozhraní .NET Framework 3.0 tak, aby umožňovala její použití v aplikacích, které běží v systému Windows Vista. Vylepšené zabezpečení systému Windows Vista (označované jako Řízení uživatelských účtů nebo řízení uživatelských účtů) brání předchozí implementaci v očekávaném fungování.

Třída SendKeys je náchylná k problémům s časováním, které museli někteří vývojáři obejít. Aktualizovaná implementace je stále náchylná k problémům s časováním, ale je o něco rychlejší a může vyžadovat změny alternativních řešení. Třída SendKeys se nejprve pokusí použít předchozí implementaci a pokud selže, použije novou implementaci. V důsledku toho se třída SendKeys může v různých operačních systémech chovat odlišně. Navíc, když SendKeys třída používá novou implementaci, SendWait metoda nebude čekat na zpracování zpráv při jejich odeslání do jiného procesu.

Pokud vaše aplikace spoléhá na konzistentní chování bez ohledu na operační systém, můžete vynutit, aby třída SendKeys používala novou implementaci přidáním následujícího nastavení aplikace do app.config souboru.

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

Chcete-li vynutit použití předchozí implementace třídy SendKeys, použijte namísto toho hodnotu "JournalHook".

Odeslání stisknutí klávesy do stejné aplikace

  1. Volejte metodu Send nebo SendWait třídy SendKeys. Zadané stisknutí kláves bude přijato aktivní kontrolou aplikace. Následující příklad kódu používá Send k simulaci stisknutí klávesy ENTER, když uživatel dvakrát klikne na povrch formuláře. Tento příklad předpokládá Form s jedním ovládacím prvkem Button, který má index tabulátoru 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
    

Odeslání stisknutí klávesy do jiné aplikace

  1. Aktivujte okno aplikace, které obdrží stisknutí kláves, a potom zavolejte Send nebo SendWait metodu. Vzhledem k tomu, že neexistuje žádná spravovaná metoda pro aktivaci jiné aplikace, musíte použít nativní metody Systému Windows k vynucení zaměření na jiné aplikace. Následující příklad kódu používá volání platformy k zavolání metod FindWindow a SetForegroundWindow pro aktivaci okna aplikace Kalkulačka a poté zavolá SendWait k provedení řady výpočtů v aplikaci Kalkulačka.

    Poznámka

    Správné parametry volání FindWindow, které vyhledá aplikaci Kalkulačka, se liší v závislosti na vaší verzi Systému Windows. Následující kód najde aplikaci Calculator ve Windows 7. V systému Windows Vista změňte první parametr na SciCalc. K určení správných parametrů můžete použít nástroj Spy++, který je součástí sady Visual Studio.

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

Příklad

Následující příklad kódu je kompletní aplikace pro předchozí příklady kódu.

#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

Kompilace kódu

Tento příklad vyžaduje:

  • Odkazy na sestavení System, System.Drawing a System.Windows.Forms.

Viz také