はじめに
現在、Friendlyと呼ばれるGUIのテスト自動化をするためのコンポーネントが存在します。
一体どうすれば他アプリケーションをどうやったら操作できるのか疑問に思い、学習しましたので記事として残します。
今回の記事で試したこと
以下の記事を参考にすると、外部アプリケーションを操作できます。
今回はこのサンプルを少し変更して、C#でメモ帳に文字列を入力します。
https://tech.sanwasystem.com/entry/2015/11/25/171004
メモ帳を操作するための事前準備
- アプリケーション名を調べます。メモ帳のアプリケーション名は「notepad」です。
- 対象のアプリのウインドウ構造を調べます。実際に上記のURLのプログラムを動かして調べたところ、編集領域のクラス名は「Edit」コントロールのようでした。
- どんなメッセージ、パラメータを送信すればテキスト入力できるかを調査します。参考URLを読み、以下のことが分かりました。
- 「WM_CHAR(0x0102)」というメッセージを送るとテキスト入力できる。
- wParamはキーの文字コード(UTF-16)を表す
- lParamは以下を表す
- 0-15 bit:メッセージの繰り返し回数
- 16-23 bit:スキャンコード、OEM依存
- 24 bit:拡張キー
- 25-28 bit:予約済み
- 29 bit:Altキーが押されていると1, それ以外の場合0
- 30 bit:以前のキーの状態、キーが押されていれば1、上げられていれば0
- 31 bit:遷移状態、キーが離されていれば1、押されていれば0
実際のプログラム
以下に参考にした記事のプログラムとの差分を示します。以下の差分を取り込んでいただくと、メモ帳に"A"が7回入力できるプログラムが作成できます。
class Program
{
public const int WM_CHAR = 0x0102;
...
static void Main(string[] args)
{
// メモ帳のトップウィンドウのウィンドウハンドル(※見つかることを前提としている)
var mainWindowHandle = Process.GetProcessesByName("notepad")[0].MainWindowHandle;
// 対象の編集領域を探す
var hWnd = FindTargetEdit(GetWindow(mainWindowHandle));
// キーボードにメッセージを送る
// 0x00000041 : "A"の文字コード
// 0x40000007 : キーが離された状態から押された状態へ遷移、7回キー入力を繰り返すことを表すパラメータ
// (どんな値を埋めれば良いか分からない箇所は0埋めとしました)
SendMessage(hWnd, WM_CHAR, 0x00000041, 0x40000007);
}
// 全てのEditコントロールを列挙し、最初に見つけたEditコントロールのウィンドウハンドルを返す
public static IntPtr FindTargetEdit(Window top)
{
var all = GetAllChildWindows(top, new List<Window>());
// クラス名からコントロールを取得する。メモ帳の場合はEditコントロールが編集領域。
return all.Where(x => x.ClassName == "Edit").First().hWnd;
}
実際にやってみて
全く知らない状態からに他アプリケーション(今回の場合はメモ帳)を操作しようと思うと、色々なことを知らなければならないことが分かりました。おそらく、Friendlyはこのような処理をきれいに隠蔽することでGUIの操作を簡潔にできるようにしているのだと思います。
また、改めてFriendlyのソースコードを読んで肝となる部分の理解を深めたいと思います。