uia 0.0.4

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