rautomation 0.7.3 → 0.8.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 (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
+ }