uia 0.2.1 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ === Version 0.3 /2014-05-06
2
+ * Enhancements
3
+ * added the ability to list more than one pattern to search for
4
+
1
5
  === Version 0.2.1 / 2014-04-30
2
6
  * Bug Fixes
3
7
  * fixes issue with using the :control_type condition with multiple types allowed (i.e. [:button, :list])
@@ -48,12 +48,12 @@ namespace UIA.Helper
48
48
  get { return _element.GetRuntimeId(); }
49
49
  }
50
50
 
51
- public virtual long[] BoundingRectangle
51
+ public virtual int[] BoundingRectangle
52
52
  {
53
53
  get
54
54
  {
55
55
  var r = _element.Current.BoundingRectangle;
56
- return new[] { (long)r.Left, (long)r.Top, (long)(r.Right - r.Left), (long)(r.Bottom - r.Top) };
56
+ return new[] { (int)r.Left, (int)r.Top, (int)(r.Right - r.Left), (int)(r.Bottom - r.Top) };
57
57
  }
58
58
  }
59
59
 
@@ -16,7 +16,7 @@ namespace UIA.Helper
16
16
 
17
17
  public static Point Center(this Rect rectangle)
18
18
  {
19
- if( rectangle == Rect.Empty )
19
+ if (rectangle == Rect.Empty)
20
20
  throw new Exception("No point could be found");
21
21
 
22
22
  return new Point(rectangle.Left + rectangle.Width / 2, rectangle.Top + rectangle.Height / 2);
@@ -34,6 +34,16 @@ namespace UIA.Helper
34
34
  {
35
35
  return new PropertyCondition(AutomationElement.NameProperty, name);
36
36
  }
37
+
38
+ public static int PropertyId(this string propertyName)
39
+ {
40
+ var automationField = typeof(AutomationElement).GetField(propertyName);
41
+
42
+ if (null == automationField)
43
+ throw new ArgumentException(string.Format("{0} is not a valid AutomationProperty", propertyName));
44
+
45
+ return ((AutomationProperty)automationField.GetValue(null)).Id;
46
+ }
37
47
  }
38
48
 
39
49
  public static class ElementExtensions
@@ -49,7 +59,8 @@ namespace UIA.Helper
49
59
  Thread.Sleep(100);
50
60
  }
51
61
  return automationElement.Current.HasKeyboardFocus;
52
- } catch { return false; }
62
+ }
63
+ catch { return false; }
53
64
  }
54
65
 
55
66
  public static bool ScrollToIfPossible(this AutomationElement automationElement)
@@ -51,9 +51,9 @@ public:
51
51
  array<int>^ get() override { return _runtimeIds; }
52
52
  }
53
53
 
54
- virtual property array<long long>^ BoundingRectangle
54
+ virtual property array<int>^ BoundingRectangle
55
55
  {
56
- array<long long>^ get() override { return gcnew array<long long> {0, 0, 0, 0}; }
56
+ array<int>^ get() override { return gcnew array<int> {0, 0, 0, 0}; }
57
57
  }
58
58
 
59
59
  virtual property int NativeWindowHandle
@@ -1,26 +1,26 @@
1
1
  #include "stdafx.h"
2
- #include <ElementStructures.h>
2
+ #include <SearchCondition.h>
3
3
 
4
- TEST(Conditions_HaveIds)
4
+ TEST(Conditions, HaveIds)
5
5
  {
6
6
  auto condition = SearchCondition(123, 0);
7
7
  ASSERT_EQ(123, condition.propertyId);
8
8
  }
9
9
 
10
- TEST(Conditions_CanBeNumbers)
10
+ TEST(Conditions, CanBeNumbers)
11
11
  {
12
12
  auto condition = SearchCondition(0, 456);
13
13
  ASSERT_EQ(456, condition.number);
14
14
  }
15
15
 
16
- TEST(Conditions_CanBeStrings)
16
+ TEST(Conditions, CanBeStrings)
17
17
  {
18
18
  auto condition = SearchCondition(0, "expected value");
19
19
  ASSERT_STREQ("expected value", condition.string);
20
20
  ASSERT_TRUE(condition.IsString());
21
21
  }
22
22
 
