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 +4 -0
- data/ext/UiaDll/UIA.Helper/Element.cs +2 -2
- data/ext/UiaDll/UIA.Helper/Extensions.cs +13 -2
- data/ext/UiaDll/UiaDll.Test/ElementStub.h +2 -2
- data/ext/UiaDll/UiaDll.Test/SearchConditionTest.cpp +18 -5
- data/ext/UiaDll/UiaDll.Test/stdafx.h +1 -1
- data/ext/UiaDll/UiaDll/ConditionHelper.h +14 -9
- data/ext/UiaDll/UiaDll/ConditionMethods.cpp +19 -14
- data/ext/UiaDll/UiaDll/ElementMethods.cpp +6 -18
- data/ext/UiaDll/UiaDll/ElementStructures.h +0 -75
- data/ext/UiaDll/UiaDll/SearchCondition.h +83 -0
- data/ext/UiaDll/UiaDll/Stdafx.h +12 -1
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj +1 -0
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +3 -0
- data/lib/core_ext/array.rb +5 -0
- data/lib/core_ext/symbol.rb +4 -0
- data/lib/uia/library.rb +14 -11
- data/lib/uia/version.rb +1 -1
- data/spec/uia/element_spec.rb +2 -0
- metadata +6 -4
data/ChangeLog
CHANGED
@@ -48,12 +48,12 @@ namespace UIA.Helper
|
|
48
48
|
get { return _element.GetRuntimeId(); }
|
49
49
|
}
|
50
50
|
|
51
|
-
public virtual
|
51
|
+
public virtual int[] BoundingRectangle
|
52
52
|
{
|
53
53
|
get
|
54
54
|
{
|
55
55
|
var r = _element.Current.BoundingRectangle;
|
56
|
-
return new[] { (
|
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(
|
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
|
-
}
|
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<
|
54
|
+
virtual property array<int>^ BoundingRectangle
|
55
55
|
{
|
56
|
-
array<
|
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 <
|
2
|
+
#include <SearchCondition.h>
|
3
3
|
|
4
|
-
TEST(
|
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(
|
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(
|
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(
|
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
|
+
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#pragma once
|
2
|
-
#include "
|
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
|
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->
|
34
|
-
|
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^
|
44
|
-
if(
|
45
|
-
return
|
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 <
|
50
|
-
conditions->Add(
|
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
|
-
|
18
|
+
SearchConditionPtr ManagedBuildPatternCondition(list<const char*>& patterns, char* errorInfo, const int errorInfoLength) {
|
19
19
|
try {
|
20
|
-
|
21
|
-
|
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(
|
28
|
+
StringHelper::CopyToUnmanagedString(e->Message, errorInfo, errorInfoLength);
|
24
29
|
return NULL;
|
25
30
|
}
|
26
31
|
}
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
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
|
-
|
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;
|
data/ext/UiaDll/UiaDll/Stdafx.h
CHANGED
@@ -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>
|
data/lib/core_ext/symbol.rb
CHANGED
@@ -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|
|
data/lib/uia/library.rb
CHANGED
@@ -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, [:
|
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(
|
78
|
-
|
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
|
-
|
83
|
-
Condition_ControlType
|
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, *
|
170
|
+
def self.find_first(element, scope, *conditions)
|
166
171
|
string_buffer = FFI::MemoryPointer.new :char, 1024
|
167
|
-
|
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, *
|
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
|
-
|
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|
|
data/lib/uia/version.rb
CHANGED
data/spec/uia/element_spec.rb
CHANGED
@@ -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.
|
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-
|
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:
|
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:
|
269
|
+
hash: 914295965
|
268
270
|
requirements: []
|
269
271
|
rubyforge_project:
|
270
272
|
rubygems_version: 1.8.28
|