rautomation 0.6.3 → 0.7.0

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