uia 0.2.1 → 0.3
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 +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
|