質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2999閲覧

VC++でUI Automationを使いボタンコントロールをクリックする処理を行いたい

notgoodpg

総合スコア37

MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/01/25 08:25

編集2018/01/26 05:54

まとめ

  • UI Automationでボタンのクリックまで出来る
  • 最初のハンドラを取得するところもUI Automationで出来る

前提・実現したいこと

VC++でUI Automationを使いボタンコントロールをクリックする処理を行いたい。

自作のアプリケーションから他のアプリケーションを操作する処理を実現するために
まずWindows7に標準で搭載されている電卓アプリを操作しようとしています。
以前の質問でボタンのテキストが空になっていることが判明し、そのボタンを判別する手段としてUI Autmationを教えていただきました。
なんとかボタンの特定までは行き着けそうなのですが、特定したボタンをクリックする事が出来ずにいます。

今のところは

UI Automationで目的のNameを持つWindowを探す ↓ 見つかればHWNDを取得する ↓ SendMessageでBM_CLICKを送出することでボタンを押す ```という流れで実現できるかなと思いながらコードを作っています。 よろしくお願いいたします。 ### 該当のソースコード 2018 0126 動いた 過去のソースは編集履歴を参照してください ```c++ void CUIAutoDlg::UseUIAutomation() { // COM初期化 if( CoInitialize(NULL) != S_OK){ MessageBox(_T("CoInitialize stuck!")); return; } // IUIAutmation初期化 IUIAutomation *autoMaster; if (HRESULT h = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&autoMaster)) != S_OK) { MessageBox(_T("CoCreateInstance stuck!")); return; } // TreeWalker初期化 IUIAutomationTreeWalker *treeWalker; autoMaster->get_ContentViewWalker(&treeWalker); // 電卓のIUIAutomationElement取得 IUIAutomationElement *autElm = NULL; HWND h = ::FindWindow(_T("CalcFrame"), _T("電卓")); if(autoMaster->ElementFromHandle(h, &autElm)){ MessageBox(_T("ElementFromHandle stuck!")); return; } autElm->SetFocus(); // 1のボタンを探してくる IUIAutomationElement *clickElement = NULL; if (GetUIAutomationElementFromChildrenByName(autoMaster, treeWalker, autElm, L"1", clickElement) != S_OK) { MessageBox(_T("control not found!")); return; } // 押す IUnknown *btn; clickElement->GetCurrentPattern(UIA_InvokePatternId, &btn); ((IUIAutomationInvokePattern *)btn)->Invoke(); btn->Release(); autElm->Release(); treeWalker->Release(); autoMaster->Release(); CoUninitialize();} BOOL CUIAutoDlg::GetUIAutomationElementFromChildrenByName(IUIAutomation *autoMaster, IUIAutomationTreeWalker *treeWalker, IUIAutomationElement *uiaElement, const BSTR windowName, IUIAutomationElement *& distElement) { IUIAutomationElement *childElm = NULL; // 子コントロールからさがす if (treeWalker->GetFirstChildElement(uiaElement, &childElm) != S_OK) { return S_FALSE; // 子がない } IUIAutomationElement *nextChildElm = NULL; UIA_HWND hwnd = NULL; while (childElm) { BSTR tempWindowName; childElm->get_CurrentName(&tempWindowName); if (_tcscmp( tempWindowName, windowName) == 0) { // Nameが一致するコントロールを見つけた SysFreeString(tempWindowName); // 用済み distElement = childElm; return S_OK; //hwnd; // UIA_HWNDはHWNDじゃない! } SysFreeString(tempWindowName); // 用済み // 孫以下のウィドウは再起で処理 if (GetUIAutomationElementFromChildrenByName(autoMaster, treeWalker, childElm, windowName, distElement) == S_OK) return S_OK; treeWalker->GetNextSiblingElement(childElm, &nextChildElm); childElm->Release(); // 用済み childElm = nextChildElm; } return S_FALSE; // nameの該当するコントロールが無い }

一応、GetHWNDByNameの戻り値をNULLにして一旦動かしてみてはいます。

試したこと

UIA_HWNDからHWNDへの変換方法を探してみましたが見つけられませんでした。
HWNDを取得する方法を探してみましたが見つけられませんでした・・・。
IUIAutmationElementクラスがメッセージ投げてくれるのではなどと思って調べてみましたがそれっぽい関数が見つけられませんでした

補足情報(FW/ツールのバージョンなど)

  • Windows7/64bit SP1
  • VisualStudio2015SP
  • VC++/MFC
  • UI Automation

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ボタン操作はUIAutomationのAPIで出来ます。
UI Automation Control Patterns Overview
ここに一覧が載っています。説明が抽象的ですが、IUIAutomationInvokePatternを取得してInvokeすればいいことが分かります。
Windows SDKのinspectでもメニューからInvokeを実行することが出来ます。

投稿2018/01/25 13:02

hmmm

総合スコア818

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

notgoodpg

2018/01/26 05:54

ご回答ありがとうございます。 なんとか動くようになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問