rautomation 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/.gitignore +9 -8
  2. data/Gemfile.lock +2 -2
  3. data/History.rdoc +13 -0
  4. data/README.rdoc +3 -2
  5. data/Rakefile +30 -10
  6. data/VERSION +1 -1
  7. data/ext/UiaDll/Release/UiaDll.dll +0 -0
  8. data/ext/UiaDll/UiaDll/AssemblyInfo.cpp +40 -0
  9. data/ext/UiaDll/UiaDll/AutomatedComboBox.cpp +66 -0
  10. data/ext/UiaDll/UiaDll/AutomatedComboBox.h +32 -0
  11. data/ext/UiaDll/UiaDll/AutomatedTable.cpp +50 -0
  12. data/ext/UiaDll/UiaDll/AutomatedTable.h +22 -0
  13. data/ext/UiaDll/UiaDll/AutomationClicker.cpp +50 -0
  14. data/ext/UiaDll/UiaDll/AutomationClicker.h +24 -0
  15. data/ext/UiaDll/UiaDll/ExpandCollapseHelper.cpp +53 -0
  16. data/ext/UiaDll/UiaDll/ExpandCollapseHelper.h +22 -0
  17. data/ext/UiaDll/UiaDll/MenuItemSelector.cpp +75 -0
  18. data/ext/UiaDll/UiaDll/MenuItemSelector.h +22 -0
  19. data/ext/UiaDll/UiaDll/ReadMe.txt +8 -18
  20. data/ext/UiaDll/UiaDll/StringHelper.cpp +9 -0
  21. data/ext/UiaDll/UiaDll/StringHelper.h +7 -0
  22. data/ext/UiaDll/UiaDll/ToggleStateHelper.cpp +33 -0
  23. data/ext/UiaDll/UiaDll/ToggleStateHelper.h +10 -0
  24. data/ext/UiaDll/UiaDll/UiaDll.cpp +458 -325
  25. data/ext/UiaDll/UiaDll/UiaDll.h +13 -0
  26. data/ext/UiaDll/UiaDll/UiaDll.vcxproj +45 -28
  27. data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +66 -7
  28. data/ext/UiaDll/UiaDll/app.ico +0 -0
  29. data/ext/UiaDll/UiaDll/app.rc +0 -0
  30. data/ext/UiaDll/UiaDll/dllmain.cpp +5 -23
  31. data/ext/UiaDll/UiaDll/resource.h +3 -0
  32. data/ext/UiaDll/UiaDll/stdafx.cpp +0 -3
  33. data/ext/UiaDll/UiaDll/stdafx.h +23 -18
  34. data/ext/UiaDll/UiaDll.sln +6 -6
  35. data/ext/WindowsForms/Release/WindowsForms.exe +0 -0
  36. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/AboutBox.Designer.cs +0 -0
  37. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/AboutBox.cs +0 -0
  38. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/AboutBox.resx +0 -0
  39. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/DataEntryForm.Designer.cs +0 -0
  40. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/DataEntryForm.cs +0 -0
  41. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/DataEntryForm.resx +0 -0
  42. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/MainFormWindow.Designer.cs +173 -76
  43. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/MainFormWindow.cs +76 -77
  44. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/MainFormWindow.resx +3 -0
  45. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/PersonForm.Designer.cs +0 -0
  46. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/PersonForm.cs +0 -0
  47. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/PersonForm.resx +0 -0
  48. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/Program.cs +0 -0
  49. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/Properties/AssemblyInfo.cs +0 -0
  50. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/Properties/Resources.Designer.cs +0 -0
  51. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/Properties/Resources.resx +0 -0
  52. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/Properties/Settings.Designer.cs +0 -0
  53. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/Properties/Settings.settings +0 -0
  54. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/SimpleElementsForm.Designer.cs +0 -0
  55. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/SimpleElementsForm.cs +0 -0
  56. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/SimpleElementsForm.resx +0 -0
  57. data/ext/WindowsForms/{src/WindowsForms/WindowsForms → WindowsForms}/WindowsForms.csproj +2 -2
  58. data/ext/WindowsForms/{src/WindowsForms/WindowsForms.sln → WindowsForms.sln} +0 -0
  59. data/lib/rautomation/adapter/ms_uia/constants.rb +1 -0
  60. data/lib/rautomation/adapter/ms_uia/control.rb +11 -0
  61. data/lib/rautomation/adapter/ms_uia/functions.rb +8 -5
  62. data/lib/rautomation/adapter/ms_uia/menu.rb +36 -0
  63. data/lib/rautomation/adapter/ms_uia/select_list.rb +4 -12
  64. data/lib/rautomation/adapter/ms_uia/table.rb +90 -11
  65. data/lib/rautomation/adapter/ms_uia/uia_dll.rb +48 -2
  66. data/lib/rautomation/adapter/ms_uia/window.rb +6 -1
  67. data/lib/rautomation/adapter/ms_uia.rb +1 -0
  68. data/spec/adapter/autoit/mouse_spec.rb +2 -2
  69. data/spec/adapter/ms_uia/functions_spec.rb +39 -0
  70. data/spec/adapter/ms_uia/select_list_spec.rb +26 -13
  71. data/spec/adapter/ms_uia/table_spec.rb +96 -2
  72. data/spec/adapter/ms_uia/window_spec.rb +37 -11
  73. data/spec/adapter/win_32/mouse_spec.rb +2 -2
  74. data/spec/adapter/win_32/window_spec.rb +0 -9
  75. data/spec/spec_helper.rb +3 -3
  76. data/spec/window_spec.rb +17 -6
  77. metadata +48 -40
  78. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.cpp +0 -174
  79. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj +0 -95
  80. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.filters +0 -42
  81. data/ext/ListViewExplorer/ListViewExplorer/ListViewExplorer.vcxproj.user +0 -3
  82. data/ext/ListViewExplorer/ListViewExplorer/ReadMe.txt +0 -40
  83. data/ext/ListViewExplorer/ListViewExplorer/stdafx.cpp +0 -8
  84. data/ext/ListViewExplorer/ListViewExplorer/stdafx.h +0 -17
  85. data/ext/ListViewExplorer/ListViewExplorer/table_support.cpp +0 -250
  86. data/ext/ListViewExplorer/ListViewExplorer/table_support.h +0 -2
  87. data/ext/ListViewExplorer/ListViewExplorer/targetver.h +0 -8
  88. data/ext/ListViewExplorer/ListViewExplorer.sln +0 -20
  89. data/ext/ListViewExplorer/ListViewExplorer.suo +0 -0
  90. data/ext/UiaDll/UiaDll.suo +0 -0
  91. data/ext/WindowsForms/bin/WindowsForms.exe +0 -0
  92. data/ext/WindowsForms/src/WindowsForms/WindowsForms.suo +0 -0
