uia 0.1.3.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +5 -0
- data/ext/UiaDll/Release/UIA.Helper.dll +0 -0
- data/ext/UiaDll/Release/UiaDll.dll +0 -0
- data/ext/UiaDll/UIA.Helper/Element.cs +14 -24
- data/ext/UiaDll/UiaDll/ConditionHelper.h +2 -0
- data/ext/UiaDll/UiaDll/ConditionMethods.cpp +10 -0
- data/ext/UiaDll/UiaDll/ElementMethods.cpp +40 -15
- data/ext/UiaDll/UiaDll/ElementStructures.h +14 -0
- data/ext/UiaDll/UiaDll/ExpandCollapseMethods.cpp +3 -3
- data/ext/UiaDll/UiaDll/InvokePatternMethods.cpp +1 -1
- data/ext/UiaDll/UiaDll/RangeValueMethods.cpp +2 -2
- data/ext/UiaDll/UiaDll/SelectionItemMethods.cpp +4 -4
- data/ext/UiaDll/UiaDll/SelectionMethods.cpp +2 -2
- data/ext/UiaDll/UiaDll/Stdafx.h +1 -1
- data/ext/UiaDll/UiaDll/TableItemMethods.cpp +1 -1
- data/ext/UiaDll/UiaDll/TableMethods.cpp +2 -2
- data/ext/UiaDll/UiaDll/TextMethods.cpp +1 -1
- data/ext/UiaDll/UiaDll/ToggleMethods.cpp +2 -2
- data/ext/UiaDll/UiaDll/ValuePatternMethods.cpp +2 -2
- data/ext/UiaDll/UiaDll/WindowMethods.cpp +3 -3
- data/lib/uia/element.rb +4 -0
- data/lib/uia/finder.rb +12 -2
- data/lib/uia/library.rb +22 -3
- data/lib/uia/patterns/selection.rb +1 -1
- data/lib/uia/patterns/table.rb +2 -2
- data/lib/uia/version.rb +1 -1
- data/spec/uia/element_spec.rb +14 -1
- metadata +3 -3
data/ChangeLog
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
=== Version 0.2
|
2
|
+
* Enhancements
|
3
|
+
* added Element#find_all method to find multiple elements by locators
|
4
|
+
* Table and SelectionItem utilize #find_all rather than #filter
|
5
|
+
|
1
6
|
=== Version 0.1.3.1 / 2014-04-29
|
2
7
|
* Bug Fixes
|
3
8
|
* fixed issue with non-fully referenced InvalidControlType class
|
Binary file
|
Binary file
|
@@ -17,6 +17,16 @@ namespace UIA.Helper
|
|
17
17
|
_element = element;
|
18
18
|
}
|
19
19
|
|
20
|
+
public static Element From(AutomationElement element)
|
21
|
+
{
|
22
|
+
return null == element ? null : new Element(element);
|
23
|
+
}
|
24
|
+
|
25
|
+
public static Element[] From(AutomationElement[] elements)
|
26
|
+
{
|
27
|
+
return elements.Select(x => new Element(x)).ToArray();
|
28
|
+
}
|
29
|
+
|
20
30
|
public TPattern As<TPattern>(AutomationPattern pattern)
|
21
31
|
{
|
22
32
|
return (TPattern)_element.GetCurrentPattern(pattern);
|
@@ -102,11 +112,6 @@ namespace UIA.Helper
|
|
102
112
|
get { return Find(TreeScope.Children, Condition.TrueCondition); }
|
103
113
|
}
|
104
114
|
|
105
|
-
public Element[] ChildrenOf(AutomationPropertyCondition.Id id)
|
106
|
-
{
|
107
|
-
return Find(TreeScope.Children, AutomationPropertyCondition.From(id));
|
108
|
-
}
|
109
|
-
|
110
115
|
public Element[] Descendants
|
111
116
|
{
|
112
117
|
get { return Find(TreeScope.Descendants, Condition.TrueCondition); }
|
@@ -122,14 +127,14 @@ namespace UIA.Helper
|
|
122
127
|
Mouse.ClickCenter(_element);
|
123
128
|
}
|
124
129
|
|
125
|
-
public
|
130
|
+
public Element[] Find(TreeScope scope, Condition condition)
|
126
131
|
{
|
127
|
-
return
|
132
|
+
return Find(_element, scope, condition);
|
128
133
|
}
|
129
134
|
|
130
|
-
public
|
135
|
+
public Element FindFirst(TreeScope scope, Condition condition)
|
131
136
|
{
|
132
|
-
return
|
137
|
+
return NullOr(_element.FindFirst(scope, condition));
|
133
138
|
}
|
134
139
|
|
135
140
|
public static Element ById(string automationId)
|
@@ -142,11 +147,6 @@ namespace UIA.Helper
|
|
142
147
|
return FindFirst(scope, automationId.IdCondition());
|
143
148
|
}
|
144
149
|
|
145
|
-
public Element ChildWith(TreeScope scope, Condition condition)
|
146
|
-
{
|
147
|
-
return FindFirst(scope, condition);
|
148
|
-
}
|
149
|
-
|
150
150
|
public static Element ByName(string name)
|
151
151
|
{
|
152
152
|
return FindFirst(new PropertyCondition(AutomationElement.NameProperty, name));
|
@@ -172,11 +172,6 @@ namespace UIA.Helper
|
|
172
172
|
return FindFirst(new PropertyCondition(AutomationElement.RuntimeIdProperty, runtimeId), TreeScope.Descendants);
|
173
173
|
}
|
174
174
|
|
175
|
-
private Element[] Find(TreeScope scope, Condition condition)
|
176
|
-
{
|
177
|
-
return Find(_element, scope, condition);
|
178
|
-
}
|
179
|
-
|
180
175
|
private static Element[] Find(AutomationElement element, TreeScope scope, Condition condition)
|
181
176
|
{
|
182
177
|
return element.FindAll(scope, condition).Cast<AutomationElement>()
|
@@ -184,11 +179,6 @@ namespace UIA.Helper
|
|
184
179
|
.ToArray();
|
185
180
|
}
|
186
181
|
|
187
|
-
private Element FindFirst(TreeScope scope, Condition condition)
|
188
|
-
{
|
189
|
-
return NullOr(_element.FindFirst(scope, condition));
|
190
|
-
}
|
191
|
-
|
192
182
|
private static Element FindFirst(Condition condition, TreeScope scope = TreeScope.Children)
|
193
183
|
{
|
194
184
|
return NullOr(AutomationElement.RootElement.FindFirst(scope, condition));
|
@@ -30,6 +30,8 @@ public:
|
|
30
30
|
return ControlTypeConditions(searchCondition->numbers, searchCondition->numbersCount);
|
31
31
|
} else if(searchCondition->IsString()) {
|
32
32
|
value = gcnew String(searchCondition->string);
|
33
|
+
} else if(searchCondition->IsPatternAvailableProperty()) {
|
34
|
+
value = true;
|
33
35
|
} else {
|
34
36
|
value = searchCondition->number;
|
35
37
|
}
|
@@ -15,6 +15,16 @@ extern "C" {
|
|
15
15
|
return new SearchCondition(AutomationElement::NameProperty->Id, name);
|
16
16
|
}
|
17
17
|
|
18
|
+
__declspec(dllexport) SearchConditionPtr Condition_Pattern(const char* pattern, char* errorInfo, const int errorInfoLength) {
|
19
|
+
try {
|
20
|
+
auto patternPropertyId = dynamic_cast<AutomationProperty^>(AutomationElement::typeid->GetField(gcnew String(pattern))->GetValue(nullptr))->Id;
|
21
|
+
return new SearchCondition(patternPropertyId, true);
|
22
|
+
} catch(Exception^ e) {
|
23
|
+
StringHelper::CopyToUnmanagedString(String::Format("{0} is an invalid AutomationProperty", gcnew String(pattern)), errorInfo, errorInfoLength);
|
24
|
+
return NULL;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
18
28
|
__declspec(dllexport) SearchConditionPtr Condition_ControlType(const int n, const int arg0, ...) {
|
19
29
|
va_list arguments;
|
20
30
|
va_start(arguments, arg0);
|
@@ -4,21 +4,20 @@
|
|
4
4
|
using namespace UIA::Helper;
|
5
5
|
|
6
6
|
extern "C" {
|
7
|
-
Element^
|
7
|
+
Element^ ElementFrom(ElementInformationPtr element) {
|
8
8
|
if( element->nativeWindowHandle > 0 ) {
|
9
9
|
return Element::ByHandle(IntPtr(element->nativeWindowHandle));
|
10
10
|
}
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
return Element::ByRuntimeId(ArrayHelper::ToArray(element->runtimeId, element->runtimeIdLength));
|
13
|
+
}
|
15
14
|
__declspec(dllexport) void Element_Release(ElementInformationPtr elementInformation) {
|
16
15
|
delete elementInformation;
|
17
16
|
}
|
18
17
|
|
19
18
|
__declspec(dllexport) void Element_Refresh(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
20
19
|
try {
|
21
|
-
element->Refresh(
|
20
|
+
element->Refresh(ElementFrom(element));
|
22
21
|
} catch(Exception^ e) {
|
23
22
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
24
23
|
}
|
@@ -26,16 +25,16 @@ extern "C" {
|
|
26
25
|
|
27
26
|
__declspec(dllexport) void Element_SendKeys(ElementInformationPtr element, const char* keysToSend, char* errorInfo, const int errorInfoLength) {
|
28
27
|
try {
|
29
|
-
|
28
|
+
ElementFrom(element)->SendKeys(gcnew String(keysToSend));
|
30
29
|
} catch(Exception^ e) {
|
31
30
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
32
31
|
}
|
33
32
|
}
|
34
33
|
|
35
|
-
ElementInformationPtr
|
34
|
+
ElementInformationPtr ManagedFindFirst(ElementInformationPtr element, const char* treeScope, list<SearchConditionPtr>& conditions, char* errorInfo, const int errorInfoLength) {
|
36
35
|
try {
|
37
36
|
auto scope = (TreeScope) Enum::Parse(TreeScope::typeid, gcnew String(treeScope));
|
38
|
-
return ElementInformation::From(
|
37
|
+
return ElementInformation::From(ElementFrom(element)->FindFirst(scope, ConditionHelper::ConditionFrom(conditions)));
|
39
38
|
} catch(Exception^ e) {
|
40
39
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
41
40
|
}
|
@@ -43,7 +42,33 @@ extern "C" {
|
|
43
42
|
return NULL;
|
44
43
|
}
|
45
44
|
|
46
|
-
__declspec(dllexport) ElementInformationPtr
|
45
|
+
__declspec(dllexport) ElementInformationPtr FindFirst(ElementInformationPtr element, const char* treeScope, char* errorInfo, const int errorInfoLength, const int count, SearchConditionPtr arg0, ...) {
|
46
|
+
va_list arguments;
|
47
|
+
va_start(arguments, arg0);
|
48
|
+
|
49
|
+
list<SearchConditionPtr> conditions;
|
50
|
+
conditions.push_back(arg0);
|
51
|
+
for(auto index = 1; index < count; index++) {
|
52
|
+
conditions.push_back(va_arg(arguments, SearchConditionPtr));
|
53
|
+
}
|
54
|
+
|
55
|
+
return ManagedFindFirst(element, treeScope, conditions, errorInfo, errorInfoLength);
|
56
|
+
}
|
57
|
+
|
58
|
+
int ManagedFindAll(ElementInformationPtr element, ElementInformation** elements, const char* treeScope, list<SearchConditionPtr>& conditions, char* errorInfo, const int errorInfoLength) {
|
59
|
+
try {
|
60
|
+
auto scope = (TreeScope) Enum::Parse(TreeScope::typeid, gcnew String(treeScope));
|
61
|
+
auto foundElements = ElementFrom(element)->Find(scope, ConditionHelper::ConditionFrom(conditions));
|
62
|
+
*elements = ElementInformation::From(foundElements);
|
63
|
+
return foundElements->Length;
|
64
|
+
} catch(Exception^ e) {
|
65
|
+
StringHelper::CopyToUnmanagedString(e->Message + Environment::NewLine + e->StackTrace, errorInfo, errorInfoLength);
|
66
|
+
}
|
67
|
+
|
68
|
+
return 0;
|
69
|
+
}
|
70
|
+
|
71
|
+
__declspec(dllexport) int FindAll(ElementInformationPtr parent, ElementInformation** elements, const char* treeScope, char* errorInfo, const int errorInfoLength, const int count, SearchConditionPtr arg0, ...) {
|
47
72
|
va_list arguments;
|
48
73
|
va_start(arguments, arg0);
|
49
74
|
|
@@ -53,7 +78,7 @@ extern "C" {
|
|
53
78
|
conditions.push_back(va_arg(arguments, SearchConditionPtr));
|
54
79
|
}
|
55
80
|
|
56
|
-
return
|
81
|
+
return ManagedFindAll(parent, elements, treeScope, conditions, errorInfo, errorInfoLength);
|
57
82
|
}
|
58
83
|
|
59
84
|
__declspec(dllexport) ElementInformationPtr Element_FindById(const char* automationId, char* errorInfo, const int errorLength) {
|
@@ -119,7 +144,7 @@ extern "C" {
|
|
119
144
|
|
120
145
|
__declspec(dllexport) int Element_Children(ElementInformationPtr parentElement, ElementInformation** children, char* errorInfo, const int errorLength) {
|
121
146
|
try {
|
122
|
-
auto elements =
|
147
|
+
auto elements = ElementFrom(parentElement)->Children;
|
123
148
|
*children = ElementInformation::From(elements);
|
124
149
|
return elements->Length;
|
125
150
|
} catch(Exception^ error) {
|
@@ -130,7 +155,7 @@ extern "C" {
|
|
130
155
|
|
131
156
|
__declspec(dllexport) int Element_Descendants(ElementInformationPtr parentElement, ElementInformation** descendants, char* errorInfo, const int errorLength) {
|
132
157
|
try {
|
133
|
-
auto elements =
|
158
|
+
auto elements = ElementFrom(parentElement)->Descendants;
|
134
159
|
*descendants = ElementInformation::From(elements);
|
135
160
|
return elements->Length;
|
136
161
|
} catch(Exception^ error) {
|
@@ -141,7 +166,7 @@ extern "C" {
|
|
141
166
|
|
142
167
|
__declspec(dllexport) void Element_ClickClickablePoint(ElementInformationPtr element, char* errorInfo, const int errorLength) {
|
143
168
|
try {
|
144
|
-
|
169
|
+
ElementFrom(element)->ClickClickablePoint();
|
145
170
|
} catch(Exception^ error) {
|
146
171
|
StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
|
147
172
|
}
|
@@ -149,7 +174,7 @@ extern "C" {
|
|
149
174
|
|
150
175
|
__declspec(dllexport) void Element_ClickCenter(ElementInformationPtr element, char* errorInfo, const int errorLength) {
|
151
176
|
try {
|
152
|
-
|
177
|
+
ElementFrom(element)->ClickCenter();
|
153
178
|
} catch(Exception^ error) {
|
154
179
|
StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
|
155
180
|
}
|
@@ -157,7 +182,7 @@ extern "C" {
|
|
157
182
|
|
158
183
|
__declspec(dllexport) void Element_Focus(ElementInformationPtr element, char* errorInfo, const int errorLength) {
|
159
184
|
try {
|
160
|
-
|
185
|
+
ElementFrom(element)->SetFocus();
|
161
186
|
} catch(Exception^ error) {
|
162
187
|
StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
|
163
188
|
}
|
@@ -13,6 +13,10 @@ typedef struct _SearchCondition {
|
|
13
13
|
int* numbers;
|
14
14
|
int numbersCount;
|
15
15
|
|
16
|
+
_SearchCondition(const int id) : string(NULL), numbers(NULL) {
|
17
|
+
Reset(id);
|
18
|
+
}
|
19
|
+
|
16
20
|
_SearchCondition(const int id, const char* s) : string(NULL), numbers(NULL) {
|
17
21
|
Reset(id);
|
18
22
|
|
@@ -46,6 +50,16 @@ typedef struct _SearchCondition {
|
|
46
50
|
return NULL != string;
|
47
51
|
}
|
48
52
|
|
53
|
+
bool IsPatternAvailableProperty() {
|
54
|
+
try {
|
55
|
+
auto automationProperty = System::Windows::Automation::AutomationProperty::LookupById(propertyId);
|
56
|
+
return automationProperty->ProgrammaticName->Contains("PatternAvailableProperty");
|
57
|
+
} catch(Exception^ e) {
|
58
|
+
Console::WriteLine(e->Message);
|
59
|
+
return false;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
49
63
|
static _SearchCondition* FromControlTypes(list<const int>& controlTypes) {
|
50
64
|
return new SearchCondition(System::Windows::Automation::AutomationElement::ControlTypeProperty->Id, controlTypes);
|
51
65
|
}
|
@@ -7,7 +7,7 @@ extern "C" {
|
|
7
7
|
|
8
8
|
__declspec(dllexport) ExpandCollapseInfoPtr ExpandCollapse_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
9
|
try {
|
10
|
-
auto info =
|
10
|
+
auto info = ElementFrom(element)->As<ExpandCollapsePattern^>(ExpandCollapsePattern::Pattern)->Current;
|
11
11
|
return new ExpandCollapseInfo(info.ExpandCollapseState.ToString());
|
12
12
|
} catch(Exception^ e) {
|
13
13
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
@@ -17,7 +17,7 @@ extern "C" {
|
|
17
17
|
|
18
18
|
__declspec(dllexport) void ExpandCollapse_Expand(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
19
19
|
try {
|
20
|
-
|
20
|
+
ElementFrom(element)->As<ExpandCollapsePattern^>(ExpandCollapsePattern::Pattern)->Expand();
|
21
21
|
} catch(Exception^ e) {
|
22
22
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
23
23
|
}
|
@@ -25,7 +25,7 @@ extern "C" {
|
|
25
25
|
|
26
26
|
__declspec(dllexport) void ExpandCollapse_Collapse(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
27
27
|
try {
|
28
|
-
|
28
|
+
ElementFrom(element)->As<ExpandCollapsePattern^>(ExpandCollapsePattern::Pattern)->Collapse();
|
29
29
|
} catch(Exception^ e) {
|
30
30
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
31
31
|
}
|
@@ -3,7 +3,7 @@
|
|
3
3
|
extern "C" {
|
4
4
|
__declspec(dllexport) void Invoke(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
5
5
|
try {
|
6
|
-
|
6
|
+
ElementFrom(element)->As<InvokePattern^>(InvokePattern::Pattern)->Invoke();
|
7
7
|
} catch(Exception^ e) {
|
8
8
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
9
9
|
}
|
@@ -7,7 +7,7 @@ extern "C" {
|
|
7
7
|
|
8
8
|
__declspec(dllexport) RangeValueInformationPtr RangeValue_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
9
|
try {
|
10
|
-
return new RangeValueInformation(
|
10
|
+
return new RangeValueInformation(ElementFrom(element)->As<RangeValuePattern^>(RangeValuePattern::Pattern)->Current);
|
11
11
|
} catch(Exception^ e) {
|
12
12
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
13
13
|
return NULL;
|
@@ -16,7 +16,7 @@ extern "C" {
|
|
16
16
|
|
17
17
|
__declspec(dllexport) void RangeValue_SetValue(ElementInformationPtr element, double value, char* errorInfo, const int errorInfoLength) {
|
18
18
|
try {
|
19
|
-
return
|
19
|
+
return ElementFrom(element)->As<RangeValuePattern^>(RangeValuePattern::Pattern)->SetValue(value);
|
20
20
|
} catch(Exception^ e) {
|
21
21
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
22
22
|
}
|
@@ -7,7 +7,7 @@ extern "C" {
|
|
7
7
|
|
8
8
|
__declspec(dllexport) SelectionItemInformationPtr SelectionItem_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
9
|
try {
|
10
|
-
auto info =
|
10
|
+
auto info = ElementFrom(element)->As<SelectionItemPattern^>(SelectionItemPattern::Pattern)->Current;
|
11
11
|
return new SelectionItemInformation(info);
|
12
12
|
} catch(Exception^ e) {
|
13
13
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
@@ -17,7 +17,7 @@ extern "C" {
|
|
17
17
|
|
18
18
|
__declspec(dllexport) void SelectionItem_Select(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
19
19
|
try {
|
20
|
-
|
20
|
+
ElementFrom(element)->As<SelectionItemPattern^>(SelectionItemPattern::Pattern)->Select();
|
21
21
|
} catch(Exception^ e) {
|
22
22
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
23
23
|
}
|
@@ -25,7 +25,7 @@ extern "C" {
|
|
25
25
|
|
26
26
|
__declspec(dllexport) void SelectionItem_AddToSelection(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
27
27
|
try {
|
28
|
-
|
28
|
+
ElementFrom(element)->As<SelectionItemPattern^>(SelectionItemPattern::Pattern)->AddToSelection();
|
29
29
|
} catch(Exception^ e) {
|
30
30
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
31
31
|
}
|
@@ -33,7 +33,7 @@ extern "C" {
|
|
33
33
|
|
34
34
|
__declspec(dllexport) void SelectionItem_RemoveFromSelection(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
35
35
|
try {
|
36
|
-
|
36
|
+
ElementFrom(element)->As<SelectionItemPattern^>(SelectionItemPattern::Pattern)->RemoveFromSelection();
|
37
37
|
} catch(Exception^ e) {
|
38
38
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
39
39
|
}
|
@@ -7,7 +7,7 @@ extern "C" {
|
|
7
7
|
|
8
8
|
__declspec(dllexport) SelectionInformationPtr Selection_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
9
|
try {
|
10
|
-
return new SelectionInformation(
|
10
|
+
return new SelectionInformation(ElementFrom(element)->As<SelectionPattern^>(SelectionPattern::Pattern)->Current);
|
11
11
|
} catch(Exception^ e) {
|
12
12
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
13
13
|
return NULL;
|
@@ -16,7 +16,7 @@ extern "C" {
|
|
16
16
|
|
17
17
|
__declspec(dllexport) int Selection_Selections(ElementInformationPtr element, ElementInformation** selections, char* errorInfo, const int errorInfoLength) {
|
18
18
|
try {
|
19
|
-
auto selectedElements = Element::From(
|
19
|
+
auto selectedElements = Element::From(ElementFrom(element)->As<SelectionPattern^>(SelectionPattern::Pattern)->Current.GetSelection());
|
20
20
|
*selections = ElementInformation::From(selectedElements);
|
21
21
|
return selectedElements->Length;
|
22
22
|
} catch(Exception^ e) {
|
data/ext/UiaDll/UiaDll/Stdafx.h
CHANGED
@@ -7,7 +7,7 @@ extern "C" {
|
|
7
7
|
|
8
8
|
__declspec(dllexport) TableItemInformationPtr TableItem_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
9
|
try {
|
10
|
-
return new TableItemInformation(
|
10
|
+
return new TableItemInformation(ElementFrom(element)->As<TableItemPattern^>(TableItemPattern::Pattern)->Current);
|
11
11
|
} catch(Exception^ e) {
|
12
12
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
13
13
|
return NULL;
|
@@ -7,7 +7,7 @@ extern "C" {
|
|
7
7
|
|
8
8
|
__declspec(dllexport) TableInformationPtr Table_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
9
|
try {
|
10
|
-
return new TableInformation(
|
10
|
+
return new TableInformation(ElementFrom(element)->As<TablePattern^>(TablePattern::Pattern)->Current);
|
11
11
|
} catch(Exception^ e) {
|
12
12
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
13
13
|
return NULL;
|
@@ -16,7 +16,7 @@ extern "C" {
|
|
16
16
|
|
17
17
|
__declspec(dllexport) int Table_Headers(ElementInformationPtr element, ElementInformation** headers, char* errorInfo, const int errorInfoLength) {
|
18
18
|
try {
|
19
|
-
auto headerElements =
|
19
|
+
auto headerElements = ElementFrom(element)->As<TablePattern^>(TablePattern::Pattern)->Current.GetColumnHeaders();
|
20
20
|
*headers = ElementInformation::From(Element::From(headerElements));
|
21
21
|
return headerElements->Length;
|
22
22
|
} catch(Exception^ e) {
|
@@ -3,7 +3,7 @@
|
|
3
3
|
extern "C" {
|
4
4
|
__declspec(dllexport) int Text_GetText(ElementInformationPtr element, char* text, const int textLength, char* errorInfo, const int errorInfoLength) {
|
5
5
|
try {
|
6
|
-
auto theText =
|
6
|
+
auto theText = ElementFrom(element)->As<TextPattern^>(TextPattern::Pattern)->DocumentRange->GetText(-1);
|
7
7
|
if( NULL != text ) {
|
8
8
|
StringHelper::CopyToUnmanagedString(theText, text, textLength);
|
9
9
|
}
|
@@ -7,7 +7,7 @@ extern "C" {
|
|
7
7
|
|
8
8
|
__declspec(dllexport) ToggleInformationPtr Toggle_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
9
|
try {
|
10
|
-
auto info =
|
10
|
+
auto info = ElementFrom(element)->As<TogglePattern^>(TogglePattern::Pattern)->Current;
|
11
11
|
return new ToggleInformation(info.ToggleState.ToString());
|
12
12
|
} catch(Exception^ e) {
|
13
13
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
@@ -17,7 +17,7 @@ extern "C" {
|
|
17
17
|
|
18
18
|
__declspec(dllexport) void Toggle(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
19
19
|
try {
|
20
|
-
|
20
|
+
ElementFrom(element)->As<TogglePattern^>(TogglePattern::Pattern)->Toggle();
|
21
21
|
} catch(Exception^ e) {
|
22
22
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
23
23
|
}
|
@@ -7,7 +7,7 @@ extern "C" {
|
|
7
7
|
|
8
8
|
__declspec(dllexport) void Value_Set(ElementInformationPtr element, const char* value, char* errorInfo, const int errorInfoLength) {
|
9
9
|
try {
|
10
|
-
|
10
|
+
ElementFrom(element)->As<ValuePattern^>(ValuePattern::Pattern)->SetValue(gcnew String(value));
|
11
11
|
} catch(Exception^ e) {
|
12
12
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
13
13
|
}
|
@@ -15,7 +15,7 @@ extern "C" {
|
|
15
15
|
|
16
16
|
__declspec(dllexport) ValuePatternInformationPtr Value_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
17
17
|
try {
|
18
|
-
auto valuePattern =
|
18
|
+
auto valuePattern = ElementFrom(element)->As<ValuePattern^>(ValuePattern::Pattern);
|
19
19
|
return new ValuePatternInformation(valuePattern->Current);
|
20
20
|
} catch(Exception^ e) {
|
21
21
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
@@ -7,7 +7,7 @@ extern "C" {
|
|
7
7
|
|
8
8
|
__declspec(dllexport) WindowInformationPtr Window_Information(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
9
9
|
try {
|
10
|
-
return new WindowInformation(
|
10
|
+
return new WindowInformation(ElementFrom(element)->As<WindowPattern^>(WindowPattern::Pattern)->Current);
|
11
11
|
} catch(Exception^ e) {
|
12
12
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
13
13
|
return NULL;
|
@@ -16,7 +16,7 @@ extern "C" {
|
|
16
16
|
|
17
17
|
__declspec(dllexport) void Window_SetVisualState(ElementInformationPtr element, const char* visualState, char* errorInfo, const int errorInfoLength) {
|
18
18
|
try {
|
19
|
-
|
19
|
+
ElementFrom(element)->As<WindowPattern^>(WindowPattern::Pattern)->SetWindowVisualState((WindowVisualState) Enum::Parse(WindowVisualState::typeid, gcnew String(visualState), false));
|
20
20
|
} catch(Exception^ e) {
|
21
21
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
22
22
|
}
|
@@ -24,7 +24,7 @@ extern "C" {
|
|
24
24
|
|
25
25
|
__declspec(dllexport) void Window_Close(ElementInformationPtr element, char* errorInfo, const int errorInfoLength) {
|
26
26
|
try {
|
27
|
-
|
27
|
+
ElementFrom(element)->As<WindowPattern^>(WindowPattern::Pattern)->Close();
|
28
28
|
} catch(Exception^ e) {
|
29
29
|
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
30
30
|
}
|
data/lib/uia/element.rb
CHANGED
data/lib/uia/finder.rb
CHANGED
@@ -31,7 +31,7 @@ module Uia
|
|
31
31
|
def find_child(parent, locator)
|
32
32
|
scope = (locator.delete(:scope) || :descendants).to_s.capitalize
|
33
33
|
|
34
|
-
valid_locators = [:title, :handle, :id, :name, :value, :control_type, :scope]
|
34
|
+
valid_locators = [:title, :handle, :id, :name, :value, :control_type, :pattern, :scope]
|
35
35
|
raise BadChildLocator, locator unless (locator.keys - valid_locators).empty?
|
36
36
|
|
37
37
|
case
|
@@ -41,10 +41,20 @@ module Uia
|
|
41
41
|
find_by_handle locator[:handle]
|
42
42
|
else
|
43
43
|
conditions = locator.collect {|k, v| Library.send("#{k}_condition", v) }
|
44
|
-
Library.
|
44
|
+
Library.find_first parent, scope, *conditions
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
def find_children(parent, locator)
|
49
|
+
scope = (locator.delete(:scope) || :descendants).to_s.capitalize
|
50
|
+
|
51
|
+
valid_locators = [:id, :name, :value, :control_type, :pattern, :scope]
|
52
|
+
raise BadChildLocator, locator unless (locator.keys - valid_locators).empty?
|
53
|
+
|
54
|
+
conditions = locator.collect {|k, v| Library.send("#{k}_condition", v) }
|
55
|
+
Library.find_all parent, scope, *conditions
|
56
|
+
end
|
57
|
+
|
48
58
|
private
|
49
59
|
def find_by_id(id)
|
50
60
|
find_by_property(:id, id)
|
data/lib/uia/library.rb
CHANGED
@@ -63,15 +63,21 @@ module Uia
|
|
63
63
|
attach_throwable_function :find_by_pid, :Element_FindByProcessId, [:int], ManagedElementStruct.by_ref, &element_or_nil
|
64
64
|
attach_throwable_function :find_by_handle, :Element_FindByHandle, [:int], ManagedElementStruct.by_ref, &element_or_nil
|
65
65
|
attach_function :Element_FindByRuntimeId, [:pointer, :int, :pointer, :int], ManagedElementStruct.by_ref
|
66
|
-
attach_function :
|
66
|
+
attach_function :FindFirst, [:pointer, :string, :pointer, :int, :int, :varargs], ManagedElementStruct.by_ref
|
67
|
+
attach_function :FindAll, [:pointer, :pointer, :string, :pointer, :int, :int, :varargs], :int
|
67
68
|
|
68
69
|
## conditions
|
69
70
|
attach_function :release_condition, :Condition_Release, [:pointer], :void
|
70
71
|
attach_function :id_condition, :Condition_Id, [:string], SearchCondition.by_ref
|
72
|
+
attach_function :Condition_Pattern, [:string, :pointer, :int], SearchCondition.by_ref
|
71
73
|
attach_function :name_condition, :Condition_Name, [:string], SearchCondition.by_ref
|
72
74
|
self.singleton_class.send(:alias_method, :value_condition, :name_condition)
|
73
75
|
attach_function :Condition_ControlType, [:int, :varargs], SearchCondition.by_ref
|
74
76
|
|
77
|
+
def self.pattern_condition(pattern)
|
78
|
+
can_throw(:Condition_Pattern, "Is#{pattern.to_camelized_s.delete(' ')}PatternAvailableProperty")
|
79
|
+
end
|
80
|
+
|
75
81
|
def self.control_type_condition(*control_types)
|
76
82
|
args = control_types.flatten.map(&:to_control_type_const).reduce([]) { |a, n| a << :int << n }
|
77
83
|
Condition_ControlType control_types.count, *args
|
@@ -156,15 +162,28 @@ module Uia
|
|
156
162
|
result
|
157
163
|
end
|
158
164
|
|
159
|
-
def self.
|
165
|
+
def self.find_first(element, scope, *args)
|
160
166
|
string_buffer = FFI::MemoryPointer.new :char, 1024
|
161
167
|
conditions = args.reduce([]) { |a, c| a << :pointer << c }
|
162
|
-
result =
|
168
|
+
result = FindFirst element, scope, string_buffer, 1024, args.count, *conditions
|
163
169
|
error_info = string_buffer.read_string
|
164
170
|
raise error_info unless error_info.empty?
|
165
171
|
Uia::Element.new(result) unless result.empty?
|
166
172
|
end
|
167
173
|
|
174
|
+
def self.find_all(element, scope, *args)
|
175
|
+
elements_pointer = FFI::MemoryPointer.new :pointer
|
176
|
+
string_buffer = FFI::MemoryPointer.new :char, 1024
|
177
|
+
conditions = args.reduce([]) { |a, c| a << :pointer << c }
|
178
|
+
result = FindAll element, elements_pointer, scope, string_buffer, 1024, args.count, *conditions
|
179
|
+
error_info = string_buffer.read_string
|
180
|
+
raise error_info unless error_info.empty?
|
181
|
+
result.times.collect do |which_element|
|
182
|
+
pointer = elements_pointer.read_pointer + which_element * ManagedElementStruct.size
|
183
|
+
Uia::Element.new(ManagedElementStruct.new(pointer))
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
168
187
|
rescue LoadError => e
|
169
188
|
raise LoadError, 'You must install the Visual Studio 2012 C++ Runtime Environment to use the Uia gem (http://www.microsoft.com/en-us/download/details.aspx?id=30679)'
|
170
189
|
end
|
data/lib/uia/patterns/table.rb
CHANGED
@@ -3,7 +3,7 @@ module Uia
|
|
3
3
|
module Table
|
4
4
|
module Row
|
5
5
|
def items
|
6
|
-
|
6
|
+
find_all(pattern: :table_item).each { |e| e.as :table_item }
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
@@ -20,7 +20,7 @@ module Uia
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def rows
|
23
|
-
|
23
|
+
find_all(control_type: :data_item).each { |e| e.extend Row }
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
data/lib/uia/version.rb
CHANGED
data/spec/uia/element_spec.rb
CHANGED
@@ -122,10 +122,15 @@ describe Uia::Element do
|
|
122
122
|
Then { element.find(control_type: [:custom, :semantic_zoom]).id == 'automatableMonthCalendar1' }
|
123
123
|
end
|
124
124
|
|
125
|
+
context 'pattern' do
|
126
|
+
Then { element.find(pattern: :range_value).id == 'numericUpDown1' }
|
127
|
+
end
|
128
|
+
|
125
129
|
context 'combinations' do
|
126
130
|
Then { element.find(control_type: :list, name: 'linkLabel1').id == 'FruitListBox' }
|
127
131
|
Then { element.find(control_type: :button, name: 'Forward', scope: :children) == nil }
|
128
|
-
Then { element.find(
|
132
|
+
Then { element.find(pattern: :invoke, name: 'About').id == 'aboutButton' }
|
133
|
+
Then { element.find(control_type: :custom, id: 'automatableMonthCalendar1').name == 'linkLabel1' }
|
129
134
|
Then { element.find(value: 'linkLabel1', id: 'automatableMonthCalendar1').control_type == :custom }
|
130
135
|
end
|
131
136
|
|
@@ -139,6 +144,14 @@ describe Uia::Element do
|
|
139
144
|
end
|
140
145
|
end
|
141
146
|
|
147
|
+
context '#find_all' do
|
148
|
+
Given(:list_box) { element.find(id: 'FruitListBox') }
|
149
|
+
|
150
|
+
Then { list_box.find_all(control_type: :list_item).map(&:name) == ['Apple', 'Orange', 'Mango'] }
|
151
|
+
Then { element.find_all(control_type: :tree_item, name: 'Parent Two').count == 1 }
|
152
|
+
Then { expect { element.find_all(handle: 123) }.to raise_error BadLocator }
|
153
|
+
end
|
154
|
+
|
142
155
|
context '#filter' do
|
143
156
|
context 'control_type' do
|
144
157
|
When(:buttons) { element.filter(control_type: :radio_button) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.2'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -255,7 +255,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
255
255
|
version: '0'
|
256
256
|
segments:
|
257
257
|
- 0
|
258
|
-
hash:
|
258
|
+
hash: 148459631
|
259
259
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
260
260
|
none: false
|
261
261
|
requirements:
|
@@ -264,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
264
264
|
version: '0'
|
265
265
|
segments:
|
266
266
|
- 0
|
267
|
-
hash:
|
267
|
+
hash: 148459631
|
268
268
|
requirements: []
|
269
269
|
rubyforge_project:
|
270
270
|
rubygems_version: 1.8.28
|