uia 0.1.3.1 → 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|