rautomation 0.6.3 → 0.7.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 (88) hide show
  1. data/.gitignore +34 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +24 -0
  4. data/History.rdoc +21 -0
  5. data/LICENSE +1 -1
  6. data/README.rdoc +8 -7
  7. data/Rakefile +22 -32
  8. data/VERSION +1 -1
  9. data/ext/UiaDll/Release/UiaDll.dll +0 -0
  10. data/ext/UiaDll/UiaDll.suo +0 -0
  11. data/ext/UiaDll/UiaDll/UiaDll.cpp +236 -10
  12. data/lib/rautomation/adapter/autoit/locators.rb +1 -1
  13. data/lib/rautomation/adapter/autoit/text_field.rb +10 -1
  14. data/lib/rautomation/adapter/autoit/window.rb +50 -23
  15. data/lib/rautomation/adapter/helper.rb +6 -6
  16. data/lib/rautomation/adapter/ms_uia.rb +22 -0
  17. data/lib/rautomation/adapter/{win_ffi → ms_uia}/button.rb +3 -2
  18. data/lib/rautomation/adapter/ms_uia/button_helper.rb +25 -0
  19. data/lib/rautomation/adapter/ms_uia/checkbox.rb +27 -0
  20. data/lib/rautomation/adapter/{win_ffi → ms_uia}/constants.rb +20 -5
  21. data/lib/rautomation/adapter/ms_uia/control.rb +180 -0
  22. data/lib/rautomation/adapter/{win_ffi → ms_uia}/functions.rb +24 -26
  23. data/lib/rautomation/adapter/ms_uia/keystroke_converter.rb +122 -0
  24. data/lib/rautomation/adapter/{win_ffi → ms_uia}/label.rb +3 -2
  25. data/lib/rautomation/adapter/ms_uia/list_box.rb +91 -0
  26. data/lib/rautomation/adapter/ms_uia/list_item.rb +49 -0
  27. data/lib/rautomation/adapter/ms_uia/locators.rb +23 -0
  28. data/lib/rautomation/adapter/{win_ffi → ms_uia}/radio.rb +2 -2
  29. data/lib/rautomation/adapter/{win_ffi → ms_uia}/select_list.rb +41 -7
  30. data/lib/rautomation/adapter/ms_uia/table.rb +86 -0
  31. data/lib/rautomation/adapter/{win_ffi → ms_uia}/text_field.rb +5 -4
  32. data/lib/rautomation/adapter/ms_uia/uia_dll.rb +62 -0
  33. data/lib/rautomation/adapter/ms_uia/window.rb +364 -0
  34. data/lib/rautomation/adapter/win_32.rb +21 -0
  35. data/lib/rautomation/adapter/win_32/button.rb +14 -0
  36. data/lib/rautomation/adapter/{win_ffi → win_32}/button_helper.rb +1 -1
  37. data/lib/rautomation/adapter/win_32/checkbox.rb +14 -0
  38. data/lib/rautomation/adapter/win_32/constants.rb +68 -0
  39. data/lib/rautomation/adapter/{win_ffi → win_32}/control.rb +30 -23
  40. data/lib/rautomation/adapter/win_32/functions.rb +313 -0
  41. data/lib/rautomation/adapter/win_32/keys.rb +121 -0
  42. data/lib/rautomation/adapter/win_32/label.rb +10 -0
  43. data/lib/rautomation/adapter/win_32/list_box.rb +40 -0
  44. data/lib/rautomation/adapter/{win_ffi → win_32}/locators.rb +2 -2
  45. data/lib/rautomation/adapter/win_32/radio.rb +11 -0
  46. data/lib/rautomation/adapter/win_32/select_list.rb +97 -0
  47. data/lib/rautomation/adapter/win_32/table.rb +22 -0
  48. data/lib/rautomation/adapter/win_32/text_field.rb +42 -0
  49. data/lib/rautomation/adapter/{win_ffi → win_32}/window.rb +79 -62
  50. data/lib/rautomation/element_collections.rb +9 -1
  51. data/lib/rautomation/window.rb +17 -9
  52. data/rautomation.gemspec +24 -0
  53. data/spec/adapter/autoit/window_spec.rb +71 -0
  54. data/spec/adapter/{win_ffi → ms_uia}/button_spec.rb +1 -1
  55. data/spec/adapter/{win_ffi → ms_uia}/checkbox_spec.rb +9 -3
  56. data/spec/adapter/ms_uia/control_spec.rb +28 -0
  57. data/spec/adapter/ms_uia/keystroke_converter_spec.rb +50 -0
  58. data/spec/adapter/{win_ffi → ms_uia}/label_spec.rb +2 -2
  59. data/spec/adapter/ms_uia/list_item_spec.rb +14 -0
  60. data/spec/adapter/{win_ffi → ms_uia}/listbox_spec.rb +18 -5
  61. data/spec/adapter/{win_ffi → ms_uia}/radio_spec.rb +3 -1
  62. data/spec/adapter/ms_uia/select_list_spec.rb +109 -0
  63. data/spec/adapter/{win_ffi → ms_uia}/table_spec.rb +12 -1
  64. data/spec/adapter/{win_ffi → ms_uia}/text_field_spec.rb +2 -1
  65. data/spec/adapter/ms_uia/window_spec.rb +89 -0
  66. data/spec/adapter/win_32/button_spec.rb +30 -0
  67. data/spec/adapter/win_32/checkbox_spec.rb +48 -0
  68. data/spec/adapter/win_32/label_spec.rb +15 -0
  69. data/spec/adapter/win_32/listbox_spec.rb +42 -0
  70. data/spec/adapter/win_32/radio_spec.rb +32 -0
  71. data/spec/adapter/{win_ffi → win_32}/select_list_spec.rb +16 -16
  72. data/spec/adapter/win_32/table_spec.rb +28 -0
  73. data/spec/adapter/win_32/text_field_spec.rb +24 -0
  74. data/spec/adapter/{win_ffi → win_32}/window_spec.rb +19 -14
  75. data/spec/button_spec.rb +1 -0
  76. data/spec/buttons_spec.rb +4 -4
  77. data/spec/spec_helper.rb +30 -4
  78. data/spec/text_field_spec.rb +6 -7
  79. data/spec/window_spec.rb +12 -0
  80. data/spec/windows_spec.rb +19 -0
  81. metadata +116 -97
  82. data/lib/rautomation/adapter/win_ffi.rb +0 -21
  83. data/lib/rautomation/adapter/win_ffi/checkbox.rb +0 -19
  84. data/lib/rautomation/adapter/win_ffi/keystroke_converter.rb +0 -67
  85. data/lib/rautomation/adapter/win_ffi/list_box.rb +0 -60
  86. data/lib/rautomation/adapter/win_ffi/ms_uia/uia_dll.rb +0 -36
  87. data/lib/rautomation/adapter/win_ffi/table.rb +0 -57
  88. data/spec/adapter/win_ffi/keystroke_converter_spec.rb +0 -47
