rautomation 0.5.1 → 0.6.0
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/History.rdoc +14 -0
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/ext/IAccessibleDLL/IAccessibleDLL.suo +0 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.cpp +0 -6
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj +2 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj.filters +3 -0
- data/ext/IAccessibleDLL/IAccessibleDLL/stdafx.h +9 -3
- data/ext/IAccessibleDLL/IAccessibleDLL/table_support.cpp +282 -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.suo +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.Designer.cs +27 -7
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.cs +1 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.Designer.cs +110 -11
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Release/WindowsForms.exe +0 -0
- data/lib/rautomation.rb +2 -3
- data/lib/rautomation/adapter/autoit.rb +2 -2
- data/lib/rautomation/adapter/win_ffi.rb +4 -0
- data/lib/rautomation/adapter/win_ffi/button.rb +6 -0
- data/lib/rautomation/adapter/win_ffi/checkbox.rb +7 -0
- data/lib/rautomation/adapter/win_ffi/constants.rb +44 -3
- data/lib/rautomation/adapter/win_ffi/control.rb +36 -3
- data/lib/rautomation/adapter/win_ffi/functions.rb +37 -3
- 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 +0 -1
- data/lib/rautomation/adapter/win_ffi/ms_uia/uia_dll.rb +36 -0
- data/lib/rautomation/adapter/win_ffi/radio.rb +7 -0
- data/lib/rautomation/adapter/win_ffi/select_list.rb +30 -7
- data/lib/rautomation/adapter/win_ffi/table.rb +42 -3
- data/lib/rautomation/adapter/win_ffi/text_field.rb +17 -1
- data/lib/rautomation/adapter/win_ffi/window.rb +47 -8
- data/lib/rautomation/button.rb +5 -0
- data/lib/rautomation/element_collections.rb +8 -5
- data/lib/rautomation/text_field.rb +10 -0
- data/lib/rautomation/window.rb +20 -14
- data/spec/adapter/win_ffi/button_spec.rb +41 -0
- data/spec/adapter/win_ffi/checkbox_spec.rb +19 -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 +16 -0
- data/spec/adapter/win_ffi/select_list_spec.rb +29 -4
- data/spec/adapter/win_ffi/table_spec.rb +20 -1
- data/spec/adapter/win_ffi/text_field_spec.rb +23 -0
- data/spec/adapter/win_ffi/window_spec.rb +29 -0
- data/spec/button_spec.rb +1 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/text_field_spec.rb +27 -15
- metadata +52 -34
- data/ext/IAccessibleDLL/Release/IAccessibleDLL.exp +0 -0
- data/ext/IAccessibleDLL/Release/IAccessibleDLL.lib +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.exe +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.pdb +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.vshost.exe +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.vshost.exe.manifest +0 -11
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/DesignTimeResolveAssemblyReferences.cache +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/GenerateResource.read.1.tlog +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/GenerateResource.write.1.tlog +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/ResolveAssemblyReference.cache +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.AboutBox.resources +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.DataEntryForm.resources +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.MainFormWindow.resources +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.PersonForm.resources +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.Properties.Resources.resources +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.SimpleElementsForm.resources +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.csproj.FileListAbsolute.txt +0 -25
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.exe +0 -0
- data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.pdb +0 -0
data/History.rdoc
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
=== Version 0.6.0 / 2011-07-03
|
|
2
|
+
|
|
3
|
+
=== WinFFI adapter
|
|
4
|
+
|
|
5
|
+
* Window#send_keys now accepts only String argument similar to AutoIt's Send function.
|
|
6
|
+
* added Table#strings, #select, #selected? methods.
|
|
7
|
+
* added Label element support with #value method.
|
|
8
|
+
* added #has_focus? and #set_focus methods to controls.
|
|
9
|
+
* added possibility to search controls by automation id as :id.
|
|
10
|
+
* added #enabled? and #disabled? methods for controls.
|
|
11
|
+
* added Window#control and #controls methods for accessing controls generally.
|
|
12
|
+
* added SelectList#option method.
|
|
13
|
+
* added ListBox element support with #count, #items, #exist?, #selected? and #select methods.
|
|
14
|
+
|
|
1
15
|
=== Version 0.5.1 / 2011-01-30
|
|
2
16
|
|
|
3
17
|
=== All adapters
|
data/README.rdoc
CHANGED
|
@@ -25,7 +25,7 @@ RAutomation provides:
|
|
|
25
25
|
window.text # => "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ultricies..."
|
|
26
26
|
|
|
27
27
|
window.text_field(:class => "Edit", :index => 0).set "hello, world!"
|
|
28
|
-
button = window.button(:
|
|
28
|
+
button = window.button(:value => "&Save")
|
|
29
29
|
button.exists? # => true
|
|
30
30
|
button.click
|
|
31
31
|
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.6.0
|
|
Binary file
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
// IAccessibleDLL.cpp : Defines the exported functions for the DLL application.
|
|
2
2
|
//
|
|
3
3
|
|
|
4
|
-
#undef UNICODE
|
|
5
|
-
|
|
6
4
|
#include "stdafx.h"
|
|
7
|
-
#include <windows.h>
|
|
8
|
-
#include <objbase.h>
|
|
9
|
-
#include <OleAcc.h>
|
|
10
|
-
#include <Commctrl.h>
|
|
11
5
|
|
|
12
6
|
extern "C"
|
|
13
7
|
__declspec( dllexport ) long get_button_state(HWND buttonHwnd) {
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
71
71
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
72
72
|
<OptimizeReferences>true</OptimizeReferences>
|
|
73
|
+
<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>
|
|
73
74
|
</Link>
|
|
74
75
|
</ItemDefinitionGroup>
|
|
75
76
|
<ItemGroup>
|
|
@@ -93,6 +94,7 @@
|
|
|
93
94
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
|
94
95
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
|
95
96
|
</ClCompile>
|
|
97
|
+
<ClCompile Include="table_support.cpp" />
|
|
96
98
|
</ItemGroup>
|
|
97
99
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
98
100
|
<ImportGroup Label="ExtensionTargets">
|
|
@@ -7,10 +7,16 @@
|
|
|
7
7
|
|
|
8
8
|
#include "targetver.h"
|
|
9
9
|
|
|
10
|
-
#
|
|
11
|
-
// Windows Header Files:
|
|
12
|
-
#include <windows.h>
|
|
10
|
+
#include <stdlib.h>
|
|
13
11
|
|
|
12
|
+
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
|
14
13
|
|
|
14
|
+
#include <stdio.h>
|
|
15
|
+
#include <tchar.h>
|
|
16
|
+
#include <windows.h>
|
|
17
|
+
#include <objbase.h>
|
|
18
|
+
#include <OleAcc.h>
|
|
19
|
+
#include <Commctrl.h>
|
|
20
|
+
#include <comutil.h>
|
|
15
21
|
|
|
16
22
|
// TODO: reference additional headers your program requires here
|
|
@@ -0,0 +1,282 @@
|
|
|
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 walk_tree(IAccessible *pAccessible, char **pColumnHeaderNames, long *pColumnHeadersCount) {
|
|
79
|
+
HRESULT hr ;
|
|
80
|
+
long childCount ;
|
|
81
|
+
|
|
82
|
+
hr = pAccessible->get_accChildCount(&childCount) ;
|
|
83
|
+
if (FAILED(hr) || childCount == 0)
|
|
84
|
+
return ;
|
|
85
|
+
|
|
86
|
+
VARIANT *pChildVariants = new VARIANT[childCount] ;
|
|
87
|
+
long childrenFound ;
|
|
88
|
+
hr = AccessibleChildren(pAccessible, 0, childCount, pChildVariants, &childrenFound) ;
|
|
89
|
+
if (FAILED(hr))
|
|
90
|
+
return ;
|
|
91
|
+
|
|
92
|
+
for (int i=1; i < childrenFound + 1; i++) {
|
|
93
|
+
VARIANT vChild = pChildVariants[i] ;
|
|
94
|
+
if (vChild.vt == VT_DISPATCH) {
|
|
95
|
+
IDispatch *pDispatch = vChild.pdispVal ;
|
|
96
|
+
IAccessible *pChildAccessible = NULL ;
|
|
97
|
+
hr = pDispatch->QueryInterface(IID_IAccessible, (void**) &pChildAccessible) ;
|
|
98
|
+
if (hr == S_OK) {
|
|
99
|
+
walk_tree(pChildAccessible, pColumnHeaderNames, pColumnHeadersCount) ;
|
|
100
|
+
|
|
101
|
+
pChildAccessible->Release() ;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
pDispatch->Release() ;
|
|
105
|
+
} else {
|
|
106
|
+
long role ;
|
|
107
|
+
get_role(i, pAccessible, &role) ;
|
|
108
|
+
if (role == 0x19) {
|
|
109
|
+
if (pColumnHeaderNames == NULL) {
|
|
110
|
+
*pColumnHeadersCount = *pColumnHeadersCount + 1 ;
|
|
111
|
+
} else {
|
|
112
|
+
char *headerName = (char *)malloc(sizeof(char) * BUFFER_SIZE) ;
|
|
113
|
+
get_name(i, pAccessible, headerName) ;
|
|
114
|
+
pColumnHeaderNames[i - 1] = headerName ;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
void find_column_headers(IAccessible *pAccessible, char ***pHeaderNames, long *pColumns) {
|
|
122
|
+
long columns = 0 ;
|
|
123
|
+
|
|
124
|
+
walk_tree(pAccessible, NULL, &columns) ;
|
|
125
|
+
|
|
126
|
+
char **pHeaders = (char **)malloc(sizeof(char *) * columns) ;
|
|
127
|
+
walk_tree(pAccessible, pHeaders, &columns) ;
|
|
128
|
+
|
|
129
|
+
*pHeaderNames = pHeaders ;
|
|
130
|
+
*pColumns = columns ;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
char *trimwhitespace(char *str) {
|
|
134
|
+
char *end;
|
|
135
|
+
// Trim leading space
|
|
136
|
+
while(isspace(*str))
|
|
137
|
+
str++;
|
|
138
|
+
if(*str == 0)
|
|
139
|
+
// All spaces?
|
|
140
|
+
return str;
|
|
141
|
+
// Trim trailing space
|
|
142
|
+
end = str + strlen(str) - 1;
|
|
143
|
+
|
|
144
|
+
while(end > str && isspace(*end))
|
|
145
|
+
end--; // Write new null terminator
|
|
146
|
+
|
|
147
|
+
*(end+1) = 0;
|
|
148
|
+
|
|
149
|
+
return str;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
char* remove_column_header_name(char *columnName, char *item) {
|
|
153
|
+
int itemLen = strlen(item) ;
|
|
154
|
+
int columnNameLen = strlen(columnName) ;
|
|
155
|
+
|
|
156
|
+
if (itemLen > 0) {
|
|
157
|
+
char *newItem = (char *)malloc(sizeof(char *) * (itemLen - columnNameLen)) ; // still a bit too long
|
|
158
|
+
|
|
159
|
+
strcpy(newItem, item + columnNameLen + 2) ; // :<space>
|
|
160
|
+
|
|
161
|
+
free(item) ;
|
|
162
|
+
return newItem ;
|
|
163
|
+
} else
|
|
164
|
+
return item ;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
extern "C"
|
|
168
|
+
__declspec( dllexport ) void get_table_strings(HMODULE oleAccModule, HWND controlHwnd, void **tableStrings, long *numberOfRowsOut, long *numberOfColumnsOut) {
|
|
169
|
+
// * to *[] to *[] to * string
|
|
170
|
+
IAccessible *pAccessible ;
|
|
171
|
+
LPFNACCESSIBLEOBJECTFROMWINDOW lpfnAccessibleObjectFromWindow ;
|
|
172
|
+
|
|
173
|
+
lpfnAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)GetProcAddress(oleAccModule, "AccessibleObjectFromWindow");
|
|
174
|
+
|
|
175
|
+
if (HRESULT hResult = lpfnAccessibleObjectFromWindow(controlHwnd, OBJID_CLIENT, IID_IAccessible, (void**)&pAccessible) == S_OK) {
|
|
176
|
+
int numberOfRows = get_number_of_rows(pAccessible) ; // including the header
|
|
177
|
+
long numberOfColumns = 3 ;
|
|
178
|
+
char ***table_rows ;
|
|
179
|
+
char **pHeaderNames ;
|
|
180
|
+
|
|
181
|
+
find_column_headers(pAccessible, &pHeaderNames, &numberOfColumns) ;
|
|
182
|
+
|
|
183
|
+
table_rows = (char ***)malloc(sizeof(char*) * numberOfRows) ;
|
|
184
|
+
table_rows[0] = pHeaderNames ;
|
|
185
|
+
|
|
186
|
+
for (int row = 1; row < numberOfRows; row++) {
|
|
187
|
+
char **table_row = (char **)malloc(sizeof(char*) * numberOfColumns) ;
|
|
188
|
+
|
|
189
|
+
char *mainItem = (char *)malloc(sizeof(char) * BUFFER_SIZE) ;
|
|
190
|
+
get_name(row, pAccessible, mainItem) ;
|
|
191
|
+
|
|
192
|
+
char *description = (char *)malloc(sizeof(char) * 2048) ;
|
|
193
|
+
get_description(row, pAccessible, description) ;
|
|
194
|
+
|
|
195
|
+
char *token ;
|
|
196
|
+
if (strlen(description) > 0)
|
|
197
|
+
token = strtok(description, ",") ;
|
|
198
|
+
else
|
|
199
|
+
token = NULL ;
|
|
200
|
+
|
|
201
|
+
for (int column = 0; column < numberOfColumns; column++) {
|
|
202
|
+
if (column == 0)
|
|
203
|
+
table_row[column] = mainItem ;
|
|
204
|
+
else {
|
|
205
|
+
char *item = (char *)malloc(sizeof(char) * BUFFER_SIZE) ;
|
|
206
|
+
|
|
207
|
+
if (token != NULL) {
|
|
208
|
+
strcpy(item, token) ;
|
|
209
|
+
token = strtok(NULL, ",") ;
|
|
210
|
+
} else
|
|
211
|
+
strcpy(item, "\0") ;
|
|
212
|
+
|
|
213
|
+
table_row[column] = remove_column_header_name(pHeaderNames[column], trimwhitespace(item)) ;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
table_rows[row] = table_row ;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
*tableStrings = table_rows ;
|
|
221
|
+
*numberOfRowsOut = numberOfRows ;
|
|
222
|
+
*numberOfColumnsOut = numberOfColumns ;
|
|
223
|
+
} else {
|
|
224
|
+
*numberOfRowsOut = 0 ;
|
|
225
|
+
*numberOfColumnsOut = 0 ;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
extern "C"
|
|
230
|
+
__declspec( dllexport ) void get_table_row_strings(HMODULE oleAccModule, HWND controlHwnd, void **pTableRow, long row, long *pColumns) {
|
|
231
|
+
long rows ;
|
|
232
|
+
long columns ;
|
|
233
|
+
char *tableStrings ; // pointer to array
|
|
234
|
+
|
|
235
|
+
get_table_strings(oleAccModule, controlHwnd, (void **)&tableStrings, &rows, &columns) ;
|
|
236
|
+
|
|
237
|
+
*pTableRow = ((char ***)tableStrings)[row] ;
|
|
238
|
+
*pColumns = columns ;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
extern "C"
|
|
242
|
+
__declspec( dllexport ) void select_table_row(HMODULE oleAccModule, HWND controlHwnd, long row) {
|
|
243
|
+
IAccessible *pAccessible ;
|
|
244
|
+
LPFNACCESSIBLEOBJECTFROMWINDOW lpfnAccessibleObjectFromWindow ;
|
|
245
|
+
|
|
246
|
+
lpfnAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)GetProcAddress(oleAccModule, "AccessibleObjectFromWindow");
|
|
247
|
+
|
|
248
|
+
if (HRESULT hResult = lpfnAccessibleObjectFromWindow(controlHwnd, OBJID_CLIENT, IID_IAccessible, (void**)&pAccessible) == S_OK) {
|
|
249
|
+
VARIANT varChild ;
|
|
250
|
+
VariantInit(&varChild) ;
|
|
251
|
+
varChild.vt = VT_I4 ;
|
|
252
|
+
varChild.lVal = row ;
|
|
253
|
+
|
|
254
|
+
pAccessible->accSelect(SELFLAG_ADDSELECTION, varChild) ;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
extern "C"
|
|
259
|
+
__declspec( dllexport ) long get_table_row_state(HMODULE oleAccModule, HWND controlHwnd, long row) {
|
|
260
|
+
IAccessible *pAccessible ;
|
|
261
|
+
LPFNACCESSIBLEOBJECTFROMWINDOW lpfnAccessibleObjectFromWindow ;
|
|
262
|
+
|
|
263
|
+
lpfnAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)GetProcAddress(oleAccModule, "AccessibleObjectFromWindow");
|
|
264
|
+
|
|
265
|
+
if (HRESULT hResult = lpfnAccessibleObjectFromWindow(controlHwnd, OBJID_CLIENT, IID_IAccessible, (void**)&pAccessible) == S_OK) {
|
|
266
|
+
VARIANT varChild ;
|
|
267
|
+
VariantInit(&varChild) ;
|
|
268
|
+
varChild.vt = VT_I4 ;
|
|
269
|
+
varChild.lVal = row ;
|
|
270
|
+
|
|
271
|
+
VARIANT varState ;
|
|
272
|
+
|
|
273
|
+
HRESULT hr = pAccessible->get_accState(varChild, &varState) ;
|
|
274
|
+
if (hr == S_OK) {
|
|
275
|
+
if (varState.vt == VT_I4) {
|
|
276
|
+
return varState.lVal ;
|
|
277
|
+
} else
|
|
278
|
+
return FALSE ;
|
|
279
|
+
} else
|
|
280
|
+
return FALSE ;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
Microsoft Visual Studio Solution File, Format Version 11.00
|
|
3
|
+
# Visual C++ Express 2010
|
|
4
|
+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ListViewExplorer", "ListViewExplorer\ListViewExplorer.vcxproj", "{EF611F7A-863F-4062-AAD2-84D150F4D7C0}"
|
|
5
|
+
EndProject
|
|
6
|
+
Global
|
|
7
|
+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
8
|
+
Debug|Win32 = Debug|Win32
|
|
9
|
+
Release|Win32 = Release|Win32
|
|
10
|
+
EndGlobalSection
|
|
11
|
+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
12
|
+
{EF611F7A-863F-4062-AAD2-84D150F4D7C0}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
13
|
+
{EF611F7A-863F-4062-AAD2-84D150F4D7C0}.Debug|Win32.Build.0 = Debug|Win32
|
|
14
|
+
{EF611F7A-863F-4062-AAD2-84D150F4D7C0}.Release|Win32.ActiveCfg = Release|Win32
|
|
15
|
+
{EF611F7A-863F-4062-AAD2-84D150F4D7C0}.Release|Win32.Build.0 = Release|Win32
|
|
16
|
+
EndGlobalSection
|
|
17
|
+
GlobalSection(SolutionProperties) = preSolution
|
|
18
|
+
HideSolutionNode = FALSE
|
|
19
|
+
EndGlobalSection
|
|
20
|
+
EndGlobal
|
|
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
|
+
|