data/.gitignore CHANGED
@@ -14,21 +14,22 @@ tmtags
14
14
  *.swp
15
15
 
16
16
  ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
17
+ /coverage
18
+ /rdoc
19
+ /pkg
20
20
 
21
21
  ## PROJECT::SPECIFIC
22
- .idea/*
22
+ /.idea/*
23
23
 
24
- .yardoc/
25
- doc/
24
+ /.yardoc/
25
+ /doc/
26
26
 
27
27
  ## VisualStudio
28
28
  Debug
29
29
  Release
30
30
  ipch
31
31
  *.sdf
32
+ *.suo
32
33
  *.user
33
- !ext/IAccessibleDLL/Release/*.dll
34
-
34
+ *.opensdf
35
+ _ReSharper*/
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rautomation (0.7.2)
4
+ rautomation (0.7.3)
5
5
  ffi
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
10
  diff-lcs (1.1.3)
11
- ffi (1.0.11)
11
+ ffi (1.1.5-x86-mingw32)
12
12
  rake (0.9.2.2)
13
13
  rspec (2.8.0)
14
14
  rspec-core (~> 2.8.0)
data/History.rdoc CHANGED
@@ -1,3 +1,16 @@
1
+ == 0.8.0 / 2012-12-26
2
+
3
+ === MsUia adapter
4
+
5
+ * Add Control#collapse for collapsing values in collapsable items.
6
+ * Add Control#expand for expanding values in expandable items.
7
+ * Add Row#cell(s).
8
+ * Add Table#cell(s).
9
+ * Add Table#row(s).
10
+ * Add Window#menu for selecting menu items.
11
+ * Fire change events when SelectList selections have been changed.
12
+ * Window#child instantiates MsUia adapter Window.
13
+
1
14
  == 0.7.3 / 2012-10-31
2
15
 
3
16
  === Win32 adapter
data/README.rdoc CHANGED
@@ -96,8 +96,9 @@ In case of any problems, feel free to contact me.
96
96
 
97
97
  == Contributors
98
98
 
