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.
Files changed (96) hide show
  1. data/History.rdoc +14 -0
  2. data/README.rdoc +1 -1
  3. data/VERSION +1 -1
  4. data/ext/IAccessibleDLL/IAccessibleDLL.suo +0 -0
  5. data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.cpp +0 -6
  6. data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj +2 -0
  7. data/ext/IAccessibleDLL/IAccessibleDLL/IAccessibleDLL.vcxproj.filters +3 -0
  8. data/ext/IAccessibleDLL/IAccessibleDLL/stdafx.h +9 -3
  9. data/ext/IAccessibleDLL/IAccessibleDLL/table_support.cpp +282 -0
  10. data/ext/IAccessibleDLL/Release/IAccessibleDLL.dll +0 -0
  11. data/ext/ListViewExplorer/ListViewExplorer.sln +20 -0
  12. data/ext/ListViewExplorer/ListViewExplorer.suo +0 -0
  13. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.cpp +174 -0
  14. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj +95 -0
  15. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.filters +42 -0
  16. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.user +3 -0
  17. data/ext/ListViewExplorer/ListViewExplorer/ReadMe.txt +40 -0
  18. data/ext/ListViewExplorer/ListViewExplorer/stdafx.cpp +8 -0
  19. data/ext/ListViewExplorer/ListViewExplorer/stdafx.h +17 -0
  20. data/ext/ListViewExplorer/ListViewExplorer/table_support.cpp +250 -0
  21. data/ext/ListViewExplorer/ListViewExplorer/table_support.h +2 -0
  22. data/ext/ListViewExplorer/ListViewExplorer/targetver.h +8 -0
  23. data/ext/UiaDll/Release/UiaDll.dll +0 -0
  24. data/ext/UiaDll/UiaDll.sln +20 -0
  25. data/ext/UiaDll/UiaDll.suo +0 -0
  26. data/ext/UiaDll/UiaDll/ReadMe.txt +48 -0
  27. data/ext/UiaDll/UiaDll/UiaDll.cpp +205 -0
  28. data/ext/UiaDll/UiaDll/UiaDll.vcxproj +104 -0
  29. data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +42 -0
  30. data/ext/UiaDll/UiaDll/dllmain.cpp +39 -0
  31. data/ext/UiaDll/UiaDll/globals.h +3 -0
  32. data/ext/UiaDll/UiaDll/stdafx.cpp +8 -0
  33. data/ext/UiaDll/UiaDll/stdafx.h +19 -0
  34. data/ext/UiaDll/UiaDll/targetver.h +8 -0
  35. data/ext/WindowsForms/bin/WindowsForms.exe +0 -0
  36. data/ext/WindowsForms/src/WindowsForms/WindowsForms.suo +0 -0
  37. data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.Designer.cs +27 -7
  38. data/ext/WindowsForms/src/WindowsForms/WindowsForms/DataEntryForm.cs +1 -0
  39. data/ext/WindowsForms/src/WindowsForms/WindowsForms/MainFormWindow.Designer.cs +110 -11
  40. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Release/WindowsForms.exe +0 -0
  41. data/lib/rautomation.rb +2 -3
  42. data/lib/rautomation/adapter/autoit.rb +2 -2
  43. data/lib/rautomation/adapter/win_ffi.rb +4 -0
  44. data/lib/rautomation/adapter/win_ffi/button.rb +6 -0
  45. data/lib/rautomation/adapter/win_ffi/checkbox.rb +7 -0
  46. data/lib/rautomation/adapter/win_ffi/constants.rb +44 -3
  47. data/lib/rautomation/adapter/win_ffi/control.rb +36 -3
  48. data/lib/rautomation/adapter/win_ffi/functions.rb +37 -3
  49. data/lib/rautomation/adapter/win_ffi/keystroke_converter.rb +67 -0
  50. data/lib/rautomation/adapter/win_ffi/label.rb +21 -0
  51. data/lib/rautomation/adapter/win_ffi/list_box.rb +60 -0
  52. data/lib/rautomation/adapter/win_ffi/locators.rb +0 -1
  53. data/lib/rautomation/adapter/win_ffi/ms_uia/uia_dll.rb +36 -0
  54. data/lib/rautomation/adapter/win_ffi/radio.rb +7 -0
  55. data/lib/rautomation/adapter/win_ffi/select_list.rb +30 -7
  56. data/lib/rautomation/adapter/win_ffi/table.rb +42 -3
  57. data/lib/rautomation/adapter/win_ffi/text_field.rb +17 -1
  58. data/lib/rautomation/adapter/win_ffi/window.rb +47 -8
  59. data/lib/rautomation/button.rb +5 -0
  60. data/lib/rautomation/element_collections.rb +8 -5
  61. data/lib/rautomation/text_field.rb +10 -0
  62. data/lib/rautomation/window.rb +20 -14
  63. data/spec/adapter/win_ffi/button_spec.rb +41 -0
  64. data/spec/adapter/win_ffi/checkbox_spec.rb +19 -0
  65. data/spec/adapter/win_ffi/keystroke_converter_spec.rb +47 -0
  66. data/spec/adapter/win_ffi/label_spec.rb +21 -0
  67. data/spec/adapter/win_ffi/listbox_spec.rb +52 -0
  68. data/spec/adapter/win_ffi/radio_spec.rb +16 -0
  69. data/spec/adapter/win_ffi/select_list_spec.rb +29 -4
  70. data/spec/adapter/win_ffi/table_spec.rb +20 -1
  71. data/spec/adapter/win_ffi/text_field_spec.rb +23 -0
  72. data/spec/adapter/win_ffi/window_spec.rb +29 -0
  73. data/spec/button_spec.rb +1 -0
  74. data/spec/spec_helper.rb +4 -1
  75. data/spec/text_field_spec.rb +27 -15
  76. metadata +52 -34
  77. data/ext/IAccessibleDLL/Release/IAccessibleDLL.exp +0 -0
  78. data/ext/IAccessibleDLL/Release/IAccessibleDLL.lib +0 -0
  79. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.exe +0 -0
  80. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.pdb +0 -0
  81. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.vshost.exe +0 -0
  82. data/ext/WindowsForms/src/WindowsForms/WindowsForms/bin/Debug/WindowsForms.vshost.exe.manifest +0 -11
  83. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/DesignTimeResolveAssemblyReferences.cache +0 -0
  84. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache +0 -0
  85. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/GenerateResource.read.1.tlog +0 -0
  86. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/GenerateResource.write.1.tlog +0 -0
  87. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/ResolveAssemblyReference.cache +0 -0
  88. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.AboutBox.resources +0 -0
  89. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.DataEntryForm.resources +0 -0
  90. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.MainFormWindow.resources +0 -0
  91. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.PersonForm.resources +0 -0
  92. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.Properties.Resources.resources +0 -0
  93. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.SimpleElementsForm.resources +0 -0
  94. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.csproj.FileListAbsolute.txt +0 -25
  95. data/ext/WindowsForms/src/WindowsForms/WindowsForms/obj/x86/Debug/WindowsForms.exe +0 -0
  96. 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(:text => "&Save")
28
+ button = window.button(:value => "&Save")
29
29
  button.exists? # => true
30
30
  button.click
31
31
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.1
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">
@@ -35,5 +35,8 @@
35
35
  <ClCompile Include="dllmain.cpp">
36
36
  <Filter>Source Files</Filter>
37
37
  </ClCompile>
38
+ <ClCompile Include="table_support.cpp">
39
+ <Filter>Source Files</Filter>
40
+ </ClCompile>
38
41
  </ItemGroup>
39
42
  </Project>
@@ -7,10 +7,16 @@
7
7
 
8
8
  #include "targetver.h"
9
9
 
10
- #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
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
+ }
@@ -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
@@ -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
+