方法 : マウス イベントとキーボード イベントをコードでシミュレートする
Windows フォームでは、いくつかの方法でマウス入力とキーボード入力をプログラムによってシミュレートできます。 ここでは、これらの方法の概要について説明します。
マウス入力のシミュレート
マウス イベントをシミュレートするには、シミュレートするマウス イベントを発生させる OnEventName メソッドを呼び出すのが最善の方法です。 この方法は、通常、カスタム コントロールやカスタム フォームの内部でしか利用できません。その理由は、イベントを発生させるメソッドは保護されているため、コントロールやフォームの外部からアクセスできないからです。 たとえば、次の手順は、マウスの右ボタンのクリックをコードでシミュレートする方法を示しています。
マウスの右ボタンをプログラムによってクリックするには
Button プロパティに MouseButtons.Right 値が設定されている MouseEventArgs を作成します。
この 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 を使ってコンパイルして実行する.