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 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 static Element From(AutomationElement element)
130
+ public Element[] Find(TreeScope scope, Condition condition)
126
131
  {
127
- return null == element ? null : new Element(element);
132
+ return Find(_element, scope, condition);
128
133
  }
129
134
 
130
- public static Element[] From(AutomationElement[] elements)
135
+ public Element FindFirst(TreeScope scope, Condition condition)
131
136
  {
132
- return elements.Select(x => new Element(x)).ToArray();
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^ Find(ElementInformationPtr 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
- return Element::ByRuntimeId(ArrayHelper::ToArray(element->runtimeId, element->runtimeIdLength));
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(Find(element));
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
- Find(element)->SendKeys(gcnew String(keysToSend));
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 ManagedFindByConditions(ElementInformationPtr element, const char* treeScope, list<SearchConditionPtr>& conditions, char* errorInfo, const int errorInfoLength) {
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(Find(element)->ChildWith(scope, ConditionHelper::ConditionFrom(conditions)));
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 FindByConditions(ElementInformationPtr element, const char* treeScope, char* errorInfo, const int errorInfoLength, const int count, SearchConditionPtr arg0, ...) {
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 ManagedFindByConditions(element, treeScope, conditions, errorInfo, errorInfoLength);
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 = Find(parentElement)->Children;
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 = Find(parentElement)->Descendants;
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
- Find(element)->ClickClickablePoint();
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
- Find(element)->ClickCenter();
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
- Find(element)->SetFocus();
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 = Find(element)->As<ExpandCollapsePattern^>(ExpandCollapsePattern::Pattern)->Current;
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
- Find(element)->As<ExpandCollapsePattern^>(ExpandCollapsePattern::Pattern)->Expand();
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
- Find(element)->As<ExpandCollapsePattern^>(ExpandCollapsePattern::Pattern)->Collapse();
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
- Find(element)->As<InvokePattern^>(InvokePattern::Pattern)->Invoke();
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(Find(element)->As<RangeValuePattern^>(RangeValuePattern::Pattern)->Current);
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 Find(element)->As<RangeValuePattern^>(RangeValuePattern::Pattern)->SetValue(value);
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 = Find(element)->As<SelectionItemPattern^>(SelectionItemPattern::Pattern)->Current;
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
- Find(element)->As<SelectionItemPattern^>(SelectionItemPattern::Pattern)->Select();
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
- Find(element)->As<SelectionItemPattern^>(SelectionItemPattern::Pattern)->AddToSelection();
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
- Find(element)->As<SelectionItemPattern^>(SelectionItemPattern::Pattern)->RemoveFromSelection();
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(Find(element)->As<SelectionPattern^>(SelectionPattern::Pattern)->Current);
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(Find(element)->As<SelectionPattern^>(SelectionPattern::Pattern)->Current.GetSelection());
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) {
@@ -15,4 +15,4 @@ using namespace UIA::Helper;
15
15
  #include "PatternInformationStructures.h"
16
16
  #include <list>
17
17
 
18
- extern "C" Element^ Find(ElementInformationPtr element);
18
+ extern "C" Element^ ElementFrom(ElementInformationPtr element);
@@ -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(Find(element)->As<TableItemPattern^>(TableItemPattern::Pattern)->Current);
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(Find(element)->As<TablePattern^>(TablePattern::Pattern)->Current);
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 = Find(element)->As<TablePattern^>(TablePattern::Pattern)->Current.GetColumnHeaders();
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 = Find(element)->As<TextPattern^>(TextPattern::Pattern)->DocumentRange->GetText(-1);
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 = Find(element)->As<TogglePattern^>(TogglePattern::Pattern)->Current;
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
- Find(element)->As<TogglePattern^>(TogglePattern::Pattern)->Toggle();
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
- Find(element)->As<ValuePattern^>(ValuePattern::Pattern)->SetValue(gcnew String(value));
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 = Find(element)->As<ValuePattern^>(ValuePattern::Pattern);
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(Find(element)->As<WindowPattern^>(WindowPattern::Pattern)->Current);
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
- Find(element)->As<WindowPattern^>(WindowPattern::Pattern)->SetWindowVisualState((WindowVisualState) Enum::Parse(WindowVisualState::typeid, gcnew String(visualState), false));
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
- Find(element)->As<WindowPattern^>(WindowPattern::Pattern)->Close();
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
@@ -57,6 +57,10 @@ module Uia
57
57
  find_child(@element, locator)
58
58
  end
59
59
 
60
+ def find_all(locator)
61
+ find_children(@element, locator)
62
+ end
63
+
60
64
  def locators_match?(locator)
61
65
  locator.all? do |locator, value|
62
66
  case locator
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.find_by_conditions parent, scope, *conditions
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 :FindByConditions, [:pointer, :string, :pointer, :int, :int, :varargs], ManagedElementStruct.by_ref
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.find_by_conditions(element, scope, *args)
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 = FindByConditions element, scope, string_buffer, 1024, args.count, *conditions
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
@@ -2,7 +2,7 @@ module Uia
2
2
  module Patterns
3
3
  module Selection
4
4
  def selection_items
5
- filter(pattern: :selection_item).map {|e| e.as :selection_item }
5
+ find_all(pattern: :selection_item).map {|e| e.as :selection_item }
6
6
  end
7
7
 
8
8
  def selected_items
@@ -3,7 +3,7 @@ module Uia
3
3
  module Table
4
4
  module Row
5
5
  def items
6
- filter(pattern: :table_item).each { |e| e.as :table_item }
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
- filter(control_type: :data_item).each { |e| e.extend Row }
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
@@ -1,3 +1,3 @@
1
1
  module Uia
2
- VERSION = '0.1.3.1'
2
+ VERSION = '0.2'
3
3
  end
@@ -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(control_type: :custom, id: 'automatableMonthCalendar1').name == 'linkLabel1'}
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.1.3.1
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: -143354925
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: -143354925
267
+ hash: 148459631
268
268
  requirements: []
269
269
  rubyforge_project:
270
270
  rubygems_version: 1.8.28