このテーマの続きです。
[WinActor]UIAutomationをWinActorに組み込む
Inspectツールで個別にアプリケーションの検査をしてみると、やっぱりAutomationIDが付与されていないコントロールもままある。
NameかAutomationIDで特定できそうだけども、それすらも難しそうだなーって時は、その前後の要素を検査してみたらPreviousとかNextで辿って捕まえられそうな感じしてきた。
サクッと機能追加して作ってみたぜ。
1.これでどうよ?っていう実装。

- ウィンドウ識別名 ⇒ 対象ウィンドウを選択。
- プロパティ ⇒ NameとAutomationIDが選択できる。
- 操作の内容 ⇒ クリック、フォーカスする、値の取得、値の設定、Nameの取得から選ぶ。
- 設定値 ⇒ 操作の内容でSetValueを選んだ時だけ設定。
- オプション ⇒ NextとかPreviousで辿ってコントロール取得する時用
- 取得結果 ⇒ 値の取得系の時は使う。
※ 2019/08/12 FirstChildとLastChildもオプションに追加
2.設定方法
ダウンロードした資材のzipを解凍したら、WinActor.exeと同じフォルダにUIA_cmd.exeを配置。
スクリプト実行ノードのスクリプトに以下を張り付けすればすぐ使えます。
hwnd = GetUMSWindowHandle(@ウィンドウ識別名@)
prop = !プロパティ|AutomationID,Name!
keyVal = !プロパティの値!
func = !操作の内容|Click,Focus,SetValue,GetValue,GetText!
sval = !設定値!
optn = !オプション|,Next,Previous,FirstChild,LastChild!
uia = "UIA_cmd.exe "
If IsNull(hwnd) Then
Err.Raise 1, "", "ウィンドウハンドルを取得できませんでした。"
Else
If Len(optn) > 0 Then prop = prop & ":" & optn
Set objExecCmd = CreateObject("WScript.Shell").Exec(uia & func & " """ & hwnd & """ """ & prop & ":" & keyVal & """ " & sval)
Do While objExecCmd.Status = 0
WScript.Sleep(500)
Loop
SetUMSVariable $取得結果$ , objExecCmd.StdOut.ReadAll
End If
3.UIA_cmd.exe側の処理
最初に作ったコードではAutomationIDでしか検索しない様にしてたけども、Nameで検索するパターンも加味してAutomationPropertyの取得部分を変更。
そっから、取得したAutomationElementに対してOptionでNextかPreviousが指定されていれば移動するって寸法です。
Dim TargetElm As AutomationElement
Dim AutoProp As AutomationProperty
Dim PropCond As PropertyCondition
Select Case TargetVals(0)
Case "Name"
AutoProp = AutomationElement.NameProperty
Case "AutomationID"
AutoProp = AutomationElement.AutomationIdProperty
Case Else
Console.WriteLine("操作対象の指定方法が不正です。")
Exit Sub
End Select
PropCond = New PropertyCondition(AutoProp, TargetVals(2), PropertyConditionFlags.IgnoreCase)
TargetElm = elm.FindFirst(TreeScope.Descendants, PropCond)
Select Case TargetVals(1)
Case "Previous"
TargetElm = TreeWalker.ControlViewWalker.GetPreviousSibling(TargetElm)
Case "Next"
TargetElm = TreeWalker.ControlViewWalker.GetNextSibling(TargetElm)
Case "FirstChild"
TargetElm = TreeWalker.RawViewWalker.GetFirstChild(TargetElm)
Case "LastChild"
TargetElm = TreeWalker.RawViewWalker.GetLastChild(TargetElm)
Case Else
Console.WriteLine("操作対象の指定方法が不正です。")
Exit Sub
End Select