方法: マウス イベントとキーボード イベントをコードでシミュレートする
Windows フォームは、プログラムでマウスおよびキーボード入力をシミュレートするためのいくつかのオプションを提供します。 ここでは、これらのオプションの概要について説明します。
マウス入力のシミュレート
マウス イベントをシミュレートする最善の方法は、 On
EventName メソッドを呼び出して、シミュレートの対象となるマウス イベントを発生させる方法です。 このオプションは、イベントを発生させるメソッドが保護され、コントロールまたはフォームの外部にアクセスできないため、通常はカスタム コントロールおよびフォーム内でのみ可能です。 たとえば、次の手順は、コードでマウスの右ボタンのクリックをシミュレートする方法を示しています。
プログラムでマウスの右ボタンをクリックするには
MouseEventArgs プロパティが Button 値に設定された MouseButtons.Right を作成します。
この 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"
を使用します。
同じアプリケーションにキーストロークを送信するには
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
別のアプリケーションにキーストロークを送信するには
キー入力を受信するアプリケーション ウィンドウをアクティブ化し、 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 の各アセンブリへの参照。
関連項目
.NET Desktop feedback