data/.gitignore ADDED
@@ -0,0 +1,34 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ .idea/*
23
+
24
+ .yardoc/
25
+ doc/
26
+
27
+ ## VisualStudio
28
+ Debug
29
+ Release
30
+ ipch
31
+ *.sdf
32
+ *.user
33
+ !ext/IAccessibleDLL/Release/*.dll
34
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rautomation (0.7.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ rspec (2.8.0)
11
+ rspec-core (~> 2.8.0)
12
+ rspec-expectations (~> 2.8.0)
13
+ rspec-mocks (~> 2.8.0)
14
+ rspec-core (2.8.0)
15
+ rspec-expectations (2.8.0)
16
+ diff-lcs (~> 1.1.2)
17
+ rspec-mocks (2.8.0)
18
+
19
+ PLATFORMS
20
+ x86-mingw32
21
+
22
+ DEPENDENCIES
23
+ rautomation!
24
+ rspec (~> 2.3)
data/History.rdoc CHANGED
@@ -1,3 +1,24 @@
1
+ == Version 0.7.0 / 2012-xx-xx
2
+
3
+ === All adapters
4
+
5
+ * renamed WinFfi adapter to Win32 adapter
6
+ * added experimental MsUia adapter
7
+ * added support for JRuby
8
+ * Window.windows accepts locators too
9
+ * added Window#class_names for retrieving internal class names of the window and it's controls
10
+ * default locator is :index => 0 when nothing else specified
11
+
12
+ === Win32 adapter
13
+
14
+ * Window#send_keys has now syntax similar to WatirSpec (https://github.com/watir/watirspec/blob/master/element_spec.rb#L206-249)
15
+ * added TextField#send_keys
16
+
17
+ === AutoIt adapter
18
+
19
+ * added Window#mouse_move, #mouse_click, #mouse_position, #press_mouse and #release_mouse methods for AutoIt adapter
20
+
21
+
1
22
  == Version 0.6.3 / 2011-07-16
2
23
 
3
24
  * use current window's handle (hwnd) in WinFfi::Window#child method
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2011 Jarmo Pertman
1
+ Copyright (c) 2010-2012 Jarmo Pertman
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -3,7 +3,7 @@
3
3
  * Web: http://www.github.com/jarmo/RAutomation
4
4
  * Author: Jarmo Pertman (mailto:jarmo.p[at]gmail.com)
5
5
 
6
- == DESCRIPTION
6
+ {<img alt='Click here to lend your support to: RAutomation and make a donation at www.pledgie.com !' src='https://www.pledgie.com/campaigns/16196.png?skin_name=chrome' />}[https://www.pledgie.com/campaigns/16196]
7
7
 
8
8
  RAutomation is a small and easy to use library for helping out to automate windows and their controls
9
9
  for automated testing.
@@ -35,7 +35,7 @@ RAutomation provides:
35
35
  window = RAutomation::Window.new(:title => /part of the title/i)
36
36
  windows = window.windows
37
37
  puts windows.size # => 2
38
- windows.map {|window| window.title } # => ["part of the title 1", "part of the title 2"]
38
+ windows.map &:title # => ["part of the title 1", "part of the title 2"]
39
39
 
40
40
  window.windows(:title => /part of other title/i) # => all windows with matching specified title
41
41
 
@@ -52,12 +52,12 @@ Check out the documentation for other possible usages!
52
52
 
53
53
  === Windows
54
54
 
55
- 1. gem install rautomation
56
- 2. create script and run it
55
+ gem install rautomation
57
56
 
58
57
  Available adapters:
59
- * :ffi - uses Windows API directly with FFI (default)
58
+ * :win_32 - uses Windows API directly with FFI (default)
60
59
  * :autoit - uses AutoIt for automation
60
+ * :ms_uia - an experimental adapter
61
61
 
62
62
  When using AutoIt adapter:
63
63
  You might need administrative privileges if running for the first time and you haven't installed AutoIt before!
@@ -96,7 +96,8 @@ In case of any problems, feel free to contact me.
96
96
 
97
97
  == Contributors
98
98
 
99
- * Stephan Schwab to WinFfi adapter - http://github.com/snscaimito
99
+ * Stephan Schwab - http://github.com/snscaimito
100
+ * Eric Kessler - http://github.com/enkessler
100
101
 
101
102
  == Note on Patches/Pull Requests
102
103
 
@@ -111,4 +112,4 @@ In case of any problems, feel free to contact me.
111
112
 
112
113
  == Copyright
113
114
 
114
- Copyright (c) 2010-2011 Jarmo Pertman. See LICENSE for details.
115
+ Copyright (c) 2010-2012 Jarmo Pertman. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,43 +1,33 @@
1
1
  require 'rubygems'
2
- require 'rake'
2
+ require 'bundler'
3
3
 
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "rautomation"
8
- gem.summary = %Q{Automate windows and their controls through user-friendly API with Ruby}
9
- gem.description = %Q{RAutomation is a small and easy to use library for helping out to automate windows and their controls
10
- for automated testing.
4
+ Bundler::GemHelper.install_tasks
11
5
 
12
- RAutomation provides:
13
- * Easy to use and user-friendly API (inspired by Watir http://www.watir.com)
14
- * Cross-platform compatibility
15
- * Easy extensibility - with small scripting effort it's possible to add support for not yet
16
- supported platforms or technologies}
17
- gem.email = "jarmo.p@gmail.com"
18
- gem.homepage = "http://github.com/jarmo/RAutomation"
19
- gem.authors = ["Jarmo Pertman"]
20
- gem.add_development_dependency "rspec", "~>2.3"
6
+ task :default => "spec:all"
21
7
 
22
- ignored_files = []
23
- ignored_files << ".gitignore" << ".gemspec" << "features" << "IAccessibleDLL.sdf"
24
- gem.files = `git ls-files`.strip.split($/).delete_if {|f| f =~ Regexp.union(*ignored_files)}
8
+ namespace :spec do
9
+ require 'rspec/core/rake_task'
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
13
+ spec.rcov = true
25
14
  end
26
- Jeweler::GemcutterTasks.new
27
- rescue LoadError
28
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
29
- end
30
15
 
31
- require 'rspec/core/rake_task'
32
- RSpec::Core::RakeTask.new(:spec)
16
+ adapters = %w[win_32 autoit ms_uia]
17
+ adapters.each do |adapter|
18
+ desc "Run specs against #{adapter} adapter"
19
+ task adapter do
20
+ ENV["RAUTOMATION_ADAPTER"] = adapter
21
+ puts "Running specs for adapter: #{adapter}"
22
+ task = Rake::Task["spec:spec"]
23
+ task.reenable
24
+ task.invoke
25
+ end
26
+ end
33
27
 
34
- RSpec::Core::RakeTask.new(:rcov) do |spec|
35
- spec.rcov = true
28
+ desc "Run specs against all adapters"
29
+ task :all => adapters.map {|a| "spec:#{a}"}
36
30
  end
37
31
 
38
- task :spec => :check_dependencies
39
-
40
- task :default => :spec
41
-
42
32
  require 'yard'
43
33
  YARD::Rake::YardocTask.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.3
1
+ 0.7.0
Binary file
Binary file
@@ -29,6 +29,32 @@ __declspec( dllexport ) IUIAutomationElement *RA_FindWindow(char *pszAutomationI
29
29
  return NULL ;
30
30
  }
31
31
 
32
+ //This doesn't work
33
+ extern "C"
34
+ __declspec( dllexport ) int RA_FindWindowByPID(int processId, IUIAutomationElement *pElement) {
35
+ IUIAutomationElement *pRootElement;
36
+
37
+ HRESULT hr = getGlobalIUIAutomation()->GetRootElement(&pRootElement);
38
+ if (SUCCEEDED(hr)) {
39
+ IUIAutomationCondition *pCondition;
40
+ VARIANT varProperty;
41
+
42
+ VariantInit(&varProperty);
43
+ varProperty.vt = VT_I4;
44
+ varProperty.intVal = (processId);
45
+
46
+ hr = getGlobalIUIAutomation()->CreatePropertyCondition(UIA_ProcessIdPropertyId, varProperty, &pCondition);
47
+ if (SUCCEEDED(hr)) {
48
+
49
+ hr = pRootElement->FindFirst(TreeScope_Children, pCondition, &pElement);
50
+ if (SUCCEEDED(hr)) {
51
+ return 1;
52
+ }
53
+ }
54
+ }
55
+ return 0;
56
+ }
57
+
32
58
  extern "C"
33
59
  __declspec( dllexport ) BOOL RA_IsOffscreen(IUIAutomationElement *pElement) {
34
60
  BOOL isOffscreen ;
@@ -50,6 +76,37 @@ __declspec ( dllexport ) IUIAutomationElement *RA_ElementFromHandle(HWND hwnd) {
50
76
  }
51
77
  }
52
78
 
79
+ extern "C"
80
+ __declspec ( dllexport ) IUIAutomationElement *RA_GetFocusedElement() {
81
+ IUIAutomationElement *pelement;
82
+
83
+ HRESULT hr = getGlobalIUIAutomation()->GetFocusedElement(&pelement);
84
+
85
+ if (SUCCEEDED(hr))
86
+ return pelement;
87
+ else {
88
+ printf("RA_GetFocusedElement: Cannot find element from focus. HRESULT was 0x%x\r\n", hr) ;
89
+ return false ;
90
+ }
91
+ }
92
+
93
+ extern "C"
94
+ __declspec ( dllexport ) IUIAutomationElement *RA_ElementFromPoint(int xCoord, int yCoord) {
95
+ IUIAutomationElement *pElement ;
96
+ POINT point;
97
+
98
+ point.x = xCoord;
99
+ point.y = yCoord;
100
+
101
+ HRESULT hr = getGlobalIUIAutomation()->ElementFromPoint(point, &pElement) ;
102
+ if (SUCCEEDED(hr))
103
+ return pElement ;
104
+ else {
105
+ printf("RA_ElementFromPoint: Cannot find element from point %d , %d. HRESULT was 0x%x\r\n", xCoord, yCoord, hr) ;
106
+ return NULL ;
107
+ }
108
+ }
109
+
53
110
  extern "C" __declspec ( dllexport ) IUIAutomationElement *RA_FindChildById(IUIAutomationElement *pElement, char *automationId) {
54
111
  IUIAutomationCondition *pCondition ;
55
112
  VARIANT varProperty ;
@@ -78,6 +135,34 @@ extern "C" __declspec ( dllexport ) IUIAutomationElement *RA_FindChildById(IUIAu
78
135
  }
79
136
  }
80
137
 
138
+ extern "C" __declspec ( dllexport ) IUIAutomationElement *RA_FindChildByName(IUIAutomationElement *pElement, char *elementName) {
139
+ IUIAutomationCondition *pCondition ;
140
+ VARIANT varProperty ;
141
+
142
+ VariantInit(&varProperty) ;
143
+ varProperty.vt = VT_BSTR ;
144
+ varProperty.bstrVal = _bstr_t(elementName) ;
145
+
146
+ HRESULT hr = getGlobalIUIAutomation()->CreatePropertyCondition(UIA_NamePropertyId, varProperty, &pCondition) ;
147
+ if (SUCCEEDED(hr)) {
148
+ IUIAutomationElement *pFound ;
149
+
150
+ hr = pElement->FindFirst(TreeScope_Descendants, pCondition, &pFound) ;
151
+ if (SUCCEEDED(hr)) {
152
+ if (pFound == NULL)
153
+ printf("RA_FindChildByName: Element with automation name %s was not found\r\n", elementName) ;
154
+ //printf("RA_FindChildByName: success with value %s\r\n", elementName) ;
155
+ return pFound ;
156
+ } else {
157
+ printf("RA_FindChildByName: FindFirst for children looking for %s failed. hr = 0x%x\r\n", elementName, hr) ;
158
+ return NULL ;
159
+ }
160
+ } else {
161
+ printf("RA_FindChildByName: Cannot create search condition. hr = 0x%x\r\n", hr) ;
162
+ return NULL ;
163
+ }
164
+ }
165
+
81
166
  extern "C" __declspec ( dllexport ) HWND RA_CurrentNativeWindowHandle(IUIAutomationElement *pElement) {
82
167
  UIA_HWND uia_hwnd ;
83
168
 
@@ -90,6 +175,21 @@ extern "C" __declspec ( dllexport ) HWND RA_CurrentNativeWindowHandle(IUIAutomat
90
175
  return (HWND)uia_hwnd ;
91
176
  }
92
177
 
178
+ extern "C" __declspec ( dllexport ) int RA_GetCurrentProcessId(IUIAutomationElement *pElement) {
179
+ HRESULT hr;
180
+ int process_id;
181
+
182
+ hr = pElement->get_CurrentProcessId(&process_id);
183
+
184
+ if (SUCCEEDED(hr)){
185
+ return process_id;
186
+ }
187
+ else {
188
+ printf("RA_GetCurrentProcessId: get_CurrentProcessId returned 0x%x\r\n", hr) ;
189
+ return 0 ;
190
+ }
191
+ }
192
+
93
193
  extern "C" __declspec ( dllexport ) BOOL RA_SetFocus(IUIAutomationElement *pElement) {
94
194
  HRESULT hr = pElement->SetFocus() ;
95
195
  if (hr != S_OK)
@@ -110,6 +210,59 @@ extern "C" __declspec ( dllexport ) int RA_GetCurrentControlType(IUIAutomationEl
110
210
  }
111
211
  }
112
212
 
213
+ extern "C" __declspec ( dllexport ) long RA_ClickMouse() {
214
+ mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
215
+ mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
216
+ return 0;
217
+ }
218
+
219
+ extern "C" __declspec ( dllexport ) long RA_MoveMouse(int x, int y) {
220
+ return SetCursorPos(x,y);
221
+ }
222
+
223
+ extern "C" __declspec ( dllexport ) long RA_GetDesktopHandle() {
224
+ return (long)GetDesktopWindow();
225
+ }
226
+
227
+ extern "C" __declspec ( dllexport ) int RA_CurrentBoundingRectangle(IUIAutomationElement *pElement, long *rectangle) {
228
+ RECT boundary;
229
+
230
+ HRESULT hr = pElement->get_CurrentBoundingRectangle(&boundary) ;
231
+ if (SUCCEEDED(hr)) {
232
+
233
+ rectangle[0] = boundary.left;
234
+ rectangle[1] = boundary.top;
235
+ rectangle[2] = boundary.right;
236
+ rectangle[3] = boundary.bottom;
237
+
238
+ return 1;
239
+ }
240
+ else {
241
+ printf("RA_CurrentBoundingRectangle: get_CurrentBoundingRectangle failed 0x%x\r\n", hr) ;
242
+ return 0 ;
243
+ }
244
+ }
245
+
246
+ extern "C" __declspec ( dllexport ) int RA_CurrentIsOffscreen(IUIAutomationElement *pElement, int *visible) {
247
+ BOOL offscreen;
248
+
249
+ HRESULT hr = pElement->get_CurrentIsOffscreen(&offscreen) ;
250
+ if (SUCCEEDED(hr)) {
251
+ if(offscreen){
252
+ *visible = 1;
253
+ }
254
+ else
255
+ {
256
+ *visible = 0;
257
+ }
258
+ return 1;
259
+ }
260
+ else {
261
+ printf("RA_CurrentIsOffscreen: get_CurrentIsOffscreen failed 0x%x\r\n", hr) ;
262
+ return 0 ;
263
+ }
264
+ }
265
+
113
266
  extern "C" __declspec ( dllexport ) int RA_FindChildren(IUIAutomationElement *pElement, IUIAutomationElement *pChildren[]) {
114
267
  IUIAutomationCondition *pTrueCondition ;
115
268
  IUIAutomationElementArray *pElementArray ;
@@ -153,21 +306,50 @@ extern "C" __declspec ( dllexport ) int RA_FindChildren(IUIAutomationElement *pE
153
306
  extern "C" __declspec ( dllexport ) int RA_GetName(IUIAutomationElement *pElement, char *pName) {
154
307
  BSTR bstrName ;
155
308
  HRESULT hr = pElement->get_CurrentName(&bstrName) ;
309
+
156
310
  if (FAILED(hr)) {
157
311
  printf("RA_GetName: get_CurrentName failed 0x%x\r\n", hr) ;
158
- return 0 ;
312
+ return -1 ;
159
313
  }
160
314
 
161
315
  char *pszName = _com_util::ConvertBSTRToString(bstrName) ;
162
- if (pName == NULL) {
163
- return strlen(pszName) ;
316
+
317
+ if (pszName != NULL){
318
+ if (pName == NULL) {
319
+ return strlen(pszName) ;
320
+ } else {
321
+ strcpy(pName, pszName) ;
322
+ return strlen(pszName) ;
323
+ }
164
324
  } else {
165
- strcpy(pName, pszName) ;
166
- return strlen(pszName) ;
325
+ return -1;
167
326
  }
168
327
  }
169
328
 
170
- extern "C" __declspec ( dllexport ) BOOL RA_GetIsSelected(IUIAutomationElement *pElement, int *pResult) {
329
+ extern "C" __declspec ( dllexport ) int RA_GetClassName(IUIAutomationElement *pElement, char *pClass) {
330
+ BSTR bstrClass ;
331
+ HRESULT hr = pElement->get_CurrentClassName(&bstrClass) ;
332
+
333
+ if (FAILED(hr)) {
334
+ printf("RA_GetName: get_CurrentClassName failed 0x%x\r\n", hr) ;
335
+ return -1 ;
336
+ }
337
+
338
+ char *pszClass = _com_util::ConvertBSTRToString(bstrClass) ;
339
+
340
+ if (pszClass != NULL){
341
+ if (pClass == NULL) {
342
+ return strlen(pszClass) ;
343
+ } else {
344
+ strcpy(pClass, pszClass) ;
345
+ return strlen(pszClass) ;
346
+ }
347
+ } else {
348
+ return -1;
349
+ }
350
+ }
351
+
352
+ extern "C" __declspec ( dllexport ) BOOL RA_GetIsSelected(IUIAutomationElement *pElement) {
171
353
  ISelectionItemProvider *pSelectionPattern ;
172
354
  HRESULT hr = pElement->GetCurrentPattern(UIA_SelectionItemPatternId, (IUnknown**)&pSelectionPattern) ;
173
355
 
@@ -176,14 +358,13 @@ extern "C" __declspec ( dllexport ) BOOL RA_GetIsSelected(IUIAutomationElement *
176
358
  return FALSE ;
177
359
  }
178
360
 
179
- BOOL pRetVal ;
180
- hr = pSelectionPattern->get_IsSelected(&pRetVal) ;
361
+ BOOL RetVal ;
362
+ hr = pSelectionPattern->get_IsSelected(&RetVal) ;
181
363
  if (FAILED(hr)) {
182
364
  printf("RA_GetIsSelected: get_IsSelected failed 0x%x\r\n", hr) ;
183
365
  return FALSE ;
184
366
  } else {
185
- *pResult = pRetVal ;
186
- return TRUE ;
367
+ return RetVal ;
187
368
  }
188
369
  }
189
370
 
@@ -203,3 +384,48 @@ extern "C" __declspec ( dllexport ) int RA_Select(IUIAutomationElement *pElement
203
384
 
204
385
  return 1;
205
386
  }
387
+
388
+ extern "C" __declspec ( dllexport ) int RA_Set_Value(IUIAutomationElement *pElement, char *pValue) {
389
+ IValueProvider *pValuePattern ;
390
+ HRESULT hr = pElement->GetCurrentPattern(UIA_ValuePatternId, (IUnknown**)&pValuePattern) ;
391
+
392
+ if (FAILED(hr)) {
393
+ printf("RA_Set_Value: getCurrentPattern failed 0x%x\r\n") ;
394
+ return 0 ;
395
+ }
396
+
397
+ BSTR unicodestr;
398
+
399
+ int lenA = lstrlenA(pValue);
400
+ int lenW = ::MultiByteToWideChar(CP_ACP, 0, pValue, lenA, 0, 0);
401
+
402
+ if (lenW > 0)
403
+ {
404
+ unicodestr = ::SysAllocStringLen(0, lenW);
405
+ ::MultiByteToWideChar(CP_ACP, 0, pValue, lenA, unicodestr, lenW);
406
+ }
407
+ else
408
+ {
409
+ printf("RA_Set_Value: conversion to unicode string failed\r\n");
410
+ }
411
+
412
+ hr = pValuePattern->SetValue(unicodestr);
413
+ ::SysFreeString(unicodestr);
414
+
415
+
416
+
417
+ if (FAILED(hr)) {
418
+ printf("RA_SetValue: SetValue failed 0x%x\r\n", hr) ;
419
+ return 0 ;
420
+ }
421
+
422
+ //It'd be great if this worked
423
+ /*hr = UiaRaiseAutomationEvent((IRawElementProviderSimple*) pElement, UIA_Selection_InvalidatedEventId);
424
+ if (FAILED(hr)) {
425
+ printf("RA_SetValue: UiaRaiseAutomationEvent failed 0x%x\r\n", hr) ;
426
+ return 0 ;
427
+ }*/
428
+
429
+ return 1;
430
+ }
431
+