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 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