99
- * Stephan Schwab - http://github.com/snscaimito
100
- * Eric Kessler - http://github.com/enkessler
99
+ * Levi Wilson - https://github.com/leviwilson
100
+ * Eric Kessler - https://github.com/enkessler
101
+ * Stephan Schwab - https://github.com/snscaimito
101
102
 
102
103
  == Note on Patches/Pull Requests
103
104
 
data/Rakefile CHANGED
@@ -3,31 +3,51 @@ require 'bundler'
3
3
 
4
4
  Bundler::GemHelper.install_tasks
5
5
 
6
- task :default => "spec:all"
7
-
8
- namespace :spec do
9
- require 'rspec/core/rake_task'
10
- RSpec::Core::RakeTask.new(:spec)
6
+ namespace :build do
7
+ build_tasks = [
8
+ {:name => :uia_dll, :path => "UiaDll"},
9
+ {:name => :i_accessible_dll, :path => "IAccessibleDLL"},
10
+ {:name => :windows_forms, :path => "WindowsForms"}
11
+ ]
11
12
 
12
- RSpec::Core::RakeTask.new(:rcov) do |spec|
13
- spec.rcov = true
13
+ build_tasks.each do |build_task|
14
+ desc "Build #{build_task[:path]}"
15
+ task build_task[:name] do
16
+ sh "msbuild /property:Configuration=Release ext\\#{build_task[:path]}\\#{build_task[:path]}.sln"
17
+ end
14
18
  end
15
19
 
20
+ desc "Build all external dependencies"
21
+ task :all => build_tasks.map { |t| "build:#{t[:name]}"}
22
+ end
23
+
24
+ task :build => "build:all"
25
+
26
+ namespace :spec do
16
27
  adapters = %w[win_32 autoit ms_uia]
28
+
17
29
  adapters.each do |adapter|
18
- desc "Run specs against #{adapter} adapter"
30
+ desc "Run RSpec code examples against #{adapter} adapter"
19
31
  task adapter do
20
32
  ENV["RAUTOMATION_ADAPTER"] = adapter
21
33
  puts "Running specs for adapter: #{adapter}"
22
- task = Rake::Task["spec:spec"]
34
+ task = Rake::Task["spec"]
23
35
  task.reenable
24
36
  task.invoke
25
37
  end
26
38
  end
27
39
 
28
- desc "Run specs against all adapters"
40
+ desc "Run RSpec code examples against all adapters"
29
41
  task :all => adapters.map {|a| "spec:#{a}"}
30
42
  end
31
43
 
44
+ require 'rspec/core/rake_task'
45
+ RSpec::Core::RakeTask.new(:spec)
46
+ task :spec => :build
47
+
48
+ RSpec::Core::RakeTask.new(:rcov) { |spec| spec.rcov = true }
49
+
32
50
  require 'yard'
33
51
  YARD::Rake::YardocTask.new