23
- TEST(Conditions_CanHaveMultipleNumbers)
23
+ TEST(Conditions, CanHaveMultipleNumbers)
24
24
  {
25
25
  list<const int> numbers;
26
26
  numbers.push_back(7);
@@ -32,3 +32,16 @@ TEST(Conditions_CanHaveMultipleNumbers)
32
32
  ASSERT_EQ(6, condition.numbers[1]);
33
33
  ASSERT_TRUE(condition.HasNumbers());
34
34
  }
35
+
36
+ TEST(Conditions, CanBePatterns)
37
+ {
38
+ list<const int> patterns;
39
+ patterns.push_back(123);
40
+ patterns.push_back(456);
41
+
42
+ auto condition = SearchCondition(patterns);
43
+ ASSERT_EQ(2, condition.patternsCount);
44
+ ASSERT_EQ(123, condition.patterns[0]);
45
+ ASSERT_EQ(456, condition.patterns[1]);
46
+ ASSERT_TRUE(condition.IsPattern());
47
+ }
@@ -4,4 +4,4 @@
4
4
  #include <gmock\gmock.h>
5
5
 
6
6
  using namespace System;
7
- using namespace UIA::Helper;
7
+ using namespace UIA::Helper;
@@ -1,6 +1,7 @@
1
1
  #pragma once
2
- #include "ElementStructures.h"
2
+ #include "SearchCondition.h"
3
3
  #include <list>
4
+ #include <functional>
4
5
 
5
6
  using namespace System::Collections::Generic;
6
7
  using namespace std;
@@ -27,11 +28,11 @@ public:
27
28
  Object^ value = nullptr;
28
29
 
29
30
  if(automationProperty == AutomationElement::ControlTypeProperty) {
30
- return ControlTypeConditions(searchCondition->numbers, searchCondition->numbersCount);
31
+ return Or(searchCondition->numbers, searchCondition->numbersCount, ControlType);
31
32
  } else if(searchCondition->IsString()) {
32
33
  value = gcnew String(searchCondition->string);
33
- } else if(searchCondition->IsPatternAvailableProperty()) {
34
- value = true;
34
+ } else if(searchCondition->IsPattern()) {
35
+ return Or(searchCondition->patterns, searchCondition->patternsCount, Pattern);
35
36
  } else {
36
37
  value = searchCondition->number;
37
38
  }
@@ -40,14 +41,14 @@ public:
40
41
  }
41
42
 
42
43
  private:
