uia 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,73 @@
1
+ #include "Stdafx.h"
2
+
3
+ using namespace UIA::Helper;
4
+
5
+ extern "C" {
6
+ Element^ Find(PElementInformation element) {
7
+ if( element->nativeWindowHandle > 0 ) {
8
+ return Element::ByHandle(IntPtr(element->nativeWindowHandle));
9
+ }
10
+
11
+ return Element::ByRuntimeId(ArrayHelper::ToArray(element->runtimeId, element->runtimeIdLength));
12
+ }
13
+
14
+ __declspec(dllexport) void Element_Release(PElementInformation elementInformation) {
15
+ delete elementInformation;
16
+ }
17
+
18
+ __declspec(dllexport) void Element_ReleaseMany(PElements elements) {
19
+ delete elements;
20
+ }
21
+
22
+ __declspec(dllexport) PElementInformation Element_FindById(const char* automationId, char* errorInfo, const int errorLength) {
23
+ try {
24
+ return new ElementInformation(Element::ById(gcnew String(automationId)));
25
+ } catch(Exception^ error) {
26
+ StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
27
+ }
28
+
29
+ return NULL;
30
+ }
31
+
32
+ __declspec(dllexport) PElementInformation Element_FindByHandle(HWND windowHandle, char* errorInfo, const int errorLength) {
33
+ try {
34
+ return new ElementInformation(Element::ByHandle(IntPtr(windowHandle)));
35
+ } catch(Exception^ error) {
36
+ StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
37
+ }
38
+
39
+ return NULL;
40
+ }
41
+
42
+ __declspec(dllexport) PElementInformation Element_FindByRuntimeId(const int runtimeIds[], const int numberOfIds, char* errorInfo, const int errorLength) {
43
+ try {
44
+ return new ElementInformation(Element::ByRuntimeId(ArrayHelper::ToArray(runtimeIds, numberOfIds)));
45
+ } catch(Exception^ error) {
46
+ StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
47
+ }
48
+ }
49
+
50
+ __declspec(dllexport) PElements Element_Children(PElementInformation parentElement, char* errorInfo, const int errorLength) {
51
+ try {
52
+ return new Elements(Find(parentElement)->Children);
53
+ } catch(Exception^ error) {
54
+ StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
55
+ }
56
+ }
57
+
58
+ __declspec(dllexport) PElements Element_ChildrenOfType(PElementInformation parent, int propertyId, char* errorInfo, const int errorLength) {
59
+ try {
60
+ return new Elements(Find(parent)->ChildrenOf((AutomationProperty::Id)propertyId));
61
+ } catch(Exception^ error) {
62
+ StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
63
+ }
64
+ }
65
+
66
+ __declspec(dllexport) void Element_Click(PElementInformation element, char* errorInfo, const int errorLength) {
67
+ try {
68
+ Find(element)->MouseClick();
69
+ } catch(Exception^ error) {
70
+ StringHelper::CopyToUnmanagedString(error->Message, errorInfo, errorLength);
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,52 @@
1
+ #include "Stdafx.h"
2
+
3
+ typedef struct _ElementInformation {
4
+ int nativeWindowHandle;
5
+ int* runtimeId;
6
+ int runtimeIdLength;
7
+ char* name;
8
+
9
+ _ElementInformation() : name(NULL), nativeWindowHandle(0) {}
10
+
11
+ _ElementInformation(Element^ element) : name(NULL), nativeWindowHandle(0) {
12
+ this->name = StringHelper::ToUnmanaged(element->Name);
13
+ this->nativeWindowHandle = element->NativeWindowHandle;
14
+ runtimeId = ArrayHelper::FromArray(element->RuntimeId);
15
+ runtimeIdLength = element->RuntimeId->Length;
16
+ }
17
+
18
+ ~_ElementInformation() {
19
+ if( NULL != name) {
20
+ delete[] name;
21
+ }
22
+ if( NULL != runtimeId ) {
23
+ delete[] runtimeId;
24
+ }
25
+ }
26
+
27
+ } ElementInformation, *PElementInformation;
28
+
29
+ typedef struct _Elements {
30
+ int length;
31
+ ElementInformation* elements;
32
+
33
+ _Elements(array<Element^>^ elements) {
34
+ length = elements->Length;
35
+ this->elements = NULL;
36
+ if( length > 0 ) {
37
+ this->elements = new ElementInformation[length];
38
+
39
+ auto index = 0;
40
+ for each(Element^ child in elements) {
41
+ auto element = new ElementInformation(child);
42
+ memcpy(&this->elements[index++], element, sizeof(ElementInformation));
43
+ }
44
+ }
45
+ }
46
+
47
+ ~_Elements() {
48
+ for(auto index = 0; index < length; ++index) {
49
+ elements[index].~_ElementInformation();
50
+ }
51
+ }
52
+ } Elements, *PElements;
@@ -0,0 +1,38 @@
1
+ ========================================================================
2
+ DYNAMIC LINK LIBRARY : UiaDll Project Overview
3
+ ========================================================================
4
+
5
+ AppWizard has created this UiaDll DLL for you.
6
+
7
+ This file contains a summary of what you will find in each of the files that
8
+ make up your UiaDll application.
9
+
10
+ UiaDll.vcxproj
11
+ This is the main project file for VC++ projects generated using an Application Wizard.
12
+ It contains information about the version of Visual C++ that generated the file, and
13
+ information about the platforms, configurations, and project features selected with the
14
+ Application Wizard.
15
+
16
+ UiaDll.vcxproj.filters
17
+ This is the filters file for VC++ projects generated using an Application Wizard.
18
+ It contains information about the association between the files in your project
19
+ and the filters. This association is used in the IDE to show grouping of files with
20
+ similar extensions under a specific node (for e.g. ".cpp" files are associated with the
21
+ "Source Files" filter).
22
+
23
+ UiaDll.cpp
24
+ This is the main DLL source file.
25
+
26
+ UiaDll.h
27
+ This file contains a class declaration.
28
+
29
+ AssemblyInfo.cpp
30
+ Contains custom attributes for modifying assembly metadata.
31
+
32
+ /////////////////////////////////////////////////////////////////////////////
33
+ Other notes:
34
+
35
+ AppWizard uses "TODO:" to indicate parts of the source code you
36
+ should add to or customize.
37
+
38
+ /////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,5 @@
1
+ // stdafx.cpp : source file that includes just the standard includes
2
+ // UiaDll.pch will be the pre-compiled header
3
+ // stdafx.obj will contain the pre-compiled type information
4
+
5
+ #include "stdafx.h"
@@ -0,0 +1,14 @@
1
+ // stdafx.h : include file for standard system include files,
2
+ // or project specific include files that are used frequently,
3
+ // but are changed infrequently
4
+
5
+ #pragma once
6
+
7
+ #include <Windows.h>
8
+
9
+ using namespace System;
10
+ using namespace UIA::Helper;
11
+
12
+ #include "StringHelper.h"
13
+ #include "ArrayHelper.h"
14
+ #include "ElementStructures.h"
@@ -0,0 +1,17 @@
1
+ #include "stdafx.h"
2
+ #include "StringHelper.h"
3
+
4
+ void StringHelper::CopyToUnmanagedString(String^ source, char* destination, const int destinationSize)
5
+ {
6
+ auto unmanagedString = Marshal::StringToHGlobalAnsi(source);
7
+ strncpy_s(destination, destinationSize, (const char*)(void*)unmanagedString, _TRUNCATE);
8
+ Marshal::FreeHGlobal(unmanagedString);
9
+ }
10
+
11
+ char* StringHelper::ToUnmanaged(String^ source)
12
+ {
13
+ const int numberOfBytes = source->Length + 1;
14
+ auto unmanagedString = new char[numberOfBytes];
15
+ CopyToUnmanagedString(source, unmanagedString, numberOfBytes);
16
+ return unmanagedString;
17
+ }
@@ -0,0 +1,11 @@
1
+ #pragma once
2
+
3
+ using namespace System::Runtime::InteropServices;
4
+
5
+ ref class StringHelper
6
+ {
7
+ public:
8
+ static void CopyToUnmanagedString(String^ source, char* destination, const int destinationSize);
9
+ static char* ToUnmanaged(String^ string);
10
+ };
11
+
@@ -0,0 +1,9 @@
1
+ #include "stdafx.h"
2
+ #include "DynamicAssemblyResolver.h"
3
+
4
+ extern "C" {
5
+ __declspec(dllexport) void initialize(char* privateAssemblyDirectory) {
6
+ DynamicAssemblyResolver::PrivatePath = gcnew String(privateAssemblyDirectory);
7
+ }
8
+ }
9
+
@@ -0,0 +1,13 @@
1
+ // UiaDll.h
2
+
3
+ #pragma once
4
+
5
+ using namespace System;
6
+
7
+ namespace UiaDll {
8
+
9
+ public ref class Class1
10
+ {
11
+ // TODO: Add your methods for this class here.
12
+ };
13
+ }
@@ -0,0 +1,105 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+ <ItemGroup Label="ProjectConfigurations">
4
+ <ProjectConfiguration Include="Debug|Win32">
5
+ <Configuration>Debug</Configuration>
6
+ <Platform>Win32</Platform>
7
+ </ProjectConfiguration>
8
+ <ProjectConfiguration Include="Release|Win32">
9
+ <Configuration>Release</Configuration>
10
+ <Platform>Win32</Platform>
11
+ </ProjectConfiguration>
12
+ </ItemGroup>
13
+ <PropertyGroup Label="Globals">
14
+ <ProjectGuid>{16531A20-39FB-4BDB-8F1C-E2D619BBCF58}</ProjectGuid>
15
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
16
+ <Keyword>ManagedCProj</Keyword>
17
+ <RootNamespace>UiaDll</RootNamespace>
18
+ </PropertyGroup>
19
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
20
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
21
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
22
+ <UseDebugLibraries>true</UseDebugLibraries>
23
+ <PlatformToolset>v110</PlatformToolset>
24
+ <CLRSupport>true</CLRSupport>
25
+ <CharacterSet>Unicode</CharacterSet>
26
+ </PropertyGroup>
27
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
28
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
29
+ <UseDebugLibraries>false</UseDebugLibraries>
30
+ <PlatformToolset>v110</PlatformToolset>
31
+ <CLRSupport>true</CLRSupport>
32
+ <CharacterSet>Unicode</CharacterSet>
33
+ </PropertyGroup>
34
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
35
+ <ImportGroup Label="ExtensionSettings">
36
+ </ImportGroup>
37
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
38
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
39
+ </ImportGroup>
40
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
41
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
42
+ </ImportGroup>
43
+ <PropertyGroup Label="UserMacros" />
44
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
45
+ <LinkIncremental>true</LinkIncremental>
46
+ </PropertyGroup>
47
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
48
+ <LinkIncremental>false</LinkIncremental>
49
+ </PropertyGroup>
50
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
51
+ <ClCompile>
52
+ <WarningLevel>Level3</WarningLevel>
53
+ <Optimization>Disabled</Optimization>
54
+ <PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
55
+ <PrecompiledHeader>Use</PrecompiledHeader>
56
+ </ClCompile>
57
+ <Link>
58
+ <GenerateDebugInformation>true</GenerateDebugInformation>
59
+ <AdditionalDependencies />
60
+ </Link>
61
+ </ItemDefinitionGroup>
62
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
63
+ <ClCompile>
64
+ <WarningLevel>Level3</WarningLevel>
65
+ <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
66
+ <PrecompiledHeader>Use</PrecompiledHeader>
67
+ </ClCompile>
68
+ <Link>
69
+ <GenerateDebugInformation>true</GenerateDebugInformation>
70
+ <AdditionalDependencies />
71
+ </Link>
72
+ </ItemDefinitionGroup>
73
+ <ItemGroup>
74
+ <Reference Include="System" />
75
+ <Reference Include="System.Data" />
76
+ <Reference Include="System.Xml" />
77
+ </ItemGroup>
78
+ <ItemGroup>
79
+ <ClInclude Include="ArrayHelper.h" />
80
+ <ClInclude Include="DynamicAssemblyResolver.h" />
81
+ <ClInclude Include="ElementStructures.h" />
82
+ <ClInclude Include="Stdafx.h" />
83
+ <ClInclude Include="StringHelper.h" />
84
+ </ItemGroup>
85
+ <ItemGroup>
86
+ <ClCompile Include="ArrayHelper.cpp" />
87
+ <ClCompile Include="AssemblyInfo.cpp" />
88
+ <ClCompile Include="DynamicAssemblyResolver.cpp" />
89
+ <ClCompile Include="ElementMethods.cpp" />
90
+ <ClCompile Include="Stdafx.cpp">
91
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
92
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
93
+ </ClCompile>
94
+ <ClCompile Include="StringHelper.cpp" />
95
+ <ClCompile Include="UiaDll.cpp" />
96
+ </ItemGroup>
97
+ <ItemGroup>
98
+ <ProjectReference Include="..\UIA.Helper\UIA.Helper.csproj">
99
+ <Project>{c2d567a8-b059-41a8-b9f5-ff4f8f961c1f}</Project>
100
+ </ProjectReference>
101
+ </ItemGroup>
102
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
103
+ <ImportGroup Label="ExtensionTargets">
104
+ </ImportGroup>
105
+ </Project>
@@ -0,0 +1,57 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+ <ItemGroup>
4
+ <Filter Include="Source Files">
5
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
6
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
7
+ </Filter>
8
+ <Filter Include="Header Files">
9
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
10
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
11
+ </Filter>
12
+ <Filter Include="Resource Files">
13
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
14
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
15
+ </Filter>
16
+ </ItemGroup>
17
+ <ItemGroup>
18
+ <ClInclude Include="Stdafx.h">
19
+ <Filter>Header Files</Filter>
20
+ </ClInclude>
21
+ <ClInclude Include="DynamicAssemblyResolver.h">
22
+ <Filter>Header Files</Filter>
23
+ </ClInclude>
24
+ <ClInclude Include="StringHelper.h">
25
+ <Filter>Header Files</Filter>
26
+ </ClInclude>
27
+ <ClInclude Include="ArrayHelper.h">
28
+ <Filter>Header Files</Filter>
29
+ </ClInclude>
30
+ <ClInclude Include="ElementStructures.h">
31
+ <Filter>Header Files</Filter>
32
+ </ClInclude>
33
+ </ItemGroup>
34
+ <ItemGroup>
35
+ <ClCompile Include="UiaDll.cpp">
36
+ <Filter>Source Files</Filter>
37
+ </ClCompile>
38
+ <ClCompile Include="AssemblyInfo.cpp">
39
+ <Filter>Source Files</Filter>
40
+ </ClCompile>
41
+ <ClCompile Include="Stdafx.cpp">
42
+ <Filter>Source Files</Filter>
43
+ </ClCompile>
44
+ <ClCompile Include="DynamicAssemblyResolver.cpp">
45
+ <Filter>Source Files</Filter>
46
+ </ClCompile>
47
+ <ClCompile Include="ElementMethods.cpp">
48
+ <Filter>Source Files</Filter>
49
+ </ClCompile>
50
+ <ClCompile Include="StringHelper.cpp">
51
+ <Filter>Source Files</Filter>
52
+ </ClCompile>
53
+ <ClCompile Include="ArrayHelper.cpp">
54
+ <Filter>Source Files</Filter>
55
+ </ClCompile>
56
+ </ItemGroup>
57
+ </Project>
Binary file
@@ -0,0 +1,42 @@
1
+ 
2
+ Microsoft Visual Studio Solution File, Format Version 12.00
3
+ # Visual Studio 2012
4
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UiaDll", "UiaDll\UiaDll.vcxproj", "{16531A20-39FB-4BDB-8F1C-E2D619BBCF58}"
5
+ EndProject
6
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIA.Helper", "UIA.Helper\UIA.Helper.csproj", "{C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}"
7
+ EndProject
8
+ Global
9
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
10
+ Debug|Any CPU = Debug|Any CPU
11
+ Debug|Mixed Platforms = Debug|Mixed Platforms
12
+ Debug|Win32 = Debug|Win32
13
+ Release|Any CPU = Release|Any CPU
14
+ Release|Mixed Platforms = Release|Mixed Platforms
15
+ Release|Win32 = Release|Win32
16
+ EndGlobalSection
17
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
18
+ {16531A20-39FB-4BDB-8F1C-E2D619BBCF58}.Debug|Any CPU.ActiveCfg = Debug|Win32
19
+ {16531A20-39FB-4BDB-8F1C-E2D619BBCF58}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
20
+ {16531A20-39FB-4BDB-8F1C-E2D619BBCF58}.Debug|Mixed Platforms.Build.0 = Debug|Win32
21
+ {16531A20-39FB-4BDB-8F1C-E2D619BBCF58}.Debug|Win32.ActiveCfg = Debug|Win32
22
+ {16531A20-39FB-4BDB-8F1C-E2D619BBCF58}.Debug|Win32.Build.0 = Debug|Win32
23
+ {16531A20-39FB-4BDB-8F1C-E2D619BBCF58}.Release|Any CPU.ActiveCfg = Release|Win32
24
+ {16531A20-39FB-4BDB-8F1C-E2D619BBCF58}.Release|Mixed Platforms.ActiveCfg = Release|Win32
25
+ {16531A20-39FB-4BDB-8F1C-E2D619BBCF58}.Release|Mixed Platforms.Build.0 = Release|Win32
26
+ {16531A20-39FB-4BDB-8F1C-E2D619BBCF58}.Release|Win32.ActiveCfg = Release|Win32
27
+ {16531A20-39FB-4BDB-8F1C-E2D619BBCF58}.Release|Win32.Build.0 = Release|Win32
28
+ {C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29
+ {C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
30
+ {C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
31
+ {C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
32
+ {C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}.Debug|Win32.ActiveCfg = Debug|Any CPU
33
+ {C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
34
+ {C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}.Release|Any CPU.Build.0 = Release|Any CPU
35
+ {C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
36
+ {C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
37
+ {C2D567A8-B059-41A8-B9F5-FF4F8F961C1F}.Release|Win32.ActiveCfg = Release|Any CPU
38
+ EndGlobalSection
39
+ GlobalSection(SolutionProperties) = preSolution
40
+ HideSolutionNode = FALSE
41
+ EndGlobalSection
42
+ EndGlobal
@@ -0,0 +1,3 @@
1
+ module Uia
2
+ VERSION = "0.0.4"
3
+ end
data/lib/uia.rb ADDED
@@ -0,0 +1,117 @@
1
+ require 'uia/version'
2
+ require 'ffi'
3
+
4
+ module Uia
5
+ extend FFI::Library
6
+
7
+ module ElementLayout
8
+ def self.included(base)
9
+ base.class_eval do
10
+ layout :handle, :int,
11
+ :runtime_id, :pointer,
12
+ :number_of_ids, :int,
13
+ :name, :string
14
+
15
+ def handle
16
+ self[:handle]
17
+ end
18
+
19
+ def runtime_id
20
+ self[:runtime_id].read_array_of_int(number_of_ids)
21
+ end
22
+
23
+ def number_of_ids
24
+ self[:number_of_ids]
25
+ end
26
+
27
+ def children(type=nil)
28
+ elements = (type && Uia.children_of_type(self, type)) || Uia.children(self)
29
+ elements.children
30
+ end
31
+
32
+ def name
33
+ self[:name]
34
+ end
35
+
36
+ def click
37
+ Uia.click(self)
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ class ElementStruct < FFI::ManagedStruct
44
+ include ElementLayout
45
+
46
+ def self.release(pointer)
47
+ Uia.release_element(pointer)
48
+ end
49
+ end
50
+
51
+ class ElementCast < FFI::Struct
52
+ include ElementLayout
53
+ end
54
+
55
+ class ElementChildrenStruct < FFI::ManagedStruct
56
+ layout :length, :int,
57
+ :items, :pointer
58
+
59
+ def children
60
+ @children ||= self[:length].times.collect do |i|
61
+ ElementCast.new(self[:items] + i * ElementCast.size)
62
+ end
63
+ end
64
+
65
+ def self.release(pointer)
66
+ Uia.release_elements(pointer)
67
+ end
68
+ end
69
+
70
+ def self.uia_directory
71
+ File.dirname(__FILE__) + '/../ext/UiaDll/Release'
72
+ end
73
+
74
+ ffi_lib File.join(uia_directory, 'UiaDll.dll')
75
+ ffi_convention :stdcall
76
+
77
+ attach_function :init, :initialize, [:string], :void
78
+ init(uia_directory)
79
+
80
+ PropertyId = enum(:is_selection_item, 0)
81
+
82
+
83
+ def self.attach_throwable_function(name_alias, name, arg_types, return_type)
84
+ attach_function name, arg_types + [:pointer, :int], return_type
85
+ define_singleton_method(name_alias) do |*args|
86
+ can_throw(name, *args)
87
+ end
88
+ end
89
+
90
+ # cleanup
91
+ attach_function :release_element, :Element_Release, [:pointer], :void
92
+ attach_function :release_elements, :Element_ReleaseMany, [:pointer], :void
93
+
94
+ # finding elements
95
+ attach_throwable_function :find_by_id, :Element_FindById, [:string], ElementStruct.by_ref
96
+ attach_throwable_function :find_by_handle, :Element_FindByHandle, [:int], ElementStruct.by_ref
97
+ attach_function :Element_FindByRuntimeId, [:pointer, :int, :pointer, :int], ElementStruct.by_ref
98
+
99
+ # element methods
100
+ attach_throwable_function :children, :Element_Children, [:pointer], ElementChildrenStruct.by_ref
101
+ attach_throwable_function :children_of_type, :Element_ChildrenOfType, [:pointer, PropertyId], ElementChildrenStruct.by_ref
102
+ attach_throwable_function :click, :Element_Click, [:pointer], :void
103
+
104
+ def self.find_by_runtime_id(id)
105
+ p = FFI::MemoryPointer.new :int, id.count
106
+ p.write_array_of_int(id)
107
+ can_throw(:Element_FindByRuntimeId, p, id.count)
108
+ end
109
+
110
+ def self.can_throw(method, *args)
111
+ string_buffer = FFI::MemoryPointer.new :char, 1024
112
+ result = send method, *(args << string_buffer << 1024)
113
+ error_info = string_buffer.read_string
114
+ raise error_info unless error_info.empty?
115
+ result
116
+ end
117
+ end
data/uia.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'uia/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "uia"
8
+ spec.version = Uia::VERSION
9
+ spec.authors = ["Levi Wilson"]
10
+ spec.email = ["levi@leviwilson.com"]
11
+ spec.description = %q{This wraps UIA stuff}
12
+ spec.summary = %q{This wraps UIA stuff}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ binaries = [
17
+ 'ext/UiaDll/Release/UiaDll.dll',
18
+ 'ext/UiaDll/Release/UIA.Helper.dll'
19
+ ]
20
+
21
+ spec.files = `git ls-files`.split($/) + binaries
22
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
23
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_runtime_dependency 'ffi'
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.3"
29
+ spec.add_development_dependency "rake"
30
+ end