-
-
Save kumatti1/78cb31abab7903881afd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//http://www.moug.net/faq/viewtopic.php?t=65909 | |
//yayadonさんのコードをVBAからC++へ変換 | |
#define UNICODE | |
#import "UIAutomationCore.dll" | |
#include <windows.h> | |
#include <string> | |
#include <vector> | |
HRESULT InvokeElement(UIAutomationClient::IUIAutomationElementPtr InvokePatternElem); | |
HRESULT SelectComboBoxItem(UIAutomationClient::IUIAutomation2Ptr UIA2, | |
UIAutomationClient::IUIAutomationElementPtr DesktopWnd, | |
UIAutomationClient::IUIAutomationElementPtr AncestorElem, | |
std::wstring strComboBoxName, | |
std::wstring strListItemName); | |
HRESULT ClickButton(UIAutomationClient::IUIAutomation2Ptr UIA2, | |
UIAutomationClient::IUIAutomationElementPtr AncestorElem, | |
std::wstring strButtonName); | |
HRESULT UIAutomation_Test1(); | |
// Element を Invoke する。(クリックする); | |
HRESULT InvokeElement(UIAutomationClient::IUIAutomationElementPtr InvokePatternElem) | |
{ | |
try { | |
UIAutomationClient::IUIAutomationInvokePatternPtr InvokePtn; | |
InvokePtn = InvokePatternElem->GetCurrentPattern(UIAutomationClient::UIA_InvokePatternId); | |
if (!InvokePtn) | |
{ | |
OutputDebugString(L"InvokePattern を取得できなかった。"); | |
throw S_FALSE; | |
} | |
//クリック | |
InvokePtn->Invoke(); | |
} | |
catch (_com_error& e) { | |
return e.Error(); | |
} | |
catch (HRESULT hr){ | |
return hr; | |
} | |
return S_OK; | |
} | |
// ComboBox のリスト項目を選択する。 | |
HRESULT SelectComboBoxItem(UIAutomationClient::IUIAutomation2Ptr UIA2, | |
UIAutomationClient::IUIAutomationElementPtr DesktopWnd, | |
UIAutomationClient::IUIAutomationElementPtr AncestorElem, | |
std::wstring strComboBoxName, | |
std::wstring strListItemName) | |
{ | |
try { | |
// 探索条件用 | |
UIAutomationClient::IUIAutomationConditionPtr CtrlTypeCdn; //コントロール タイプ | |
UIAutomationClient::IUIAutomationConditionPtr NameCdn; //名前 | |
UIAutomationClient::IUIAutomationConditionPtr Condition; //コントロール タイプ And 名前 | |
// strComboBoxName コンボボックスを探索。 | |
CtrlTypeCdn = UIA2->CreatePropertyCondition(UIAutomationClient::UIA_ControlTypePropertyId, | |
UIAutomationClient::UIA_ComboBoxControlTypeId); | |
NameCdn = UIA2->CreatePropertyCondition(UIAutomationClient::UIA_NamePropertyId, | |
_variant_t(_bstr_t(strComboBoxName.c_str()))); | |
Condition = UIA2->CreateAndCondition(CtrlTypeCdn, NameCdn); | |
UIAutomationClient::IUIAutomationElementPtr ComboboxElem; | |
ComboboxElem = AncestorElem->FindFirst(UIAutomationClient::TreeScope_Subtree, Condition); | |
if (!ComboboxElem) | |
{ | |
std::wstring tmp(strComboBoxName); | |
tmp += L" コンボボックスが見つからなかった。"; | |
OutputDebugString(tmp.c_str()); | |
throw S_FALSE; | |
} | |
UIAutomationClient::IUIAutomationValuePatternPtr ValuePtn; | |
ValuePtn = ComboboxElem->GetCurrentPattern(UIAutomationClient::UIA_ValuePatternId); | |
_bstr_t bstr; | |
ValuePtn->get_CurrentValue(bstr.GetAddress()); | |
std::wstring strCurrentValue((LPWSTR) bstr.GetBSTR()); | |
if (strCurrentValue == strListItemName) | |
{ | |
std::wstring tmp(strComboBoxName); | |
tmp += L" コンボボックスの現在の値と同じ\t"; | |
tmp += strCurrentValue; | |
OutputDebugString(tmp.c_str()); | |
} | |
// コンボボックスをドロップダウン。【必須】 | |
UIAutomationClient::IUIAutomationExpandCollapsePatternPtr ExpandPtn; | |
ExpandPtn = ComboboxElem->GetCurrentPattern(UIAutomationClient::UIA_ExpandCollapsePatternId); | |
ExpandPtn->Expand(); | |
// リストを探索。 | |
CtrlTypeCdn = UIA2->CreatePropertyCondition(UIAutomationClient::UIA_ControlTypePropertyId, | |
UIAutomationClient::UIA_ListControlTypeId); | |
NameCdn = UIA2->CreatePropertyCondition(UIAutomationClient::UIA_NamePropertyId, _variant_t(_bstr_t(strComboBoxName.c_str()))); | |
Condition = UIA2->CreateAndCondition(CtrlTypeCdn, NameCdn); | |
UIAutomationClient::IUIAutomationElementPtr ListElem; // List Control Type | |
ListElem = DesktopWnd->FindFirst(UIAutomationClient::TreeScope_Descendants, Condition); | |
if (!ListElem) | |
{ | |
std::wstring tmp(strComboBoxName); | |
tmp += L" コンボボックスでリストが見つからなかった。"; | |
OutputDebugString(tmp.c_str()); | |
throw S_FALSE; | |
} | |
// リスト項目をすべて探索。 | |
CtrlTypeCdn = UIA2->CreatePropertyCondition(UIAutomationClient::UIA_ControlTypePropertyId, | |
UIAutomationClient::UIA_ListItemControlTypeId); | |
UIAutomationClient::IUIAutomationElementArrayPtr ElemArray; | |
ElemArray = ListElem->FindAll(UIAutomationClient::TreeScope_Children, CtrlTypeCdn); | |
if (!ElemArray) | |
{ | |
std::wstring tmp(strComboBoxName); | |
tmp += L" コンボボックスでリスト項目が見つからなかった。"; | |
OutputDebugString(tmp.c_str()); | |
throw S_FALSE; | |
} | |
int n; | |
ElemArray->get_Length(&n); | |
for (int i = 0; i < n; i++) | |
{ | |
UIAutomationClient::IUIAutomationElementPtr ListItemElem; // ListItem Control Type | |
ListItemElem = ElemArray->GetElement(i); | |
_bstr_t bstr; | |
ListItemElem->get_CurrentName(bstr.GetAddress()); | |
std::wstring tmp2((LPWSTR) bstr.GetBSTR()); | |
if (tmp2 == strListItemName) | |
{ | |
InvokeElement(ListItemElem); | |
} | |
} | |
//Windows10 build 14257以降 ComboBoxに変わる | |
HWND h = (HWND) ComboboxElem->CurrentNativeWindowHandle; | |
HWND hParent = GetParent(h); | |
SendMessageW(hParent, WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(h), CBN_SELCHANGE), (LPARAM) h); | |
} | |
catch (_com_error& e) { | |
return e.Error(); | |
} | |
catch (HRESULT hr){ | |
return hr; | |
} | |
return S_OK; | |
} | |
// ボタンをクリックする | |
HRESULT ClickButton(UIAutomationClient::IUIAutomation2Ptr UIA2, | |
UIAutomationClient::IUIAutomationElementPtr AncestorElem, | |
std::wstring strButtonName) | |
{ | |
try { | |
// 探索条件用 | |
UIAutomationClient::IUIAutomationConditionPtr CtrlTypeCdn; //コントロール タイプ | |
UIAutomationClient::IUIAutomationConditionPtr NameCdn; //名前 | |
UIAutomationClient::IUIAutomationConditionPtr Condition; //コントロール タイプ And 名前 | |
// strButtonName ボタンを探索。 | |
CtrlTypeCdn = UIA2->CreatePropertyCondition(UIAutomationClient::UIA_ControlTypePropertyId, | |
UIAutomationClient::UIA_ButtonControlTypeId); | |
NameCdn = UIA2->CreatePropertyCondition(UIAutomationClient::UIA_NamePropertyId, _variant_t(_bstr_t(strButtonName.c_str()))); | |
Condition = UIA2->CreateAndCondition(CtrlTypeCdn, NameCdn); | |
UIAutomationClient::IUIAutomationElementPtr ButtonElem; | |
ButtonElem = AncestorElem->FindFirst(UIAutomationClient::TreeScope_Subtree, Condition); | |
if (!ButtonElem) | |
{ | |
throw S_FALSE; | |
} | |
// ボタンが有効かを確認。 | |
long lngRet; | |
ButtonElem->get_CurrentIsEnabled(&lngRet); | |
if (!lngRet) | |
{ | |
std::wstring tmp(strButtonName); | |
tmp += L" ボタンが有効でない状態。"; | |
OutputDebugString(tmp.c_str()); | |
throw S_FALSE; | |
} | |
HRESULT rc; | |
rc = InvokeElement(ButtonElem); | |
if (rc != S_OK) | |
{ | |
std::wstring tmp(strButtonName); | |
tmp += L" ボタンをクリックできなかった。"; | |
OutputDebugString(tmp.c_str()); | |
throw S_FALSE; | |
} | |
} | |
catch (_com_error& e) { | |
return e.Error(); | |
} | |
catch (HRESULT hr){ | |
return hr; | |
} | |
return S_OK; | |
} | |
// デスクトップ項目を 12 に変えてみる。 | |
HRESULT UIAutomation_Test1() | |
{ | |
try { | |
// 条件用 | |
UIAutomationClient::IUIAutomationConditionPtr CtrlTypeCdn; //コントロール タイプ | |
UIAutomationClient::IUIAutomationConditionPtr NameCdn; //名前 | |
UIAutomationClient::IUIAutomationConditionPtr Condition; //コントロール タイプ And 名前 | |
HRESULT rc; | |
UIAutomationClient::IUIAutomation2Ptr UIA2; | |
HRESULT hr = UIA2.CreateInstance(__uuidof(UIAutomationClient::CUIAutomation8)); | |
if (FAILED(hr)) | |
throw hr; | |
// デスクトップ ウィンドウを取得。 | |
UIAutomationClient::IUIAutomationElementPtr DesktopWnd; | |
DesktopWnd = UIA2->GetRootElement(); | |
// [ディスプレイ]トップレベル ウィンドウを探索。 | |
CtrlTypeCdn = UIA2->CreatePropertyCondition(UIAutomationClient::UIA_ControlTypePropertyId, | |
UIAutomationClient::UIA_WindowControlTypeId); | |
NameCdn = UIA2->CreatePropertyCondition(UIAutomationClient::UIA_NamePropertyId, _variant_t(_bstr_t(L"ディスプレイ"))); | |
Condition = UIA2->CreateAndCondition(CtrlTypeCdn, NameCdn); | |
UIAutomationClient::IUIAutomationElementPtr DisplayWnd; | |
DisplayWnd = DesktopWnd->FindFirst(UIAutomationClient::TreeScope_Children, Condition); | |
if (!DisplayWnd) | |
{ | |
MessageBox(0, L"[ディスプレイ]ウィンドウが見つかりません。", 0, MB_OK); | |
throw S_FALSE; | |
} | |
const WCHAR *s [] = { L"タイトル バー", | |
L"メニュー", | |
L"メッセージ ボックス", | |
L"パレット タイトル", | |
L"アイコン", | |
L"ヒント" }; | |
int length = _countof(s); | |
std::vector<std::wstring> arr(length); | |
std::copy(s, s + length, arr.begin()); | |
for (int i = 0; i < length; i++){ | |
// [デスクトップ項目]コンボボックス選択 | |
rc = SelectComboBoxItem(UIA2, DesktopWnd, DisplayWnd, L"デスクトップ項目", arr[i].c_str()); | |
if (rc != S_OK) | |
{ | |
MessageBox(0, L"[デスクトップ項目]コンボボックスの値の選択に失敗しました。", 0, MB_OK); | |
throw S_FALSE; | |
} | |
// [フォント サイズ]コンボボックス ---> L"12" に | |
rc = SelectComboBoxItem(UIA2, DesktopWnd, DisplayWnd, L"フォント サイズ", L"12"); | |
if (rc != S_OK) | |
{ | |
MessageBox(0, L"[フォント サイズ]コンボボックスの値の選択に失敗しました。", 0, MB_OK); | |
throw S_FALSE; | |
} | |
} | |
// [適用(A)]ボタン --- クリック | |
rc = ClickButton(UIA2, DisplayWnd, L"適用(A)"); | |
if (rc != S_OK) | |
{ | |
std::wstring tmp2(L"[適用(A)]ボタンをクリックできませんでした。\n"); | |
tmp2 += L"すでに現在の値である可能性があります。"; | |
MessageBox(0, tmp2.c_str(), 0, MB_OK); | |
} | |
} | |
catch (_com_error& e) { | |
return e.Error(); | |
} | |
catch (HRESULT hr){ | |
return hr; | |
} | |
} | |
int CALLBACK WinMain( | |
_In_ HINSTANCE hInstance, | |
_In_ HINSTANCE hPrevInstance, | |
_In_ LPSTR lpCmdLine, | |
_In_ int nCmdShow) | |
{ | |
HRESULT hr = CoInitialize(nullptr); | |
if (FAILED(hr)) | |
return -1; | |
UIAutomation_Test1(); | |
CoUninitialize(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment