方法: マウス イベントとキーボード イベントをコードでシミュレートする

Windows フォームは、プログラムでマウスおよびキーボード入力をシミュレートするためのいくつかのオプションを提供します。 ここでは、これらのオプションの概要について説明します。

マウス入力のシミュレート

マウス イベントをシミュレートする最善の方法は、 OnEventName メソッドを呼び出して、シミュレートの対象となるマウス イベントを発生させる方法です。 このオプションは、イベントを発生させるメソッドが保護され、コントロールまたはフォームの外部にアクセスできないため、通常はカスタム コントロールおよびフォーム内でのみ可能です。 たとえば、次の手順は、コードでマウスの右ボタンのクリックをシミュレートする方法を示しています。

プログラムでマウスの右ボタンをクリックするには

  1. MouseEventArgs プロパティが Button 値に設定された MouseButtons.Right を作成します。

  2. この OnMouseClick を持つ MouseEventArgs メソッドを引数として呼び出します。

カスタム コントロールの詳細については、「デザイン時の Windows フォーム コントロールの開発」を参照してください。

マウス入力をシミュレートする方法はほかにもあります。 たとえば、マウス入力によって標準的に設定する状態を表すコントロールのプロパティをプログラムで設定したり ( Checked コントロールの CheckBox プロパティなど)、シミュレートの対象イベントにアタッチされているデリゲートを直接呼び出したりできます。

キーボード入力のシミュレート

前述のマウス入力に関する戦略を使用することで、キーボード入力をシミュレートできますが、Windows フォームはアクティブなアプリケーションにキー入力を送信するための SendKeys クラスも提供します。

注意事項

アプリケーションが国際対応し、さまざまなキーボードの使用を想定している場合は、 SendKeys.Send の使用により予期しない結果になる可能性があるため、回避する必要があります。

注意

.NET Framework 3.0 の SendKeys クラスが更新され、Windows Vista で実行されるアプリケーションで使用できるようになりました。 Windows Vista の強化されたセキュリティ、(ユーザー アカウント制御または UAC と呼ばれます) により、前の実装は想定どおり機能できません。

SendKeys クラスはタイミングの問題が発生する可能性があり、一部の開発者は回避策を取る必要がありました。 更新された実装は、引き続きタイミングの問題が発生する可能性がありますが、速度が少し向上し、回避策の変更が必要となる可能性があります。 SendKeys クラスは、最初に前の実装を使用しようとし、失敗した場合に、新しい実装を使用します。 その結果、 SendKeys クラスが別のオペレーティング システムと異なる動作を取る可能性があります。 さらに、 SendKeys クラスは、新しい実装を使用した場合、 SendWait メソッドが別のプロセスに送信されたときにメッセージの処理を待機しません。

アプリケーションが、オペレーティング システムに関係なく一貫した動作に依存する場合、app.config ファイルに次のアプリケーション設定を追加することで、 SendKeys クラスが新しい実装を使用するよう強制することができます。

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

SendKeys クラスが前の実装を使用するよう強制するには、代わりに値 "JournalHook" を使用します。

同じアプリケーションにキーストロークを送信するには

  1. Send クラスの SendWait メソッドまたは SendKeys メソッドを呼び出します。 指定されたキーストロークは、アプリケーションのアクティブなコントロールによって受信されます。 次のコード例では、 Send を使用して、ユーザーがフォームのサーフェイスをダブルクリックしたときに、ENTER キーを押す操作をシミュレートします。 この例では、0 のタブ インデックスを持つ単一の Form コントロールがある Button を想定しています。

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

別のアプリケーションにキーストロークを送信するには

  1. キー入力を受信するアプリケーション ウィンドウをアクティブ化し、 Send メソッドまたは SendWait メソッドを呼び出します。 別のアプリケーションをアクティブ化するマネージド メソッドがないため、ネイティブ Windows メソッドを使用して他のアプリケーションにフォーカスを設定する必要があります。 次のコード例は、プラットフォーム呼び出しを使用して FindWindow メソッドと SetForegroundWindow メソッドを呼び出し、電卓アプリケーションのウィンドウをアクティブ化してから、 SendWait を呼び出して電卓アプリケーションに一連の計算を発行します。

    注意

    電卓アプリケーションを特定する FindWindow 呼び出しの適切なパラメーターは、Windows のバージョンに応じて異なります。 次のコードでは、Windows 7 の電卓アプリケーションを検索します。 Windows Vista では、最初のパラメーターを「SciCalc」に変更します。 Visual Studio に付属の Spy++ ツールを使用して、適切なパラメーターを特定します。

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

次のコード例は、前のコード例の完全なアプリケーションです。

#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

コードのコンパイル

この例で必要な要素は次のとおりです。

  • System、System.Drawing、および System.Windows.Forms の各アセンブリへの参照。

関連項目