Share via


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

Windows フォームでは、いくつかの方法でマウス入力とキーボード入力をプログラムによってシミュレートできます。 ここでは、これらの方法の概要について説明します。

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

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

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

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

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

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

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

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

キーボード入力は、上記のマウス入力に関する方法を使ってシミュレートできますが、Windows フォームでは、SendKeys クラスを使用してキーストロークをアクティブなアプリケーションに送ることもできます。

ヒント

ただし、アプリケーションが各種キーボードで使用できるように国際対応になっている場合、SendKeys.Send を使用すると、予期しない結果が生じる可能性があるため、このクラスの使用は避ける必要があります。

注意

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

SendKeys クラスはタイミングに関する問題の影響を受けやすく、一部の開発者はこれを回避する必要がありました。 更新された実装では、まだタイミングに関する問題の影響を受けやすい状態ですが、若干高速になるため、回避策の変更が必要な場合があります。 SendKeys クラスは、最初に以前の実装を使用し、それに失敗した場合に新しい実装を使用します。 したがって、SendKeys クラスの動作は、オペレーティング システムによって異なる場合があります。 また、SendKeys クラスが新しい実装を使用する場合は、SendWait メソッドは、メッセージが別のプロセスに対して送信されたときに、そのメッセージが処理されるまで待機しません。

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

<appSettings>

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

</appSettings>

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

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

  • SendKeys クラスの Send メソッドまたは SendWait メソッドを呼び出します。 指定したキーストロークが、アプリケーションのアクティブなコントロールによって受け取られます。 次のコード例では、Send を使用して、ユーザーがフォームの領域をダブルクリックしたときに Enter キーの押し下げをシミュレートします。 この例では、タブ インデックスが 0 (ゼロ) の単一の Button コントロールが Form に存在することを想定しています。

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

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

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

    注意

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

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

使用例

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

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("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
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}");
        }
    }
}
#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());
}

コードのコンパイル

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

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

Visual Basic または Visual C# のコマンド ラインからこの例をビルドする方法の詳細については、「コマンド ラインからのビルド (Visual Basic)」または「csc.exe を使用したコマンド ラインからのビルド」を参照してください。 Visual Studio で新しいプロジェクトにコードを貼り付けてこの例をビルドすることもできます。 詳細については 方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する および 方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する および 方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する および 方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する および 方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する.

参照

その他の技術情報

Windows フォームでのユーザー入力