43
- static Condition^ ControlTypeConditions(const int* controlTypeIds, const int controlTypes) {
44
- if(controlTypes == 1) {
45
- return ControlType(controlTypeIds[0]);
44
+ static Condition^ Or(const int* ids, const int count, std::function<Condition^(int)> conditionFor) {
45
+ if( count == 1 ) {
46
+ return conditionFor(ids[0]);
46
47
  }
47
48
 
48
49
  auto conditions = gcnew List<Condition^>();
49
- for(auto index = 0; index < controlTypes; ++index) {
50
- conditions->Add(ControlType(controlTypeIds[index]));
50
+ for(auto index = 0; index < count; ++index) {
51
+ conditions->Add(conditionFor(ids[index]));
51
52
  }
52
53
 
53
54
  return gcnew OrCondition(conditions->ToArray());
@@ -56,4 +57,8 @@ private:
56
57
  static Condition^ ControlType(const int id) {
57
58
  return gcnew PropertyCondition(AutomationElement::ControlTypeProperty, ControlType::LookupById(id));
58
59
  }
60
+
61
+ static Condition^ Pattern(const int patternId) {
62
+ return gcnew PropertyCondition(AutomationProperty::LookupById(patternId), true);
63
+ }
59
64
  };
@@ -15,27 +15,32 @@ 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) {
18
+ SearchConditionPtr ManagedBuildPatternCondition(list<const char*>& patterns, char* errorInfo, const int errorInfoLength) {
19
19
  try {
20
- auto patternPropertyId = dynamic_cast<AutomationProperty^>(AutomationElement::typeid->GetField(gcnew String(pattern))->GetValue(nullptr))->Id;
21
- return new SearchCondition(patternPropertyId, true);
20
+ list<const int> patternIds;
21
+
22
+ for(auto pattern = patterns.begin(); pattern != patterns.end(); ++pattern) {
23
+ patternIds.push_back(PropertyExtensions::PropertyId(gcnew String(*pattern)));
24
+ }
25
+
26
+ return new SearchCondition(patternIds);
22
27
  } catch(Exception^ e) {
23
- StringHelper::CopyToUnmanagedString(String::Format("{0} is an invalid AutomationProperty", gcnew String(pattern)), errorInfo, errorInfoLength);
28
+ StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
24
29
  return NULL;
25
30
  }
26
31
  }
27
32
 
28
- __declspec(dllexport) SearchConditionPtr Condition_ControlType(const int n, const int arg0, ...) {
29
- va_list arguments;
30
- va_start(arguments, arg0);
31
-
32
- list<const int> controlTypes;
33
- controlTypes.push_back(arg0);
34
- for(auto index = 1; index < n; index++) {
35
- auto value = va_arg(arguments, int);
36
- controlTypes.push_back(value);
37
- }
33
+ #pragma managed(push, off)
34
+ __declspec(dllexport) SearchConditionPtr Condition_Pattern(char* errorInfo, const int errorInfoLength, const int n, const char* arg0, ...) {
35
+ GRAB_VARARGS(patterns, const char*, n);
36
+ return ManagedBuildPatternCondition(patterns, errorInfo, errorInfoLength);
37
+ }
38
+ #pragma managed(pop)
38
39
 
40
+ #pragma managed(push, off)
41
+ __declspec(dllexport) SearchConditionPtr Condition_ControlType(const int n, const int arg0, ...) {
42
+ GRAB_VARARGS(controlTypes, const int, n);
39
43
  return SearchCondition::FromControlTypes(controlTypes);
40
44
  }
45
+ #pragma managed(pop)
41
46
  }
@@ -42,18 +42,12 @@ extern "C" {
42
42
  return NULL;
43
43
  }
44
44
 
45
+ #pragma managed(push, off)
45
46
  __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
-
47
+ GRAB_VARARGS(conditions, SearchConditionPtr, count);
55
48
  return ManagedFindFirst(element, treeScope, conditions, errorInfo, errorInfoLength);
56
49
  }
50
+ #pragma managed(pop)
57
51
 
58
52
  int ManagedFindAll(ElementInformationPtr element, ElementInformation** elements, const char* treeScope, list<SearchConditionPtr>& conditions, char* errorInfo, const int errorInfoLength) {
59
53
  try {
@@ -68,18 +62,12 @@ extern "C" {
68
62
  return 0;
69
63
  }
70
64
 
65
+ #pragma managed(push, off)
71
66
  __declspec(dllexport) int FindAll(ElementInformationPtr parent, ElementInformation** elements, const char* treeScope, char* errorInfo, const int errorInfoLength, const int count, SearchConditionPtr arg0, ...) {
72
- va_list arguments;
73
- va_start(arguments, arg0);
74
-
75
- list<SearchConditionPtr> conditions;
76
- conditions.push_back(arg0);
77
- for(auto index = 1; index < count; index++) {
78
- conditions.push_back(va_arg(arguments, SearchConditionPtr));
79
- }
80
-
67
+ GRAB_VARARGS(conditions, SearchConditionPtr, count);
81
68
  return ManagedFindAll(parent, elements, treeScope, conditions, errorInfo, errorInfoLength);
82
69
  }
70
+ #pragma managed(pop)
83
71
 
84
72
  __declspec(dllexport) ElementInformationPtr Element_FindById(const char* automationId, char* errorInfo, const int errorLength) {
85
73
  try {
@@ -2,81 +2,6 @@
2
2
  #include "ArrayHelper.h"
3
3
  #include "StringHelper.h"
4
4
 
5
- #include <list>
6
- using namespace std;
7
-
8
- typedef struct _SearchCondition {
9
- int propertyId;
10
-
11
- int number;
12
- char* string;
13
- int* numbers;
14
- int numbersCount;
15
-
16
- _SearchCondition(const int id) : string(NULL), numbers(NULL) {
17
- Reset(id);
18
- }
19
-
20
- _SearchCondition(const int id, const char* s) : string(NULL), numbers(NULL) {
21
- Reset(id);
22
-
23
- auto length = strnlen_s(s, 10000);
24
- auto size = length + 1;
25
- this->string = new char[size];
26
- strcpy_s(this->string, size, s);
27
- }
28
-
29
- _SearchCondition(const int id, const int number) : string(NULL), numbers(NULL) {
30
- Reset(id);
31
- this->number = number;
32
- }
33
-
34
- _SearchCondition(const int id, list<const int>& numbers) : string(NULL), numbers(NULL) {
35
- Reset(id);
36
- numbersCount = numbers.size();
37
- this->numbers = new int[numbersCount];
38
-
39
- int index = 0;
40
- for(std::list<const int>::iterator number = numbers.begin(); number != numbers.end(); ++number, ++index) {
41
- this->numbers[index] = *number;
42
- }
43
- }
44
-
45
- bool HasNumbers() {
46
- return NULL != numbers;
47
- }
48
-
49
- bool IsString() {
50
- return NULL != string;
51
- }
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
-
63
- static _SearchCondition* FromControlTypes(list<const int>& controlTypes) {
64
- return new SearchCondition(System::Windows::Automation::AutomationElement::ControlTypeProperty->Id, controlTypes);
65
- }
66
-
67
- void Reset(const int id) {
68
- propertyId = id;
69
- delete[] string; delete[] numbers;
70
- string = NULL; numbers = NULL;
71
- number = 0; numbersCount = 0;
72
- }
73
-
74
- ~_SearchCondition() {
75
- Reset(propertyId);
76
- }
77
-
78
- } SearchCondition, *SearchConditionPtr;
79
-
80
5
  typedef struct _ElementInformation {
81
6
  int nativeWindowHandle;
82
7
  int* runtimeId;
@@ -0,0 +1,83 @@
1
+ #pragma once
2
+ #include <list>
3
+ using namespace std;
4
+
5
+ typedef struct _SearchCondition {
6
+ int propertyId;
7
+
8
+ int number;
9
+ char* string;
10
+ int* numbers;
11
+ int numbersCount;
12
+ int* patterns;
13
+ int patternsCount;
14
+
15
+ _SearchCondition(const int id) : string(NULL), numbers(NULL), patterns(NULL) {
16
+ Reset(id);
17
+ }
18
+
19
+ _SearchCondition(const int id, const char* s) : string(NULL), numbers(NULL), patterns(NULL) {
20
+ Reset(id);
21
+
22
+ auto length = strnlen_s(s, 10000);
23
+ auto size = length + 1;
24
+ this->string = new char[size];
25
+ strcpy_s(this->string, size, s);
26
+ }
27
+
28
+ _SearchCondition(const int id, const int number) : string(NULL), numbers(NULL), patterns(NULL) {
29
+ Reset(id);
30
+ this->number = number;
31
+ }
32
+
33
+ _SearchCondition(const int id, list<const int>& numbers) : string(NULL), numbers(NULL), patterns(NULL) {
34
+ Reset(id);
35
+ numbersCount = numbers.size();
36
+ this->numbers = new int[numbersCount];
37
+
38
+ int index = 0;
39
+ for(list<const int>::iterator number = numbers.begin(); number != numbers.end(); ++number, ++index) {
40
+ this->numbers[index] = *number;
41
+ }
42
+ }
43
+
44
+ _SearchCondition(list<const int>& patterns) : string(NULL), numbers(NULL), patterns(NULL) {
45
+ Reset(patterns.front());
46
+
47
+ patternsCount = patterns.size();
48
+ this->patterns = new int[patternsCount];
49
+
50
+ int index = 0;
51
+ for(std::list<const int>::iterator pattern = patterns.begin(); pattern != patterns.end(); ++pattern, ++index) {
52
+ this->patterns[index] = * pattern;
53
+ }
54
+ }
55
+
56
+ bool HasNumbers() {
57
+ return NULL != numbers;
58
+ }
59
+
60
+ bool IsString() {
61
+ return NULL != string;
62
+ }
63
+
64
+ bool IsPattern() {
65
+ return NULL != patterns;
66
+ }
67
+
68
+ static _SearchCondition* FromControlTypes(list<const int>& controlTypes) {
69
+ return new SearchCondition(System::Windows::Automation::AutomationElement::ControlTypeProperty->Id, controlTypes);
70
+ }
71
+
72
+ void Reset(const int id) {
73
+ propertyId = id;
74
+ delete[] string; delete[] numbers; delete[] patterns;
75
+ string = NULL; numbers = NULL;
76
+ number = 0; numbersCount = 0; patternsCount = 0;
77
+ }
78
+
79
+ ~_SearchCondition() {
80
+ Reset(propertyId);
81
+ }
82
+
83
+ } SearchCondition, *SearchConditionPtr;
@@ -13,6 +13,17 @@ using namespace UIA::Helper;
13
13
  #include "ArrayHelper.h"
14
14
  #include "ElementStructures.h"
15
15
  #include "PatternInformationStructures.h"
16
+ #include "SearchCondition.h"
16
17
  #include <list>
17
18
 
18
- extern "C" Element^ ElementFrom(ElementInformationPtr element);
19
+ extern "C" Element^ ElementFrom(ElementInformationPtr element);
20
+
21
+ #define GRAB_VARARGS(argument_list, arg_type, arg_count) \
22
+ va_list arguments;\
23
+ va_start(arguments, arg0);\
24
+ list<##arg_type##> ##argument_list##;\
25
+ ##argument_list##.push_back(arg0);\
26
+ for(auto index = 1; index < ##arg_count##; ++index) {\
27
+ auto value = va_arg(arguments, ##arg_type##);\
28
+ ##argument_list##.push_back(value);\
29
+ }
@@ -84,6 +84,7 @@
84
84
  <ClInclude Include="DynamicAssemblyResolver.h" />
85
85
  <ClInclude Include="ElementStructures.h" />
86
86
  <ClInclude Include="PatternInformationStructures.h" />
87
+ <ClInclude Include="SearchCondition.h" />
87
88
  <ClInclude Include="Stdafx.h" />
88
89
  <ClInclude Include="StringHelper.h" />
89
90
  </ItemGroup>
@@ -39,6 +39,9 @@
39
39
  <ClInclude Include="ConditionHelper.h">
40
40
  <Filter>Header Files</Filter>
41
41
  </ClInclude>
42
+ <ClInclude Include="SearchCondition.h">
43
+ <Filter>Header Files</Filter>
44
+ </ClInclude>
42
45
  </ItemGroup>
43
46
  <ItemGroup>
44
47
  <ClCompile Include="UiaDll.cpp">
@@ -0,0 +1,5 @@
1
+ class Array
2
+ def to_var_args(type)
3
+ self.flatten.reduce([]) { |a, n| a << type << n }
4
+ end
5
+ end
@@ -3,6 +3,10 @@ class Symbol
3
3
  self.to_s.split('_').map(&:capitalize).join(' ')
4
4
  end
5
5
 
6
+ def to_pattern_available_property
7
+ "Is#{self.to_camelized_s.delete(' ')}PatternAvailableProperty"
8
+ end
9
+
6
10
  # :selection_item => Uia::Patterns::SelectionItem
7
11
  def to_pattern_const
8
12
  "Uia::Patterns::#{self.to_s.capitalize}".split('::').reduce(Object) do |m, current|
@@ -69,18 +69,23 @@ module Uia
69
69
  ## conditions
70
70
  attach_function :release_condition, :Condition_Release, [:pointer], :void
71
71
  attach_function :id_condition, :Condition_Id, [:string], SearchCondition.by_ref
72
- attach_function :Condition_Pattern, [:string, :pointer, :int], SearchCondition.by_ref
72
+ attach_function :Condition_Pattern, [:pointer, :int, :int, :varargs], SearchCondition.by_ref
73
73
  attach_function :name_condition, :Condition_Name, [:string], SearchCondition.by_ref
74
74
  self.singleton_class.send(:alias_method, :value_condition, :name_condition)
75
75
  attach_function :Condition_ControlType, [:int, :varargs], SearchCondition.by_ref
76
76
 
77
- def self.pattern_condition(pattern)
78
- can_throw(:Condition_Pattern, "Is#{pattern.to_camelized_s.delete(' ')}PatternAvailableProperty")
77
+ def self.pattern_condition(*patterns)
78
+ string_buffer = FFI::MemoryPointer.new :char, 1024
79
+ pattern_strings = patterns.flatten.map(&:to_pattern_available_property)
80
+ result = Condition_Pattern string_buffer, 1024, pattern_strings.count, *pattern_strings.to_var_args(:string)
81
+ error_info = string_buffer.read_string
82
+ raise error_info unless error_info.empty?
83
+ result
79
84
  end
80
85
 
81
86
  def self.control_type_condition(*control_types)
82
- args = control_types.flatten.map(&:to_control_type_const).reduce([]) { |a, n| a << :int << n }
83
- Condition_ControlType args.count, *args
87
+ control_type_ids = control_types.flatten.map(&:to_control_type_const)
88
+ Condition_ControlType control_type_ids.count, *control_type_ids.to_var_args(:int)
84
89
  end
85
90
 
86
91
  # element methods
@@ -162,20 +167,18 @@ module Uia
162
167
  result
163
168
  end
164
169
 
165
- def self.find_first(element, scope, *args)
170
+ def self.find_first(element, scope, *conditions)
166
171
  string_buffer = FFI::MemoryPointer.new :char, 1024
167
- conditions = args.reduce([]) { |a, c| a << :pointer << c }
168
- result = FindFirst element, scope, string_buffer, 1024, args.count, *conditions
172
+ result = FindFirst element, scope, string_buffer, 1024, conditions.count, *conditions.to_var_args(:pointer)
169
173
  error_info = string_buffer.read_string
170
174
  raise error_info unless error_info.empty?
171
175
  Uia::Element.new(result) unless result.empty?
172
176
  end
173
177
 
174
- def self.find_all(element, scope, *args)
178
+ def self.find_all(element, scope, *conditions)
175
179
  elements_pointer = FFI::MemoryPointer.new :pointer
176
180
  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
181
+ result = FindAll element, elements_pointer, scope, string_buffer, 1024, conditions.count, *conditions.to_var_args(:pointer)
179
182
  error_info = string_buffer.read_string
180
183
  raise error_info unless error_info.empty?
181
184
  result.times.collect do |which_element|
@@ -1,3 +1,3 @@
1
1
  module Uia
2
- VERSION = '0.2.1'
2
+ VERSION = '0.3'
3
3
  end
@@ -124,6 +124,8 @@ describe Uia::Element do
124
124
 
125
125
  context 'pattern' do
126
126
  Then { element.find(pattern: :range_value).id == 'numericUpDown1' }
127
+ Then { element.find(pattern: [:selection_item, :range_value]).id == 'numericUpDown1' }
128
+ Then { expect { element.find(pattern: [:not_valid, :range_value]) }.to raise_error RuntimeError, 'IsNotValidPatternAvailableProperty is not a valid AutomationProperty' }
127
129
  end
128
130
 
129
131
  context 'combinations' do
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.2.1
4
+ version: '0.3'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-30 00:00:00.000000000 Z
12
+ date: 2014-05-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
@@ -176,6 +176,7 @@ files:
176
176
  - ext/UiaDll/UiaDll/PatternInformationStructures.h
177
177
  - ext/UiaDll/UiaDll/RangeValueMethods.cpp
178
178
  - ext/UiaDll/UiaDll/ReadMe.txt
179
+ - ext/UiaDll/UiaDll/SearchCondition.h
179
180
  - ext/UiaDll/UiaDll/SelectionItemMethods.cpp
180
181
  - ext/UiaDll/UiaDll/SelectionMethods.cpp
181
182
  - ext/UiaDll/UiaDll/Stdafx.cpp
@@ -192,6 +193,7 @@ files:
192
193
  - ext/UiaDll/UiaDll/ValuePatternMethods.cpp
193
194
  - ext/UiaDll/UiaDll/WindowMethods.cpp
194
195
  - ext/UiaDll/UiaDll/app.rc
196
+ - lib/core_ext/array.rb
195
197
  - lib/core_ext/string.rb
196
198
  - lib/core_ext/symbol.rb
197
199
  - lib/uia.rb
@@ -255,7 +257,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
255
257
  version: '0'
256
258
  segments:
257
259
  - 0
258
- hash: -475586851
260
+ hash: 914295965
259
261
  required_rubygems_version: !ruby/object:Gem::Requirement
260
262
  none: false
261
263
  requirements:
@@ -264,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
266
  version: '0'
265
267
  segments:
266
268
  - 0
267
- hash: -475586851
269
+ hash: 914295965
268
270
  requirements: []
269
271
  rubyforge_project:
270
272
  rubygems_version: 1.8.28