rdp-rautomation 0.6.3.1
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/.document +5 -0
- data/.rspec +2 -0
- data/.yardopts +6 -0
- data/History.rdoc +103 -0
- data/LICENSE +20 -0
- data/README.rdoc +114 -0
- data/Rakefile +43 -0
- data/VERSION +1 -0
- data/ext/AutoItX/AutoItX.chm +0 -0
- data/ext/AutoItX/AutoItX3.dll +0 -0
- data/ext/IAccessibleDLL/IAccessibleDLL.sln +20 -0
- data/ext/IAccessibleDLL/IAccessibleDLL.suo +0 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.cpp +30 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj +102 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj.filters +42 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj.user +3 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/ReadMe.txt +48 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/dllmain.cpp +19 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/stdafx.cpp +8 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/stdafx.h +22 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/table_support.cpp +282 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/targetver.h +8 -0
- data/ext/IAccessibleDLL/Release/IAccessibleDLL.dll +0 -0
- data/ext/ListViewExplorer/ListViewExplorer.sln +20 -0
- data/ext/ListViewExplorer/ListViewExplorer.suo +0 -0
- data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.cpp +174 -0
- data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj +95 -0
- data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.filters +42 -0
- data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.user +3 -0
- data/ext/ListViewExplorer/ListViewExplorer/ReadMe.txt +40 -0
- data/ext/ListViewExplorer/ListViewExplorer/stdafx.cpp +8 -0
- data/ext/ListViewExplorer/ListViewExplorer/stdafx.h +17 -0
- data/ext/ListViewExplorer/ListViewExplorer/table_support.cpp +250 -0
- data/ext/ListViewExplorer/ListViewExplorer/table_support.h +2 -0
- data/ext/ListViewExplorer/ListViewExplorer/targetver.h +8 -0
- data/ext/UiaDll/Release/UiaDll.dll +0 -0
- data/ext/UiaDll/UiaDll.sln +20 -0
- data/ext/UiaDll/UiaDll.suo +0 -0
- data/ext/UiaDll/UiaDll/ReadMe.txt +48 -0
- data/ext/UiaDll/UiaDll/UiaDll.cpp +205 -0
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj +104 -0
- data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +42 -0
- data/ext/UiaDll/UiaDll/dllmain.cpp +39 -0
- data/ext/UiaDll/UiaDll/globals.h +3 -0
- data/ext/UiaDll/UiaDll/stdafx.cpp +8 -0
- data/ext/UiaDll/UiaDll/stdafx.h +19 -0
- data/ext/UiaDll/UiaDll/targetver.h +8 -0
- data/ext/WindowsForms/bin/WindowsForms.exe +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms.sln +20 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms.suo +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/AboutBox.Designer.cs +80 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/AboutBox.cs +103 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/AboutBox.resx +120 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.Designer.cs +187 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.cs +46 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.resx +120 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.Designer.cs +377 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.cs +78 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.resx +120 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/PersonForm.Designer.cs +119 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/PersonForm.cs +34 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/PersonForm.resx +120 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Program.cs +21 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/AssemblyInfo.cs +36 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Resources.Designer.cs +71 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Resources.resx +117 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Settings.Designer.cs +30 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/Properties/Settings.settings +7 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/SimpleElementsForm.Designer.cs +93 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/SimpleElementsForm.cs +19 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/SimpleElementsForm.resx +120 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/WindowsForms.csproj +123 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Release/WindowsForms.exe +0 -0
- data/lib/rautomation.rb +6 -0
- data/lib/rautomation/adapter/autoit.rb +5 -0
- data/lib/rautomation/adapter/autoit/button.rb +59 -0
- data/lib/rautomation/adapter/autoit/locators.rb +22 -0
- data/lib/rautomation/adapter/autoit/text_field.rb +61 -0
- data/lib/rautomation/adapter/autoit/window.rb +184 -0
- data/lib/rautomation/adapter/helper.rb +20 -0
- data/lib/rautomation/adapter/win_ffi.rb +21 -0
- data/lib/rautomation/adapter/win_ffi/button.rb +25 -0
- data/lib/rautomation/adapter/win_ffi/button_helper.rb +24 -0
- data/lib/rautomation/adapter/win_ffi/checkbox.rb +19 -0
- data/lib/rautomation/adapter/win_ffi/constants.rb +94 -0
- data/lib/rautomation/adapter/win_ffi/control.rb +79 -0
- data/lib/rautomation/adapter/win_ffi/functions.rb +333 -0
- data/lib/rautomation/adapter/win_ffi/keystroke_converter.rb +67 -0
- data/lib/rautomation/adapter/win_ffi/label.rb +21 -0
- data/lib/rautomation/adapter/win_ffi/list_box.rb +60 -0
- data/lib/rautomation/adapter/win_ffi/locators.rb +22 -0
- data/lib/rautomation/adapter/win_ffi/ms_uia/uia_dll.rb +36 -0
- data/lib/rautomation/adapter/win_ffi/radio.rb +19 -0
- data/lib/rautomation/adapter/win_ffi/select_list.rb +87 -0
- data/lib/rautomation/adapter/win_ffi/table.rb +57 -0
- data/lib/rautomation/adapter/win_ffi/text_field.rb +52 -0
- data/lib/rautomation/adapter/win_ffi/window.rb +226 -0
- data/lib/rautomation/button.rb +55 -0
- data/lib/rautomation/element_collections.rb +47 -0
- data/lib/rautomation/text_field.rb +60 -0
- data/lib/rautomation/wait_helper.rb +23 -0
- data/lib/rautomation/window.rb +234 -0
- data/spec/adapter/win_ffi/button_spec.rb +41 -0
- data/spec/adapter/win_ffi/checkbox_spec.rb +48 -0
- data/spec/adapter/win_ffi/keystroke_converter_spec.rb +47 -0
- data/spec/adapter/win_ffi/label_spec.rb +21 -0
- data/spec/adapter/win_ffi/listbox_spec.rb +52 -0
- data/spec/adapter/win_ffi/radio_spec.rb +37 -0
- data/spec/adapter/win_ffi/select_list_spec.rb +66 -0
- data/spec/adapter/win_ffi/table_spec.rb +39 -0
- data/spec/adapter/win_ffi/text_field_spec.rb +23 -0
- data/spec/adapter/win_ffi/window_spec.rb +43 -0
- data/spec/button_spec.rb +68 -0
- data/spec/buttons_spec.rb +21 -0
- data/spec/spec_helper.rb +96 -0
- data/spec/text_field_spec.rb +65 -0
- data/spec/text_fields_spec.rb +22 -0
- data/spec/window_spec.rb +122 -0
- data/spec/windows_spec.rb +55 -0
- metadata +207 -0
|
Binary file
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// ListViewExplorer.cpp : Defines the entry point for the console application.
|
|
2
|
+
//
|
|
3
|
+
|
|
4
|
+
#include "stdafx.h"
|
|
5
|
+
|
|
6
|
+
HWND ask_for_list_view_handle() {
|
|
7
|
+
HWND hwnd = 0 ;
|
|
8
|
+
|
|
9
|
+
printf("HWND of list view control: ") ;
|
|
10
|
+
scanf_s("%x", &hwnd) ;
|
|
11
|
+
while(getchar() != '\n') continue;
|
|
12
|
+
|
|
13
|
+
return hwnd ;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
void print_acc_name(VARIANT varIn, IAccessible *pAccessible) {
|
|
17
|
+
BSTR bstrName ;
|
|
18
|
+
|
|
19
|
+
if (pAccessible->get_accName(varIn, &bstrName) == S_OK) {
|
|
20
|
+
char *pszName = _com_util::ConvertBSTRToString(bstrName) ;
|
|
21
|
+
printf(" Name: %s\r\n", pszName) ;
|
|
22
|
+
delete[] pszName ;
|
|
23
|
+
SysFreeString(bstrName) ;
|
|
24
|
+
} else
|
|
25
|
+
printf(" Name: not available\r\n") ;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
void print_acc_value(VARIANT varIn, IAccessible *pAccessible) {
|
|
29
|
+
BSTR bstrValue ;
|
|
30
|
+
|
|
31
|
+
if (pAccessible->get_accValue(varIn, &bstrValue) == S_OK) {
|
|
32
|
+
char *pszValue = _com_util::ConvertBSTRToString(bstrValue) ;
|
|
33
|
+
printf(" Value: %s\r\n", pszValue) ;
|
|
34
|
+
delete[] pszValue ;
|
|
35
|
+
SysFreeString(bstrValue) ;
|
|
36
|
+
} else
|
|
37
|
+
printf(" Value: not available\r\n") ;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
void print_acc_description(VARIANT varIn, IAccessible *pAccessible) {
|
|
41
|
+
BSTR bstrValue ;
|
|
42
|
+
|
|
43
|
+
if (pAccessible->get_accDescription(varIn, &bstrValue) == S_OK) {
|
|
44
|
+
char *pszValue = _com_util::ConvertBSTRToString(bstrValue) ;
|
|
45
|
+
printf(" Description: %s\r\n", pszValue) ;
|
|
46
|
+
delete[] pszValue ;
|
|
47
|
+
SysFreeString(bstrValue) ;
|
|
48
|
+
} else
|
|
49
|
+
printf(" Description: not available\r\n") ;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void print_acc_child_count(IAccessible *pAccessible) {
|
|
53
|
+
long count ;
|
|
54
|
+
pAccessible->get_accChildCount(&count) ;
|
|
55
|
+
printf(" Number of childs: %d\r\n", count) ;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
void print_acc_role(VARIANT varIn, IAccessible *pAccessible) {
|
|
59
|
+
VARIANT varOut ;
|
|
60
|
+
VariantInit(&varOut) ;
|
|
61
|
+
varOut.vt = VT_I4 ;
|
|
62
|
+
|
|
63
|
+
pAccessible->get_accRole(varIn, &varOut) ;
|
|
64
|
+
|
|
65
|
+
int roleTextMax = 255 ;
|
|
66
|
+
LPTSTR pRoleText = new TCHAR[roleTextMax] ;
|
|
67
|
+
GetRoleText(varOut.lVal, pRoleText, roleTextMax) ;
|
|
68
|
+
|
|
69
|
+
int lenSzRoleText = 255 ;
|
|
70
|
+
char *pszRoleText = new char[lenSzRoleText] ;
|
|
71
|
+
WideCharToMultiByte(CP_ACP, 0, pRoleText, wcslen(pRoleText) + 1, pszRoleText, lenSzRoleText, NULL, NULL) ;
|
|
72
|
+
|
|
73
|
+
printf(" Role is %s\r\n", pszRoleText) ;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
void print_properties(IAccessible *pAccessible, long childId) {
|
|
77
|
+
VARIANT varChild ;
|
|
78
|
+
VariantInit(&varChild) ;
|
|
79
|
+
varChild.vt = VT_I4 ;
|
|
80
|
+
varChild.lVal = childId ;
|
|
81
|
+
|
|
82
|
+
print_acc_name(varChild, pAccessible) ;
|
|
83
|
+
print_acc_value(varChild, pAccessible) ;
|
|
84
|
+
print_acc_role(varChild, pAccessible) ;
|
|
85
|
+
print_acc_description(varChild, pAccessible) ;
|
|
86
|
+
|
|
87
|
+
if (childId == CHILDID_SELF)
|
|
88
|
+
print_acc_child_count(pAccessible) ;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
void iterate_over_childs(IAccessible *pAccessible) {
|
|
92
|
+
printf("Iterating over childs\r\n") ;
|
|
93
|
+
|
|
94
|
+
long childCount ;
|
|
95
|
+
pAccessible->get_accChildCount(&childCount) ;
|
|
96
|
+
|
|
97
|
+
for (int childId = 1; childId <= childCount; childId++) {
|
|
98
|
+
printf("Child number %d: ", childId) ;
|
|
99
|
+
VARIANT varChild ;
|
|
100
|
+
VariantInit(&varChild) ;
|
|
101
|
+
varChild.vt = VT_I4 ;
|
|
102
|
+
varChild.lVal = childId ;
|
|
103
|
+
|
|
104
|
+
IDispatch *pIDispatch ;
|
|
105
|
+
HRESULT hr = pAccessible->get_accChild(varChild, &pIDispatch) ;
|
|
106
|
+
if (hr == S_OK) {
|
|
107
|
+
printf("get_accChild returned S_OK. Now asking for IDispatch") ;
|
|
108
|
+
IAccessible *pChildIAccessible ;
|
|
109
|
+
pIDispatch->QueryInterface(IID_IAccessible, (void**)&pChildIAccessible) ;
|
|
110
|
+
print_properties(pChildIAccessible, CHILDID_SELF) ;
|
|
111
|
+
} else if (hr == S_FALSE) {
|
|
112
|
+
printf("Simple element\r\n") ;
|
|
113
|
+
print_properties(pAccessible, childId) ;
|
|
114
|
+
} else if (hr == E_INVALIDARG)
|
|
115
|
+
printf("Invalid argument\r\n") ;
|
|
116
|
+
else
|
|
117
|
+
printf("getAccChild returned %x\r\n", hr) ;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
int _tmain(int argc, _TCHAR* argv[])
|
|
122
|
+
{
|
|
123
|
+
printf("ListView Explorer\r\n") ;
|
|
124
|
+
|
|
125
|
+
HWND hwndListView = ask_for_list_view_handle() ;
|
|
126
|
+
|
|
127
|
+
HMODULE hModule = LoadLibraryA("oleacc.dll");
|
|
128
|
+
if (hModule == 0) {
|
|
129
|
+
printf("Cannot load oleacc.dll\r\n") ;
|
|
130
|
+
return 1 ;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
long numberOfRows ;
|
|
134
|
+
long numberOfColumns ;
|
|
135
|
+
char ***tableStrings ;
|
|
136
|
+
|
|
137
|
+
get_table_strings(hModule, hwndListView, (char **)&tableStrings, &numberOfRows, &numberOfColumns) ;
|
|
138
|
+
|
|
139
|
+
printf("Now printing result\r\n") ;
|
|
140
|
+
for (int row = 0; row < numberOfRows; row++) {
|
|
141
|
+
for (int column = 0; column < numberOfColumns; column++) {
|
|
142
|
+
printf("row %d, col %d is '%s'\r\n", row, column, tableStrings[row][column]) ;
|
|
143
|
+
free(tableStrings[row][column]) ;
|
|
144
|
+
}
|
|
145
|
+
free(tableStrings[row]) ;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
/*
|
|
150
|
+
printf("ListView Explorer\r\n") ;
|
|
151
|
+
|
|
152
|
+
HWND hwndListView = ask_for_list_view_handle() ;
|
|
153
|
+
IAccessible *pAccessible ;
|
|
154
|
+
LPFNACCESSIBLEOBJECTFROMWINDOW lpfnAccessibleObjectFromWindow ;
|
|
155
|
+
|
|
156
|
+
HMODULE hModule = LoadLibraryA("oleacc.dll");
|
|
157
|
+
if (hModule == 0) {
|
|
158
|
+
printf("Cannot load oleacc.dll\r\n") ;
|
|
159
|
+
return 1 ;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
lpfnAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)GetProcAddress(hModule, "AccessibleObjectFromWindow");
|
|
163
|
+
|
|
164
|
+
if (HRESULT hResult = lpfnAccessibleObjectFromWindow(hwndListView, OBJID_CLIENT, IID_IAccessible, (void**)&pAccessible) == S_OK) {
|
|
165
|
+
printf("Got IAccessible\r\n") ;
|
|
166
|
+
print_properties(pAccessible, CHILDID_SELF) ;
|
|
167
|
+
iterate_over_childs(pAccessible) ;
|
|
168
|
+
} else
|
|
169
|
+
printf("Cannot retrieve IAccessible for window HWND %x. AccessibleObjectFromWindow returned %x\r\n", hwndListView, hResult) ;
|
|
170
|
+
*/
|
|
171
|
+
|
|
172
|
+
return 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
@@ -0,0 +1,95 @@
|
|
|
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>{EF611F7A-863F-4062-AAD2-84D150F4D7C0}</ProjectGuid>
|
|
15
|
+
<Keyword>Win32Proj</Keyword>
|
|
16
|
+
<RootNamespace>ListViewExplorer</RootNamespace>
|
|
17
|
+
</PropertyGroup>
|
|
18
|
+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
19
|
+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
20
|
+
<ConfigurationType>Application</ConfigurationType>
|
|
21
|
+
<UseDebugLibraries>true</UseDebugLibraries>
|
|
22
|
+
<CharacterSet>Unicode</CharacterSet>
|
|
23
|
+
</PropertyGroup>
|
|
24
|
+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
25
|
+
<ConfigurationType>Application</ConfigurationType>
|
|
26
|
+
<UseDebugLibraries>false</UseDebugLibraries>
|
|
27
|
+
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
28
|
+
<CharacterSet>Unicode</CharacterSet>
|
|
29
|
+
</PropertyGroup>
|
|
30
|
+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
31
|
+
<ImportGroup Label="ExtensionSettings">
|
|
32
|
+
</ImportGroup>
|
|
33
|
+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
34
|
+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
35
|
+
</ImportGroup>
|
|
36
|
+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
37
|
+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
38
|
+
</ImportGroup>
|
|
39
|
+
<PropertyGroup Label="UserMacros" />
|
|
40
|
+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
41
|
+
<LinkIncremental>true</LinkIncremental>
|
|
42
|
+
</PropertyGroup>
|
|
43
|
+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
44
|
+
<LinkIncremental>false</LinkIncremental>
|
|
45
|
+
</PropertyGroup>
|
|
46
|
+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
47
|
+
<ClCompile>
|
|
48
|
+
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
49
|
+
<WarningLevel>Level3</WarningLevel>
|
|
50
|
+
<Optimization>Disabled</Optimization>
|
|
51
|
+
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
52
|
+
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
|
53
|
+
</ClCompile>
|
|
54
|
+
<Link>
|
|
55
|
+
<SubSystem>Console</SubSystem>
|
|
56
|
+
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
57
|
+
<AdditionalDependencies>oleacc.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
58
|
+
</Link>
|
|
59
|
+
</ItemDefinitionGroup>
|
|
60
|
+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
61
|
+
<ClCompile>
|
|
62
|
+
<WarningLevel>Level3</WarningLevel>
|
|
63
|
+
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
64
|
+
<Optimization>MaxSpeed</Optimization>
|
|
65
|
+
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
66
|
+
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
67
|
+
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
68
|
+
</ClCompile>
|
|
69
|
+
<Link>
|
|
70
|
+
<SubSystem>Console</SubSystem>
|
|
71
|
+
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
72
|
+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
73
|
+
<OptimizeReferences>true</OptimizeReferences>
|
|
74
|
+
</Link>
|
|
75
|
+
</ItemDefinitionGroup>
|
|
76
|
+
<ItemGroup>
|
|
77
|
+
<None Include="ReadMe.txt" />
|
|
78
|
+
</ItemGroup>
|
|
79
|
+
<ItemGroup>
|
|
80
|
+
<ClInclude Include="stdafx.h" />
|
|
81
|
+
<ClInclude Include="table_support.h" />
|
|
82
|
+
<ClInclude Include="targetver.h" />
|
|
83
|
+
</ItemGroup>
|
|
84
|
+
<ItemGroup>
|
|
85
|
+
<ClCompile Include="ListViewExplorer.cpp" />
|
|
86
|
+
<ClCompile Include="stdafx.cpp">
|
|
87
|
+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
|
88
|
+
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
|
89
|
+
</ClCompile>
|
|
90
|
+
<ClCompile Include="table_support.cpp" />
|
|
91
|
+
</ItemGroup>
|
|
92
|
+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
93
|
+
<ImportGroup Label="ExtensionTargets">
|
|
94
|
+
</ImportGroup>
|
|
95
|
+
</Project>
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
<None Include="ReadMe.txt" />
|
|
19
|
+
</ItemGroup>
|
|
20
|
+
<ItemGroup>
|
|
21
|
+
<ClInclude Include="stdafx.h">
|
|
22
|
+
<Filter>Header Files</Filter>
|
|
23
|
+
</ClInclude>
|
|
24
|
+
<ClInclude Include="targetver.h">
|
|
25
|
+
<Filter>Header Files</Filter>
|
|
26
|
+
</ClInclude>
|
|
27
|
+
<ClInclude Include="table_support.h">
|
|
28
|
+
<Filter>Header Files</Filter>
|
|
29
|
+
</ClInclude>
|
|
30
|
+
</ItemGroup>
|
|
31
|
+
<ItemGroup>
|
|
32
|
+
<ClCompile Include="stdafx.cpp">
|
|
33
|
+
<Filter>Source Files</Filter>
|
|
34
|
+
</ClCompile>
|
|
35
|
+
<ClCompile Include="ListViewExplorer.cpp">
|
|
36
|
+
<Filter>Source Files</Filter>
|
|
37
|
+
</ClCompile>
|
|
38
|
+
<ClCompile Include="table_support.cpp">
|
|
39
|
+
<Filter>Source Files</Filter>
|
|
40
|
+
</ClCompile>
|
|
41
|
+
</ItemGroup>
|
|
42
|
+
</Project>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
========================================================================
|
|
2
|
+
CONSOLE APPLICATION : ListViewExplorer Project Overview
|
|
3
|
+
========================================================================
|
|
4
|
+
|
|
5
|
+
AppWizard has created this ListViewExplorer application for you.
|
|
6
|
+
|
|
7
|
+
This file contains a summary of what you will find in each of the files that
|
|
8
|
+
make up your ListViewExplorer application.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
ListViewExplorer.vcxproj
|
|
12
|
+
This is the main project file for VC++ projects generated using an Application Wizard.
|
|
13
|
+
It contains information about the version of Visual C++ that generated the file, and
|
|
14
|
+
information about the platforms, configurations, and project features selected with the
|
|
15
|
+
Application Wizard.
|
|
16
|
+
|
|
17
|
+
ListViewExplorer.vcxproj.filters
|
|
18
|
+
This is the filters file for VC++ projects generated using an Application Wizard.
|
|
19
|
+
It contains information about the association between the files in your project
|
|
20
|
+
and the filters. This association is used in the IDE to show grouping of files with
|
|
21
|
+
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
|
|
22
|
+
"Source Files" filter).
|
|
23
|
+
|
|
24
|
+
ListViewExplorer.cpp
|
|
25
|
+
This is the main application source file.
|
|
26
|
+
|
|
27
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
28
|
+
Other standard files:
|
|
29
|
+
|
|
30
|
+
StdAfx.h, StdAfx.cpp
|
|
31
|
+
These files are used to build a precompiled header (PCH) file
|
|
32
|
+
named ListViewExplorer.pch and a precompiled types file named StdAfx.obj.
|
|
33
|
+
|
|
34
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
35
|
+
Other notes:
|
|
36
|
+
|
|
37
|
+
AppWizard uses "TODO:" comments to indicate parts of the source code you
|
|
38
|
+
should add to or customize.
|
|
39
|
+
|
|
40
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// stdafx.cpp : source file that includes just the standard includes
|
|
2
|
+
// ListViewExplorer.pch will be the pre-compiled header
|
|
3
|
+
// stdafx.obj will contain the pre-compiled type information
|
|
4
|
+
|
|
5
|
+
#include "stdafx.h"
|
|
6
|
+
|
|
7
|
+
// TODO: reference any additional headers you need in STDAFX.H
|
|
8
|
+
// and not in this file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// stdafx.h : include file for standard system include files,
|
|
2
|
+
// or project specific include files that are used frequently, but
|
|
3
|
+
// are changed infrequently
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
#pragma once
|
|
7
|
+
|
|
8
|
+
#include "targetver.h"
|
|
9
|
+
|
|
10
|
+
#include <stdio.h>
|
|
11
|
+
#include <tchar.h>
|
|
12
|
+
|
|
13
|
+
#include <Windows.h>
|
|
14
|
+
#include <OleAcc.h>
|
|
15
|
+
#include <comutil.h>
|
|
16
|
+
|
|
17
|
+
#include "table_support.h"
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
#include "stdafx.h"
|
|
2
|
+
|
|
3
|
+
#define BUFFER_SIZE 255
|
|
4
|
+
|
|
5
|
+
long get_number_of_rows(IAccessible *pAccessible) {
|
|
6
|
+
long count ;
|
|
7
|
+
|
|
8
|
+
pAccessible->get_accChildCount(&count) ;
|
|
9
|
+
return count ;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
void get_name(long childId, IAccessible *pAccessible, char *itemText) {
|
|
13
|
+
BSTR bstrValue ;
|
|
14
|
+
|
|
15
|
+
VARIANT varIn ;
|
|
16
|
+
VariantInit(&varIn) ;
|
|
17
|
+
varIn.vt = VT_I4 ;
|
|
18
|
+
varIn.lVal = childId ;
|
|
19
|
+
|
|
20
|
+
if (pAccessible->get_accName(varIn, &bstrValue) == S_OK) {
|
|
21
|
+
char *pszName = _com_util::ConvertBSTRToString(bstrValue) ;
|
|
22
|
+
strcpy(itemText, pszName) ;
|
|
23
|
+
delete[] pszName ;
|
|
24
|
+
SysFreeString(bstrValue) ;
|
|
25
|
+
} else
|
|
26
|
+
strcpy(itemText, "\0") ;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
HRESULT get_role(long childId, IAccessible *pAccessible, long *pRole) {
|
|
30
|
+
VARIANT varIn ;
|
|
31
|
+
VariantInit(&varIn) ;
|
|
32
|
+
varIn.vt = VT_I4 ;
|
|
33
|
+
varIn.lVal = childId ;
|
|
34
|
+
|
|
35
|
+
VARIANT varOut ;
|
|
36
|
+
VariantInit(&varOut) ;
|
|
37
|
+
varOut.vt = VT_I4 ;
|
|
38
|
+
|
|
39
|
+
HRESULT hr = pAccessible->get_accRole(varIn, &varOut) ;
|
|
40
|
+
*pRole = varOut.lVal ;
|
|
41
|
+
|
|
42
|
+
return hr ;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
void get_role(long childId, IAccessible *pAccessible, char *itemText) {
|
|
46
|
+
long role ;
|
|
47
|
+
|
|
48
|
+
if (get_role(childId, pAccessible, &role) == S_OK) {
|
|
49
|
+
int roleTextMax = 255 ;
|
|
50
|
+
LPTSTR pRoleText = new TCHAR[roleTextMax] ;
|
|
51
|
+
GetRoleText(role, pRoleText, roleTextMax) ;
|
|
52
|
+
|
|
53
|
+
int lenSzRoleText = 255 ;
|
|
54
|
+
char *pszRoleText = new char[lenSzRoleText] ;
|
|
55
|
+
WideCharToMultiByte(CP_ACP, 0, pRoleText, wcslen(pRoleText) + 1, pszRoleText, lenSzRoleText, NULL, NULL) ;
|
|
56
|
+
|
|
57
|
+
sprintf(itemText, "0x%x, %s", role, pszRoleText) ;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
void get_description(long childId, IAccessible *pAccessible, char *itemText) {
|
|
62
|
+
BSTR bstrValue ;
|
|
63
|
+
|
|
64
|
+
VARIANT varIn ;
|
|
65
|
+
VariantInit(&varIn) ;
|
|
66
|
+
varIn.vt = VT_I4 ;
|
|
67
|
+
varIn.lVal = childId ;
|
|
68
|
+
|
|
69
|
+
if (pAccessible->get_accDescription(varIn, &bstrValue) == S_OK) {
|
|
70
|
+
char *pszName = _com_util::ConvertBSTRToString(bstrValue) ;
|
|
71
|
+
strcpy(itemText, pszName) ;
|
|
72
|
+
delete[] pszName ;
|
|
73
|
+
SysFreeString(bstrValue) ;
|
|
74
|
+
} else
|
|
75
|
+
strcpy(itemText, "\0") ;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
void print_child_name(long childId, IAccessible *pAccessible) {
|
|
79
|
+
char *childName = (char *)malloc(sizeof(char) * BUFFER_SIZE) ;
|
|
80
|
+
get_name(childId, pAccessible, childName) ;
|
|
81
|
+
|
|
82
|
+
if (childId == CHILDID_SELF)
|
|
83
|
+
printf("Name for child SELF is %s\r\n", childId, childName) ;
|
|
84
|
+
else
|
|
85
|
+
printf("Name for child %d is %s\r\n", childId, childName) ;
|
|
86
|
+
|
|
87
|
+
free(childName) ;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
void print_child_role(long childId, IAccessible *pAccessible) {
|
|
91
|
+
char *childRole = (char *)malloc(sizeof(char) * BUFFER_SIZE) ;
|
|
92
|
+
get_role(childId, pAccessible, childRole) ;
|
|
93
|
+
|
|
94
|
+
if (childId == CHILDID_SELF)
|
|
95
|
+
printf("Role for child SELF is %s\r\n", childId, childRole) ;
|
|
96
|
+
else
|
|
97
|
+
printf("Role for child %d is %s\r\n", childId, childRole) ;
|
|
98
|
+
|
|
99
|
+
free(childRole) ;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
void walk_tree(IAccessible *pAccessible, char **pColumnHeaderNames, long *pColumnHeadersCount) {
|
|
103
|
+
HRESULT hr ;
|
|
104
|
+
long childCount ;
|
|
105
|
+
|
|
106
|
+
hr = pAccessible->get_accChildCount(&childCount) ;
|
|
107
|
+
if (FAILED(hr) || childCount == 0)
|
|
108
|
+
return ;
|
|
109
|
+
|
|
110
|
+
VARIANT *pChildVariants = new VARIANT[childCount] ;
|
|
111
|
+
long childrenFound ;
|
|
112
|
+
hr = AccessibleChildren(pAccessible, 0, childCount, pChildVariants, &childrenFound) ;
|
|
113
|
+
if (FAILED(hr))
|
|
114
|
+
return ;
|
|
115
|
+
|
|
116
|
+
for (int i=1; i < childrenFound + 1; i++) {
|
|
117
|
+
VARIANT vChild = pChildVariants[i] ;
|
|
118
|
+
if (vChild.vt == VT_DISPATCH) {
|
|
119
|
+
IDispatch *pDispatch = vChild.pdispVal ;
|
|
120
|
+
IAccessible *pChildAccessible = NULL ;
|
|
121
|
+
hr = pDispatch->QueryInterface(IID_IAccessible, (void**) &pChildAccessible) ;
|
|
122
|
+
if (hr == S_OK) {
|
|
123
|
+
walk_tree(pChildAccessible, pColumnHeaderNames, pColumnHeadersCount) ;
|
|
124
|
+
|
|
125
|
+
pChildAccessible->Release() ;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
pDispatch->Release() ;
|
|
129
|
+
} else {
|
|
130
|
+
long role ;
|
|
131
|
+
get_role(i, pAccessible, &role) ;
|
|
132
|
+
if (role == 0x19) {
|
|
133
|
+
if (pColumnHeaderNames == NULL) {
|
|
134
|
+
*pColumnHeadersCount = *pColumnHeadersCount + 1 ;
|
|
135
|
+
} else {
|
|
136
|
+
char *headerName = (char *)malloc(sizeof(char) * BUFFER_SIZE) ;
|
|
137
|
+
get_name(i, pAccessible, headerName) ;
|
|
138
|
+
pColumnHeaderNames[i - 1] = headerName ;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
void find_column_headers(IAccessible *pAccessible, char ***pHeaderNames, long *pColumns) {
|
|
146
|
+
long columns = 0 ;
|
|
147
|
+
|
|
148
|
+
walk_tree(pAccessible, NULL, &columns) ;
|
|
149
|
+
printf("Columns: %d\r\n", columns) ;
|
|
150
|
+
|
|
151
|
+
char **pHeaders = (char **)malloc(sizeof(char *) * columns) ;
|
|
152
|
+
walk_tree(pAccessible, pHeaders, &columns) ;
|
|
153
|
+
|
|
154
|
+
*pHeaderNames = pHeaders ;
|
|
155
|
+
*pColumns = columns ;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
char *trimwhitespace(char *str) {
|
|
159
|
+
char *end;
|
|
160
|
+
// Trim leading space
|
|
161
|
+
while(isspace(*str))
|
|
162
|
+
str++;
|
|
163
|
+
if(*str == 0)
|
|
164
|
+
// All spaces?
|
|
165
|
+
return str;
|
|
166
|
+
// Trim trailing space
|
|
167
|
+
end = str + strlen(str) - 1;
|
|
168
|
+
|
|
169
|
+
while(end > str && isspace(*end))
|
|
170
|
+
end--; // Write new null terminator
|
|
171
|
+
|
|
172
|
+
*(end+1) = 0;
|
|
173
|
+
|
|
174
|
+
return str;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
char* remove_column_header_name(char *columnName, char *item) {
|
|
178
|
+
int itemLen = strlen(item) ;
|
|
179
|
+
int columnNameLen = strlen(columnName) ;
|
|
180
|
+
|
|
181
|
+
if (itemLen > 0) {
|
|
182
|
+
char *newItem = (char *)malloc(sizeof(char *) * (itemLen - columnNameLen)) ; // still a bit too long
|
|
183
|
+
|
|
184
|
+
strcpy(newItem, item + columnNameLen + 2) ; // :<space>
|
|
185
|
+
|
|
186
|
+
free(item) ;
|
|
187
|
+
return newItem ;
|
|
188
|
+
} else
|
|
189
|
+
return item ;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
void get_table_strings(HMODULE oleAccModule, HWND controlHwnd, char **tableStrings, long *numberOfRowsOut, long *numberOfColumnsOut) {
|
|
193
|
+
IAccessible *pAccessible ;
|
|
194
|
+
LPFNACCESSIBLEOBJECTFROMWINDOW lpfnAccessibleObjectFromWindow ;
|
|
195
|
+
|
|
196
|
+
lpfnAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)GetProcAddress(oleAccModule, "AccessibleObjectFromWindow");
|
|
197
|
+
|
|
198
|
+
if (HRESULT hResult = lpfnAccessibleObjectFromWindow(controlHwnd, OBJID_CLIENT, IID_IAccessible, (void**)&pAccessible) == S_OK) {
|
|
199
|
+
int numberOfRows = get_number_of_rows(pAccessible) ; // including the header
|
|
200
|
+
long numberOfColumns = 3 ;
|
|
201
|
+
char ***table_rows ;
|
|
202
|
+
char **pHeaderNames ;
|
|
203
|
+
|
|
204
|
+
find_column_headers(pAccessible, &pHeaderNames, &numberOfColumns) ;
|
|
205
|
+
|
|
206
|
+
table_rows = (char ***)malloc(sizeof(char*) * numberOfRows) ;
|
|
207
|
+
table_rows[0] = pHeaderNames ;
|
|
208
|
+
|
|
209
|
+
for (int row = 1; row < numberOfRows; row++) {
|
|
210
|
+
char **table_column = (char **)malloc(sizeof(char*) * numberOfColumns) ;
|
|
211
|
+
|
|
212
|
+
char *mainItem = (char *)malloc(sizeof(char) * BUFFER_SIZE) ;
|
|
213
|
+
get_name(row, pAccessible, mainItem) ;
|
|
214
|
+
|
|
215
|
+
char *description = (char *)malloc(sizeof(char) * 2048) ;
|
|
216
|
+
get_description(row, pAccessible, description) ;
|
|
217
|
+
|
|
218
|
+
char *token ;
|
|
219
|
+
if (strlen(description) > 0)
|
|
220
|
+
token = strtok(description, ",") ;
|
|
221
|
+
else
|
|
222
|
+
token = NULL ;
|
|
223
|
+
|
|
224
|
+
for (int column = 0; column < numberOfColumns; column++) {
|
|
225
|
+
if (column == 0)
|
|
226
|
+
table_column[column] = mainItem ;
|
|
227
|
+
else {
|
|
228
|
+
char *item = (char *)malloc(sizeof(char) * BUFFER_SIZE) ;
|
|
229
|
+
|
|
230
|
+
if (token != NULL) {
|
|
231
|
+
strcpy(item, token) ;
|
|
232
|
+
token = strtok(NULL, ",") ;
|
|
233
|
+
} else
|
|
234
|
+
strcpy(item, "\0") ;
|
|
235
|
+
|
|
236
|
+
table_column[column] = remove_column_header_name(pHeaderNames[column], trimwhitespace(item)) ;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
table_rows[row] = table_column ;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
*tableStrings = (char *)table_rows ;
|
|
244
|
+
*numberOfRowsOut = numberOfRows ;
|
|
245
|
+
*numberOfColumnsOut = numberOfColumns ;
|
|
246
|
+
} else {
|
|
247
|
+
*numberOfRowsOut = 0 ;
|
|
248
|
+
*numberOfColumnsOut = 0 ;
|
|
249
|
+
}
|
|
250
|
+
}
|