52
+
53
+ task :default => "spec:all"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.3
1
+ 0.8.0
Binary file
@@ -0,0 +1,40 @@
1
+ #include "stdafx.h"
2
+
3
+ using namespace System;
4
+ using namespace System::Reflection;
5
+ using namespace System::Runtime::CompilerServices;
6
+ using namespace System::Runtime::InteropServices;
7
+ using namespace System::Security::Permissions;
8
+
9
+ //
10
+ // General Information about an assembly is controlled through the following
11
+ // set of attributes. Change these attribute values to modify the information
12
+ // associated with an assembly.
13
+ //
14
+ [assembly:AssemblyTitleAttribute("UiaDll")];
15
+ [assembly:AssemblyDescriptionAttribute("")];
16
+ [assembly:AssemblyConfigurationAttribute("")];
17
+ [assembly:AssemblyCompanyAttribute("")];
18
+ [assembly:AssemblyProductAttribute("UiaDll")];
19
+ [assembly:AssemblyCopyrightAttribute("Copyright (c) 2012")];
20
+ [assembly:AssemblyTrademarkAttribute("")];
21
+ [assembly:AssemblyCultureAttribute("")];
22
+
23
+ //
24
+ // Version information for an assembly consists of the following four values:
25
+ //
26
+ // Major Version
27
+ // Minor Version
28
+ // Build Number
29
+ // Revision
30
+ //
31
+ // You can specify all the value or you can default the Revision and Build Numbers
32
+ // by using the '*' as shown below:
33
+
34
+ [assembly:AssemblyVersionAttribute("1.0.*")];
35
+
36
+ [assembly:ComVisible(false)];
37
+
38
+ [assembly:CLSCompliantAttribute(true)];
39
+
40
+ [assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
@@ -0,0 +1,66 @@
1
+ #include "StdAfx.h"
2
+ #include "AutomatedComboBox.h"
3
+
4
+ AutomatedComboBox::AutomatedComboBox(const HWND windowHandle)
5
+ {
6
+ _comboControl = AutomationElement::FromHandle(IntPtr(windowHandle));
7
+ }
8
+
9
+ bool AutomatedComboBox::SelectByIndex(const int whichItem)
10
+ {
11
+ try {
12
+ auto selectionItems = _comboControl->FindAll(System::Windows::Automation::TreeScope::Subtree, SelectionCondition);
13
+ Select(selectionItems[whichItem]);
14
+ return true;
15
+ } catch(Exception^ e) {
16
+ Console::WriteLine(e->ToString());
17
+ return false;
18
+ }
19
+ }
20
+
21
+ bool AutomatedComboBox::SelectByValue(const char* whichItem)
22
+ {
23
+ try {
24
+ auto nameCondition = gcnew PropertyCondition(AutomationElement::NameProperty, gcnew String(whichItem));
25
+ auto selectionAndNameCondition = gcnew AndCondition(SelectionCondition, nameCondition);
26
+
27
+ Select(_comboControl->FindFirst(System::Windows::Automation::TreeScope::Subtree, selectionAndNameCondition));
28
+ return true;
29
+ } catch(Exception^ e) {
30
+ Console::WriteLine(e->ToString());
31
+ return false;
32
+ }
33
+ }
34
+
35
+ bool AutomatedComboBox::GetValueByIndex(const int whichItem, char* comboValue, const int comboValueSize)
36
+ {
37
+ try {
38
+ auto selectionItem = SelectionItems[whichItem];
39
+ auto nameProperty = dynamic_cast<String^>(selectionItem->GetCurrentPropertyValue(AutomationElement::NameProperty));
40
+
41
+ StringHelper::CopyToUnmanagedString(nameProperty, comboValue, comboValueSize);
42
+ return true;
43
+ } catch(Exception^ e) {
44
+ Console::WriteLine(e->ToString());
45
+ return false;
46
+ }
47
+ }
48
+
49
+ int AutomatedComboBox::SelectedIndex::get() {
50
+ int selectedIndex = 0;
51
+ for each(AutomationElement^ selectionItem in SelectionItems) {
52
+ auto selectionPattern = dynamic_cast<SelectionItemPattern^>(selectionItem->GetCurrentPattern(SelectionItemPattern::Pattern));
53
+ if( selectionPattern->Current.IsSelected ) {
54
+ return selectedIndex;
55
+ }
56
+ ++selectedIndex;
57
+ }
58
+ return -1;
59
+ }
60
+
61
+
62
+ void AutomatedComboBox::Select(AutomationElement^ itemToSelect)
63
+ {
64
+ auto selectionPattern = dynamic_cast<SelectionItemPattern^>(itemToSelect->GetCurrentPattern(SelectionItemPattern::Pattern));
65
+ selectionPattern->Select();
66
+ }
@@ -0,0 +1,32 @@
1
+ #pragma once
2
+ using namespace System::Windows::Automation;
3
+
4
+ public ref class AutomatedComboBox
5
+ {
6
+ public:
7
+ AutomatedComboBox(const HWND windowHandle);
8
+ bool SelectByIndex(const int whichItem);
9
+ bool SelectByValue(const char* whichItem);
10
+ bool GetValueByIndex(const int whichItem, char* comboValue, const int comboValueSize);
11
+
12
+ property int Count {
13
+ int get() { return SelectionItems->Count; }
14
+ }
15
+
16
+ property int SelectedIndex {
17
+ int get();
18
+ }
19
+
20
+ private:
21
+ AutomationElement^ _comboControl;
22
+ void Select(AutomationElement^ itemToSelect);
23
+
24
+ property AutomationElementCollection^ SelectionItems {
25
+ AutomationElementCollection^ get() { return _comboControl->FindAll(System::Windows::Automation::TreeScope::Subtree, SelectionCondition); }
26
+ }
27
+
28
+ property PropertyCondition^ SelectionCondition {
29
+ PropertyCondition^ get() { return gcnew PropertyCondition(AutomationElement::IsSelectionItemPatternAvailableProperty, true); }
30
+ }
31
+ };
32
+
@@ -0,0 +1,50 @@
1
+ #include "StdAfx.h"
2
+ #include "AutomatedTable.h"
3
+
4
+ AutomatedTable::AutomatedTable(const HWND windowHandle)
5
+ {
6
+ _tableControl = AutomationElement::FromHandle(IntPtr(windowHandle));
7
+ }
8
+
9
+ int AutomatedTable::RowCount::get()
10
+ {
11
+ auto tablePattern = dynamic_cast<TablePattern^>(_tableControl->GetCurrentPattern(TablePattern::Pattern));
12
+ return tablePattern->Current.RowCount;
13
+ }
14
+
15
+ bool AutomatedTable::Exists(const char* whichItem)
16
+ {
17
+ return Exists(gcnew PropertyCondition(AutomationElement::NameProperty, gcnew String(whichItem)));
18
+ }
19
+
20
+ bool AutomatedTable::Exists(const int whichItemIndex, const int whichColumnIndex)
21
+ {
22
+ return nullptr != DataItemAt(whichItemIndex, whichColumnIndex);
23
+ }
24
+
25
+ String^ AutomatedTable::ValueAt(const int whichItemIndex, const int whichItemColumn)
26
+ {
27
+ return DataItemAt(whichItemIndex, whichItemColumn)->Current.Name;
28
+ }
29
+
30
+ AutomationElement^ AutomatedTable::DataItemAt(const int whichItemIndex, const int whichItemColumn)
31
+ {
32
+ auto dataItemProperty = gcnew PropertyCondition(AutomationElement::IsTableItemPatternAvailableProperty, true);
33
+ auto indexProperty = gcnew PropertyCondition(TableItemPattern::RowProperty, whichItemIndex);
34
+ auto columnProperty = gcnew PropertyCondition(TableItemPattern::ColumnProperty, whichItemColumn);
35
+ return _tableControl->FindFirst(System::Windows::Automation::TreeScope::Subtree, gcnew AndCondition(dataItemProperty, indexProperty, columnProperty));
36
+ }
37
+
38
+ bool AutomatedTable::Exists(Condition^ condition)
39
+ {
40
+ auto dataItemProperty = gcnew PropertyCondition(AutomationElement::IsTableItemPatternAvailableProperty, true);
41
+ return _tableControl->FindAll(System::Windows::Automation::TreeScope::Subtree, gcnew AndCondition(dataItemProperty, condition))->Count > 0;
42
+ }
43
+
44
+ void AutomatedTable::Select(const int dataItemIndex)
45
+ {
46
+ auto dataItemProperty = gcnew PropertyCondition(AutomationElement::ControlTypeProperty, ControlType::DataItem);
47
+ auto dataItem = _tableControl->FindAll(System::Windows::Automation::TreeScope::Subtree, dataItemProperty)[dataItemIndex];
48
+ auto selectionItemPattern = dynamic_cast<SelectionItemPattern^>(dataItem->GetCurrentPattern(SelectionItemPattern::Pattern));
49
+ selectionItemPattern->Select();
50
+ }
@@ -0,0 +1,22 @@
1
+ #pragma once
2
+ using namespace System::Windows::Automation;
3
+
4
+ ref class AutomatedTable
5
+ {
6
+ public:
7
+ AutomatedTable(const HWND windowHandle);
8
+ bool Exists(const char* whichItem);
9
+ bool Exists(const int whichItemIndex, const int whichColumnIndex);
10
+ String^ ValueAt(const int whichItemIndex, const int whichColumnIndex);
11
+ void Select(const int dataItemIndex);
12
+
13
+ property int RowCount {
14
+ int get();
15
+ }
16
+
17
+ private:
18
+ AutomationElement^ _tableControl;
19
+ bool Exists(Condition^ condition);
20
+ AutomationElement^ DataItemAt(const int whichItemIndex, const int whichItemRow);
21
+ };
22
+
@@ -0,0 +1,50 @@
1
+ #include "StdAfx.h"
2
+ #include "AutomationClicker.h"
3
+
4
+ AutomationClicker::AutomationClicker(const HWND windowHandle) {
5
+ _automationElement = AutomationElement::FromHandle(IntPtr(windowHandle));
6
+ }
7
+
8
+ void AutomationClicker::Click() {
9
+ if( CanInvoke() ) {
10
+ return Invoke();
11
+ } else if( CanToggle() ) {
12
+ return Toggle();
13
+ } else if( CanSelect() ) {
14
+ return Select();
15
+ }
16
+
17
+ throw gcnew Exception(gcnew String("AutomationElement did not support the InvokePattern, TogglePattern or the SelectionItemPattern"));
18
+ }
19
+
20
+ void AutomationClicker::MouseClick() {
21
+ _automationElement->SetFocus();
22
+ auto clickablePoint = _automationElement->GetClickablePoint();
23
+ Cursor::Position = Point((int)clickablePoint.X, (int)clickablePoint.Y);
24
+ mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
25
+ mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
26
+ }
27
+
28
+ bool AutomationClicker::CanInvoke() {
29
+ return (bool)(_automationElement->GetCurrentPropertyValue(AutomationElement::IsInvokePatternAvailableProperty));
30
+ }
31
+
32
+ void AutomationClicker::Invoke() {
33
+ dynamic_cast<InvokePattern^>(_automationElement->GetCurrentPattern(InvokePattern::Pattern))->Invoke();
34
+ }
35
+
36
+ bool AutomationClicker::CanToggle() {
37
+ return (bool)(_automationElement->GetCurrentPropertyValue(AutomationElement::IsTogglePatternAvailableProperty));
38
+ }
39
+
40
+ void AutomationClicker::Toggle() {
41
+ dynamic_cast<TogglePattern^>(_automationElement->GetCurrentPattern(TogglePattern::Pattern))->Toggle();
42
+ }
43
+
44
+ bool AutomationClicker::CanSelect() {
45
+ return (bool)(_automationElement->GetCurrentPropertyValue(AutomationElement::IsSelectionItemPatternAvailableProperty));
46
+ }
47
+
48
+ void AutomationClicker::Select() {
49
+ dynamic_cast<SelectionItemPattern^>(_automationElement->GetCurrentPattern(SelectionItemPattern::Pattern))->Select();
50
+ }
@@ -0,0 +1,24 @@
1
+ #pragma once
2
+ using namespace System::Windows::Automation;
3
+ using namespace System::Windows::Forms;
4
+ using namespace System::Drawing;
5
+
6
+ ref class AutomationClicker
7
+ {
8
+ public:
9
+ AutomationClicker(const HWND windowHandle);
10
+ void Click();
11
+ void MouseClick();
12
+
13
+ private:
14
+ AutomationElement^ _automationElement;
15
+
16
+ bool CanInvoke();
17
+ void Invoke();
18
+
19
+ bool CanToggle();
20
+ void Toggle();
21
+
22
+ bool CanSelect();
23
+ void Select();
24
+ };
@@ -0,0 +1,53 @@
1
+ #include "StdAfx.h"
2
+ #include "ExpandCollapseHelper.h"
3
+
4
+
5
+ void ExpandCollapseHelper::ExpandByValue(const HWND windowHandle, const char* whichItem)
6
+ {
7
+ Expand(ExpandableItem(windowHandle, whichItem));
8
+ }
9
+
10
+ void ExpandCollapseHelper::ExpandByIndex(const HWND windowHandle, const int whichItemIndex)
11
+ {
12
+ auto expandableItem = ExpandableItems(windowHandle)[whichItemIndex];
13
+ Expand(expandableItem);
14
+ }
15
+
16
+ void ExpandCollapseHelper::CollapseByValue(const HWND windowHandle, const char* whichItem)
17
+ {
18
+ Collapse(ExpandableItem(windowHandle, whichItem));
19
+ }
20
+
21
+ void ExpandCollapseHelper::CollapseByIndex(const HWND windowHandle, const int whichItemIndex)
22
+ {
23
+ auto expandableItem = ExpandableItems(windowHandle)[whichItemIndex];
24
+ Collapse(expandableItem);
25
+ }
26
+
27
+ AutomationElementCollection^ ExpandCollapseHelper::ExpandableItems(const HWND windowHandle)
28
+ {
29
+ auto automationElement = AutomationElement::FromHandle(IntPtr(windowHandle));
30
+ return automationElement->FindAll(System::Windows::Automation::TreeScope::Subtree, IsExpandable);
31
+ }
32
+
33
+ AutomationElement^ ExpandCollapseHelper::ExpandableItem(const HWND windowHandle, const char* whichItem)
34
+ {
35
+ auto automationElement = AutomationElement::FromHandle(IntPtr(windowHandle));
36
+ auto andTheNameMatches = gcnew PropertyCondition(AutomationElement::NameProperty, gcnew String(whichItem));
37
+ return automationElement->FindFirst(System::Windows::Automation::TreeScope::Subtree, gcnew AndCondition(IsExpandable, andTheNameMatches));
38
+ }
39
+
40
+ void ExpandCollapseHelper::Expand(AutomationElement^ automationElement)
41
+ {
42
+ dynamic_cast<ExpandCollapsePattern^>(automationElement->GetCurrentPattern(ExpandCollapsePattern::Pattern))->Expand();
43
+ }
44
+
45
+ void ExpandCollapseHelper::Collapse(AutomationElement^ automationElement)
46
+ {
47
+ dynamic_cast<ExpandCollapsePattern^>(automationElement->GetCurrentPattern(ExpandCollapsePattern::Pattern))->Collapse();
48
+ }
49
+
50
+ PropertyCondition^ ExpandCollapseHelper::IsExpandable::get()
51
+ {
52
+ return gcnew PropertyCondition(AutomationElement::IsExpandCollapsePatternAvailableProperty, true);
53
+ }
@@ -0,0 +1,22 @@
1
+ #pragma once
2
+ using namespace System::Windows::Automation;
3
+
4
+ ref class ExpandCollapseHelper
5
+ {
6
+ public:
7
+ void ExpandByValue(const HWND windowHandle, const char* whichItem);
8
+ void ExpandByIndex(const HWND windowHandle, const int whichItemIndex);
9
+ void CollapseByValue(const HWND windowHandle, const char* whichItem);
10
+ void CollapseByIndex(const HWND windowHandle, const int whichItemIndex);
11
+
12
+ private:
13
+ AutomationElementCollection^ ExpandableItems(const HWND windowHandle);
14
+ AutomationElement^ ExpandableItem(const HWND windowHandle, const char* whichItem);
15
+ void Expand(AutomationElement^ automationElement);
16
+ void Collapse(AutomationElement^ automationElement);
17
+
18
+ property PropertyCondition^ IsExpandable {
19
+ PropertyCondition^ get();
20
+ }
21
+ };
22
+
@@ -0,0 +1,75 @@
1
+ #include "StdAfx.h"
2
+ #include "MenuItemSelector.h"
3
+
4
+ using namespace std;
5
+
6
+ void MenuItemSelector::SelectMenuPath(const HWND windowHandle, list<const char*>& menuItems)
7
+ {
8
+ auto automationElement = AutomationElement::FromHandle(IntPtr(windowHandle));
9
+ auto foundMenuItem = FindMenuItem(automationElement, menuItems);
10
+ auto invokePattern = dynamic_cast<InvokePattern^>(foundMenuItem->GetCurrentPattern(InvokePattern::Pattern));
11
+ invokePattern->Invoke();
12
+ }
13
+
14
+ BOOL MenuItemSelector::MenuItemExists(const HWND windowHandle, list<const char*>& menuItems)
15
+ {
16
+ try {
17
+ auto automationElement = AutomationElement::FromHandle(IntPtr(windowHandle));
18
+ return FindMenuItem(automationElement, menuItems) != nullptr;
19
+ } catch(Exception^ e) {
20
+ return FALSE;
21
+ }
22
+ }
23
+
24
+ AutomationElement^ MenuItemSelector::FindMenuItem(AutomationElement^ rootElement, std::list<const char*>& menuItems)
25
+ {
26
+ auto foundMenuItem = rootElement;
27
+
28
+ for(list<const char*>::iterator menuItem = menuItems.begin(); menuItem != menuItems.end(); ++menuItem) {
29
+ foundMenuItem = GetNextMenuItem(foundMenuItem, gcnew String(*menuItem));
30
+ }
31
+
32
+ return foundMenuItem;
33
+ }
34
+
35
+ PropertyCondition^ MenuItemSelector::NameConditionFor(String^ name)
36
+ {
37
+ return gcnew PropertyCondition(AutomationElement::NameProperty, name);
38
+ }
39
+
40
+ AutomationElement^ MenuItemSelector::GetNextMenuItem(AutomationElement^ foundMenuItem, String^ nextMenu)
41
+ {
42
+ TryToExpand(AsExpandCollapse(foundMenuItem));
43
+ auto nextMenuItem = foundMenuItem->FindFirst(System::Windows::Automation::TreeScope::Subtree,
44
+ gcnew AndCondition(MenuItemControlType, NameConditionFor(nextMenu)));
45
+ if( nullptr == nextMenuItem ) {
46
+ throw gcnew Exception(String::Format("MenuItem with the text \"{0}\" does not exist", nextMenu));
47
+ }
48
+ return nextMenuItem;
49
+ }
50
+
51
+ ExpandCollapsePattern^ MenuItemSelector::AsExpandCollapse(AutomationElement^ foundMenuItem)
52
+ {
53
+ try
54
+ {
55
+ return dynamic_cast<ExpandCollapsePattern^>(foundMenuItem->GetCurrentPattern(ExpandCollapsePattern::Pattern));
56
+ }
57
+ catch(Exception^ e)
58
+ {
59
+ return nullptr;
60
+ }
61
+ }
62
+
63
+ void MenuItemSelector::TryToExpand(ExpandCollapsePattern^ expandCollapsePattern)
64
+ {
65
+ if (nullptr == expandCollapsePattern) return;
66
+
67
+ try
68
+ {
69
+ expandCollapsePattern->Expand();
70
+ }
71
+ catch(Exception^ e)
72
+ {
73
+ expandCollapsePattern->Expand();
74
+ }
75
+ }
@@ -0,0 +1,22 @@
1
+ #pragma once
2
+ using namespace System::Windows::Automation;
3
+
4
+ public ref class MenuItemSelector
5
+ {
6
+ public:
7
+ void SelectMenuPath(const HWND windowHandle, std::list<const char*>& menuItems);
8
+ BOOL MenuItemExists(const HWND windowHandle, std::list<const char*>& menuItems);
9
+
10
+ private:
11
+ AutomationElement^ FindMenuItem(AutomationElement^ rootElement, std::list<const char*>& menuItems);
12
+ PropertyCondition^ NameConditionFor(String^ name);
13
+ AutomationElement^ GetNextMenuItem(AutomationElement^ foundMenuItem, String^ nextMenu);
14
+ ExpandCollapsePattern^ AsExpandCollapse(AutomationElement^ foundMenuItem);
15
+ void TryToExpand(ExpandCollapsePattern^ expandCollapsePattern);
16
+
17
+ property PropertyCondition^ MenuItemControlType {
18
+ private:
19
+ PropertyCondition^ get() { return gcnew PropertyCondition(AutomationElement::ControlTypeProperty, ControlType::MenuItem); }
20
+ }
21
+ };
22
+
@@ -2,15 +2,14 @@
2
2
  DYNAMIC LINK LIBRARY : UiaDll Project Overview
3
3
  ========================================================================
4
4
 
5
- AppWizard has created this UiaDll DLL for you.
5
+ AppWizard has created this UiaDll DLL for you.
6
6
 
7
7
  This file contains a summary of what you will find in each of the files that
8
8
  make up your UiaDll application.
9
9
 
10
-
11
10
  UiaDll.vcxproj
12
- This is the main project file for VC++ projects generated using an Application Wizard.
13
- It contains information about the version of Visual C++ that generated the file, and
11
+ This is the main project file for VC++ projects generated using an Application Wizard.
12
+ It contains information about the version of Visual C++ that generated the file, and
14
13
  information about the platforms, configurations, and project features selected with the
15
14
  Application Wizard.
16
15
 
@@ -24,25 +23,16 @@ UiaDll.vcxproj.filters
24
23
  UiaDll.cpp
25
24
  This is the main DLL source file.
26
25
 
27
- When created, this DLL does not export any symbols. As a result, it
28
- will not produce a .lib file when it is built. If you wish this project
29
- to be a project dependency of some other project, you will either need to
30
- add code to export some symbols from the DLL so that an export library
31
- will be produced, or you can set the Ignore Input Library property to Yes
32
- on the General propert page of the Linker folder in the project's Property
33
- Pages dialog box.
34
-
35
- /////////////////////////////////////////////////////////////////////////////
36
- Other standard files:
26
+ UiaDll.h
27
+ This file contains a class declaration.
37
28
 
38
- StdAfx.h, StdAfx.cpp
39
- These files are used to build a precompiled header (PCH) file
40
- named UiaDll.pch and a precompiled types file named StdAfx.obj.
29
+ AssemblyInfo.cpp
30
+ Contains custom attributes for modifying assembly metadata.
41
31
 
42
32
  /////////////////////////////////////////////////////////////////////////////
43
33
  Other notes:
44
34
 
45
- AppWizard uses "TODO:" comments to indicate parts of the source code you
35
+ AppWizard uses "TODO:" to indicate parts of the source code you
46
36
  should add to or customize.
47
37
 
48
38
  /////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,9 @@
1
+ #include "StdAfx.h"
2
+ #include "StringHelper.h"
3
+
4
+ void StringHelper::CopyToUnmanagedString(String^ source, char* destination, const int destinationSize)
5
+ {
6
+ auto unmanagedString = Marshal::StringToHGlobalAnsi(source);
7
+ strncpy(destination, (const char*)(void*)unmanagedString, destinationSize - 1);
8
+ Marshal::FreeHGlobal(unmanagedString);
9
+ }