rautomation 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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
+