Partilhar via


Como: Simular o mouse e eventos de teclado no código

Os Formulários do Windows fornecem várias opções para simular entradas de mouse e teclado via programação.Este tópico fornece uma visão geral sobre essas opções.

Simulando Entrada de Mouse

A melhor maneira para simular eventos do mouse é chamar o método OnEventName que gera o evento do mouse que você deseja simular.Essa opção normalmente só é possível em controles e formulários personalizados, porque os métodos que geram eventos são protegidos e não podem ser acessados de fora do controle ou formulário.Por exemplo, os passos a seguir ilustram como simular um clique do botão direito do mouse em código.

Para clicar o botão direito do mouse via programação.

  1. Crie um MouseEventArgs cuja propriedade Button é definida como o valor MouseButtons.Right.

  2. Chame o método OnMouseClick com este MouseEventArgs como o argumento.

Para obter mais informações sobre controles personalizados, consulte Desenvolver Windows Forms Controls at Design Time.

Existem outras maneiras de simular a entrada do mouse.Por exemplo, você pode definir via programação uma propriedade do controle que representa um estado que normalmente é definido através da entrada do mouse (como a propriedade Checked do controle CheckBox) ou você pode chamar diretamente o representante que está anexado ao evento que você deseja simular.

Simulando a Entrada do Teclado

Embora você possa simular uma entrada de teclado usando as estratégias discutidas acima para a entrada do mouse, os Formulários do Windows também oferecem a classe SendKeys para enviar pressionamentos de teclas para o aplicativo ativo.

Cuidado:

Se seu aplicativo é destinado ao uso internacional com uma variedade de teclados, o uso de SendKeys.Send pode levar a resultados imprevisíveis e devem ser evitadas.

Observação:

O SendKeys classe foi atualizado para o .NET estrutura 3.0 ativar seu uso em aplicativos executados no Windows Vista. A segurança avançada do Windows Vista (conhecido como Controle de Conta de Usuário ou UAC) impede que a implementação anterior funcione conforme esperado.

O SendKeys classe é suscetível a problemas de temporização, alguns desenvolvedores tiveram como solução alternativa.A implementação atualizada é suscetível a problemas de atraso, ainda, mas é ligeiramente mais rápida e pode exigir alterações para as soluções alternativas.O SendKeys classe tenta usar a implementação anterior pela primeira vez e se isso falhar, usará a nova implementação.sistema autônomo resultado, o SendKeys classe pode ter um comportamento diferente em sistemas operacionais diferentes.Além disso, quando o SendKeys classe usa a nova implementação, o SendWait método não aguardará mensagens a serem processadas quando elas são enviadas para outro processo.

Se seu aplicativo depende de um comportamento consistente independentemente do sistema operacional, você pode forçar o SendKeys classe para usar a nova implementação, adicionando a seguinte configuração de aplicativo para o arquivo app.config.

<appSettings>

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

</appSettings>

Para forçar o SendKeys classe para usar a implementação anterior, use o valor "JournalHook" em vez disso.

Para enviar um pressionamento de tecla para o mesmo aplicativo

  • Chame o método Send ou SendWait da classe SendKeys.Os pressionamentos de teclas especificados serão recebidos pelo controle ativo do aplicativo.O exemplo de código a seguir usa Send para simular o pressionamento da tecla ENTER quando o usuário clica duas vezes na superfície do formulário.Este exemplo considera um Form com um único controle Button que possui um índice de tabulação 0.

    ' 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
    
    // 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:
        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}");
        }
    

Para enviar um pressionamento de tecla para um aplicativo diferente.

  • Ative a janela do aplicativo que receberá os pressionamentos de teclas e, em seguida, chame o método Send ou SendWait.Como não há nenhum método gerenciado para ativar outro aplicativo, você deve usar os métodos nativos do Windows para forçar o foco em outros aplicativos.O código exemplo a seguir usa invocação de plataforma para chamar os métodos FindWindow e SetForegroundWindow para ativar a janela de aplicativo da calculadora e em seguida, chama SendWait para emitir uma série de cálculos para o aplicativo da Calculadora.

    ' 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("SciCalc", "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
    
    // 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("SciCalc", "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.
        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("SciCalc", "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("=");
            }
    

Exemplo

O código exemplo a seguir é o aplicativo completo para os códigos exemplo anteriores.

Imports System
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("SciCalc", "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
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("SciCalc", "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}");
        }
    }
}
#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("SciCalc", "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());
}

Compilando o código

Este exemplo requer:

  • Referências para as montagens (assemblys) do System, System.Drawing e System.Windows.Forms.

Para obter informações sobre como criar este exemplo a partir da linha de comando para Visual Basic ou Visual C#, consulte Criando a partir da linha de comando (Visual Basic) ou Linha de comando criando com csc.exe.Você também pode construir este exemplo no Visual Studio colando o código em um novo projeto.

Consulte também

Outros recursos

Entrada do Usuário nos Formulários do Windows