From 2027c0a502dd962ace1206b877c1ca9f71acbab4 Mon Sep 17 00:00:00 2001 From: Zoey Riordan Date: Fri, 13 Dec 2019 15:06:46 -0800 Subject: [PATCH] hook up UIA tree to WPF control --- .../PublicTerminalCore/HwndTerminal.cpp | 112 ++++++++++++++++-- .../PublicTerminalCore/HwndTerminal.hpp | 17 ++- .../PublicTerminalCore.vcxproj.filters | 12 ++ src/cascadia/PublicTerminalCore/pch.h | 4 + .../TermControlAutomationPeer.cpp | 30 ++++- .../TermControlAutomationPeer.h | 14 ++- .../TerminalControl/TerminalControl.vcxproj | 4 - .../WpfTerminalControl/NativeMethods.cs | 3 + .../WpfTerminalControl/TerminalContainer.cs | 7 +- .../TerminalControl.xaml.cs | 2 +- src/types/IControlInfo.h | 15 +++ src/types/ScreenInfoUiaProviderBase.h | 2 +- .../TermControlUiaProvider.cpp | 47 ++++---- .../TermControlUiaProvider.hpp | 23 ++-- .../TermControlUiaTextRange.cpp} | 38 +++--- .../TermControlUiaTextRange.hpp} | 10 +- src/types/lib/types.vcxproj | 4 + src/types/lib/types.vcxproj.filters | 14 ++- src/types/sources.inc | 2 + 19 files changed, 277 insertions(+), 83 deletions(-) create mode 100644 src/types/IControlInfo.h rename src/{cascadia/TerminalControl => types}/TermControlUiaProvider.cpp (73%) rename src/{cascadia/TerminalControl => types}/TermControlUiaProvider.hpp (79%) rename src/{cascadia/TerminalControl/UiaTextRange.cpp => types/TermControlUiaTextRange.cpp} (73%) rename src/{cascadia/TerminalControl/UiaTextRange.hpp => types/TermControlUiaTextRange.hpp} (88%) diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index 0499bb0896a..f9a08df137b 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -3,24 +3,40 @@ #include "pch.h" #include "HwndTerminal.hpp" +#include "../../types/TermControlUiaProvider.hpp" #include #include "../../renderer/base/Renderer.hpp" #include "../../renderer/dx/DxRenderer.hpp" #include "../../cascadia/TerminalCore/Terminal.hpp" #include "../../types/viewport.cpp" #include "../../types/inc/GlyphWidth.hpp" +#include using namespace ::Microsoft::Terminal::Core; static LPCWSTR term_window_class = L"HwndTerminalClass"; -static LRESULT CALLBACK HwndTerminalWndProc( +LRESULT CALLBACK HwndTerminal::HwndTerminalWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, - LPARAM lParam) noexcept + LPARAM lParam) { - return DefWindowProcW(hwnd, uMsg, wParam, lParam); + HwndTerminal* terminal = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); + + if (terminal) + { + switch (uMsg) + { + case WM_GETOBJECT: + if (static_cast(lParam) == static_cast(UiaRootObjectId)) + { + auto lock = terminal->_terminal->LockForWriting(); + return UiaReturnRawElementProvider(hwnd, wParam, lParam, terminal->_GetUiaProvider()); + } + } + } + return DefWindowProc(hwnd, uMsg, wParam, lParam); } static bool RegisterTermClass(HINSTANCE hInstance) noexcept @@ -32,7 +48,7 @@ static bool RegisterTermClass(HINSTANCE hInstance) noexcept } wc.style = 0; - wc.lpfnWndProc = HwndTerminalWndProc; + wc.lpfnWndProc = HwndTerminal::HwndTerminalWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; @@ -47,7 +63,8 @@ static bool RegisterTermClass(HINSTANCE hInstance) noexcept HwndTerminal::HwndTerminal(HWND parentHwnd) : _desiredFont{ DEFAULT_FONT_FACE, 0, 10, { 0, 14 }, CP_UTF8 }, - _actualFont{ DEFAULT_FONT_FACE, 0, 10, { 0, 14 }, CP_UTF8, false } + _actualFont{ DEFAULT_FONT_FACE, 0, 10, { 0, 14 }, CP_UTF8, false }, + _uiaProvider{ nullptr } { HINSTANCE hInstance = wil::GetModuleInstanceHandle(); @@ -69,6 +86,8 @@ HwndTerminal::HwndTerminal(HWND parentHwnd) : nullptr, hInstance, nullptr)); + + SetWindowLongPtr(_hwnd.get(), GWLP_USERDATA, reinterpret_cast(this)); } } @@ -141,6 +160,16 @@ void HwndTerminal::RegisterWriteCallback(const void _stdcall callback(wchar_t*)) }); } +::Microsoft::Console::Types::IUiaData* HwndTerminal::GetUiaData() const +{ + return _terminal.get(); +} + +HWND HwndTerminal::GetHwnd() const +{ + return _hwnd.get(); +} + void HwndTerminal::_UpdateFont(int newDpi) { auto lock = _terminal->LockForWriting(); @@ -150,6 +179,24 @@ void HwndTerminal::_UpdateFont(int newDpi) _renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont); } +IRawElementProviderSimple* HwndTerminal::_GetUiaProvider() +{ + if (nullptr == _uiaProvider) + { + try + { + THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, this->GetUiaData(), this)); + } + catch (...) + { + LOG_HR(wil::ResultFromCaughtException()); + _uiaProvider = nullptr; + } + } + + return _uiaProvider.Get(); +} + HRESULT HwndTerminal::Refresh(const SIZE windowSize, _Out_ COORD* dimensions) { RETURN_HR_IF_NULL(E_INVALIDARG, dimensions); @@ -186,10 +233,27 @@ void HwndTerminal::SendOutput(std::wstring_view data) HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal) { - auto _terminal = std::make_unique(parentHwnd); + auto _hostWindow = CreateWindowEx( + 0, + L"static", + nullptr, + WS_CHILD | + WS_CLIPCHILDREN | + WS_CLIPSIBLINGS | + WS_VISIBLE, + 0, + 0, + 0, + 0, + parentHwnd, + (HMENU)0x02, + nullptr, + 0 + ); + auto _terminal = std::make_unique(_hostWindow); RETURN_IF_FAILED(_terminal->Initialize()); - *hwnd = _terminal->_hwnd.get(); + *hwnd = _hostWindow; *terminal = _terminal.release(); return S_OK; @@ -216,6 +280,16 @@ void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data) HRESULT _stdcall TerminalTriggerResize(void* terminal, double width, double height, _Out_ COORD* dimensions) { const auto publicTerminal = static_cast(terminal); + + SetWindowPos( + publicTerminal->GetHwnd(), + nullptr, + 0, + 0, + static_cast(width), + static_cast(height), + 0 + ); const SIZE windowSize{ static_cast(width), static_cast(height) }; return publicTerminal->Refresh(windowSize, dimensions); @@ -413,3 +487,27 @@ void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible) const auto publicTerminal = static_cast(terminal); publicTerminal->_terminal->SetCursorVisible(visible); } + +COORD HwndTerminal::GetFontSize() +{ + return _actualFont.GetSize(); +} + +RECT HwndTerminal::GetBounds() +{ + RECT windowRect; + GetWindowRect(_hwnd.get(), &windowRect); + return windowRect; +} + +RECT HwndTerminal::GetPadding() +{ + return { + 0, 0, 0, 0, + }; +} + +HRESULT HwndTerminal::GetHostUiaProvider(IRawElementProviderSimple** provider) +{ + return UiaHostProviderFromHwnd(_hwnd.get(), provider); +} diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.hpp b/src/cascadia/PublicTerminalCore/HwndTerminal.hpp index 29785524a56..3607f27466e 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.hpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.hpp @@ -6,6 +6,9 @@ #include "../../renderer/base/Renderer.hpp" #include "../../renderer/dx/DxRenderer.hpp" #include "../../cascadia/TerminalCore/Terminal.hpp" +#include +#include "../../types/IControlInfo.h" +#include "../../types/TermControlUiaProvider.hpp" using namespace Microsoft::Console::VirtualTerminal; @@ -39,7 +42,7 @@ __declspec(dllexport) void _stdcall TerminalBlinkCursor(void* terminal); __declspec(dllexport) void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible); }; -struct HwndTerminal +struct HwndTerminal : ::Microsoft::Console::Types::IControlInfo { public: HwndTerminal(HWND hwnd); @@ -48,11 +51,16 @@ struct HwndTerminal HRESULT Refresh(const SIZE windowSize, _Out_ COORD* dimensions); void RegisterScrollCallback(std::function callback); void RegisterWriteCallback(const void _stdcall callback(wchar_t*)); + ::Microsoft::Console::Types::IUiaData* GetUiaData() const; + HWND GetHwnd() const; + + static LRESULT CALLBACK HwndTerminalWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); private: wil::unique_hwnd _hwnd; FontInfoDesired _desiredFont; FontInfo _actualFont; + ::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider; std::unique_ptr<::Microsoft::Terminal::Core::Terminal> _terminal; @@ -74,4 +82,11 @@ struct HwndTerminal friend void _stdcall TerminalBlinkCursor(void* terminal); friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible); void _UpdateFont(int newDpi); + IRawElementProviderSimple* _GetUiaProvider(); + + // Inherited via IControlInfo + virtual COORD GetFontSize() override; + virtual RECT GetBounds() override; + virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override; + virtual RECT GetPadding() override; }; diff --git a/src/cascadia/PublicTerminalCore/PublicTerminalCore.vcxproj.filters b/src/cascadia/PublicTerminalCore/PublicTerminalCore.vcxproj.filters index 446e02bf119..48f0587b2f8 100644 --- a/src/cascadia/PublicTerminalCore/PublicTerminalCore.vcxproj.filters +++ b/src/cascadia/PublicTerminalCore/PublicTerminalCore.vcxproj.filters @@ -24,6 +24,12 @@ Source Files + + Source Files + + + Source Files + @@ -32,5 +38,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/src/cascadia/PublicTerminalCore/pch.h b/src/cascadia/PublicTerminalCore/pch.h index c788085d430..6a89c0d9c4a 100644 --- a/src/cascadia/PublicTerminalCore/pch.h +++ b/src/cascadia/PublicTerminalCore/pch.h @@ -1,4 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN // If this is not defined, windows.h includes commdlg.h which defines FindText globally and conflicts with UIAutomation ITextRangeProvider. +#endif + #include diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp index 40ae55f4be4..caa5f95d151 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp @@ -28,9 +28,10 @@ namespace XamlAutomation namespace winrt::Microsoft::Terminal::TerminalControl::implementation { TermControlAutomationPeer::TermControlAutomationPeer(winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl* owner) : - TermControlAutomationPeerT(*owner) // pass owner to FrameworkElementAutomationPeer + TermControlAutomationPeerT(*owner), // pass owner to FrameworkElementAutomationPeer + _termControl{ owner } { - THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, owner, std::bind(&TermControlAutomationPeer::GetBoundingRectWrapped, this))); + THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, _termControl->GetUiaData(), this)); }; // Method Description: @@ -159,7 +160,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation #pragma endregion - RECT TermControlAutomationPeer::GetBoundingRectWrapped() +#pragma region IControlInfo + COORD TermControlAutomationPeer::GetFontSize() + { + return _termControl->GetActualFont().GetSize(); + } + + RECT TermControlAutomationPeer::GetBounds() { auto rect = GetBoundingRectangle(); return { @@ -170,6 +177,23 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation }; } + HRESULT TermControlAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider) + { + return S_OK; + } + + RECT TermControlAutomationPeer::GetPadding() + { + auto padding = _termControl->GetPadding(); + return { + gsl::narrow(padding.Left), + gsl::narrow(padding.Top), + gsl::narrow(padding.Right), + gsl::narrow(padding.Bottom) + } + } +#pragma endregion + // Method Description: // - extracts the UiaTextRanges from the SAFEARRAY and converts them to Xaml ITextRangeProviders // Arguments: diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.h b/src/cascadia/TerminalControl/TermControlAutomationPeer.h index d5bfc4b09d1..ac6eca4ae50 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.h +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.h @@ -29,12 +29,14 @@ Author(s): #include #include "TermControlUiaProvider.hpp" #include "../types/IUiaEventDispatcher.h" +#include "../types/IControlInfo.h" namespace winrt::Microsoft::Terminal::TerminalControl::implementation { struct TermControlAutomationPeer : public TermControlAutomationPeerT, - ::Microsoft::Console::Types::IUiaEventDispatcher + ::Microsoft::Console::Types::IUiaEventDispatcher, + ::Microsoft::Console::Types::IControlInfo, { public: TermControlAutomationPeer(winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl* owner); @@ -59,11 +61,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange(); #pragma endregion +#pragma region IControlInfo Pattern + // Inherited via IControlInfo + virtual COORD GetFontSize() override; + virtual RECT GetBounds() override; + virtual RECT GetPadding() override; + virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override; +#pragma endregion + RECT GetBoundingRectWrapped(); private: ::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider; - + winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl* _termControl; winrt::com_array WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges); }; } diff --git a/src/cascadia/TerminalControl/TerminalControl.vcxproj b/src/cascadia/TerminalControl/TerminalControl.vcxproj index ad008d5129c..a4804a9b990 100644 --- a/src/cascadia/TerminalControl/TerminalControl.vcxproj +++ b/src/cascadia/TerminalControl/TerminalControl.vcxproj @@ -36,7 +36,6 @@ SearchBoxControl.xaml - TermControl.idl @@ -46,7 +45,6 @@ TSFInputControl.idl - @@ -57,7 +55,6 @@ SearchBoxControl.xaml - TermControl.idl @@ -68,7 +65,6 @@ TermControlAutomationPeer.idl - diff --git a/src/cascadia/WpfTerminalControl/NativeMethods.cs b/src/cascadia/WpfTerminalControl/NativeMethods.cs index d56908575ce..9273ca03149 100644 --- a/src/cascadia/WpfTerminalControl/NativeMethods.cs +++ b/src/cascadia/WpfTerminalControl/NativeMethods.cs @@ -7,6 +7,7 @@ namespace Microsoft.Terminal.Wpf { using System; using System.Runtime.InteropServices; + using System.Windows.Automation.Provider; #pragma warning disable SA1600 // Elements should be documented internal static class NativeMethods @@ -36,6 +37,8 @@ public enum WindowMessage : int /// WM_MOUSEACTIVATE = 0x0021, + WM_GETOBJECT = 0x003D, + /// /// The WM_WINDOWPOSCHANGED message is sent to a window whose size, position, or place in the Z order has changed as a result of a call to the SetWindowPos function or another window-management function. /// diff --git a/src/cascadia/WpfTerminalControl/TerminalContainer.cs b/src/cascadia/WpfTerminalControl/TerminalContainer.cs index ba21d1fa72b..b447108225c 100644 --- a/src/cascadia/WpfTerminalControl/TerminalContainer.cs +++ b/src/cascadia/WpfTerminalControl/TerminalContainer.cs @@ -26,7 +26,7 @@ public class TerminalContainer : HwndHost private DispatcherTimer blinkTimer; private NativeMethods.ScrollCallback scrollCallback; private NativeMethods.WriteCallback writeCallback; - + /// /// Initializes a new instance of the class. /// @@ -35,7 +35,7 @@ public TerminalContainer() this.MessageHook += this.TerminalContainer_MessageHook; this.GotFocus += this.TerminalContainer_GotFocus; this.Focusable = true; - + var blinkTime = NativeMethods.GetCaretBlinkTime(); if (blinkTime != uint.MaxValue) @@ -72,6 +72,8 @@ public TerminalContainer() /// internal int Columns { get; private set; } + internal IntPtr Hwnd => this.hwnd; + /// /// Sets the connection to the terminal backend. /// @@ -172,7 +174,6 @@ protected override void OnDpiChanged(DpiScale oldDpi, DpiScale newDpi) protected override HandleRef BuildWindowCore(HandleRef hwndParent) { var dpiScale = VisualTreeHelper.GetDpi(this); - NativeMethods.CreateTerminal(hwndParent.Handle, out this.hwnd, out this.terminal); this.scrollCallback = this.OnScroll; diff --git a/src/cascadia/WpfTerminalControl/TerminalControl.xaml.cs b/src/cascadia/WpfTerminalControl/TerminalControl.xaml.cs index f068d0edfd3..edb01e2e9aa 100644 --- a/src/cascadia/WpfTerminalControl/TerminalControl.xaml.cs +++ b/src/cascadia/WpfTerminalControl/TerminalControl.xaml.cs @@ -9,7 +9,7 @@ namespace Microsoft.Terminal.Wpf using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; - + /// /// A basic terminal control. This control can receive and render standard VT100 sequences. /// diff --git a/src/types/IControlInfo.h b/src/types/IControlInfo.h new file mode 100644 index 00000000000..95b18891eb8 --- /dev/null +++ b/src/types/IControlInfo.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace Microsoft::Console::Types +{ + class IControlInfo + { + public: + virtual COORD GetFontSize() = 0; + virtual RECT GetBounds() = 0; + virtual RECT GetPadding() = 0; + virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) = 0; + }; +} \ No newline at end of file diff --git a/src/types/ScreenInfoUiaProviderBase.h b/src/types/ScreenInfoUiaProviderBase.h index 82bdd31fcb0..10ede6464c2 100644 --- a/src/types/ScreenInfoUiaProviderBase.h +++ b/src/types/ScreenInfoUiaProviderBase.h @@ -54,7 +54,7 @@ namespace Microsoft::Console::Types _COM_Outptr_result_maybenull_ IUnknown** ppInterface) override; IFACEMETHODIMP GetPropertyValue(_In_ PROPERTYID idProp, _Out_ VARIANT* pVariant) noexcept override; - IFACEMETHODIMP get_HostRawElementProvider(_COM_Outptr_result_maybenull_ IRawElementProviderSimple** ppProvider) noexcept override; + virtual IFACEMETHODIMP get_HostRawElementProvider(_COM_Outptr_result_maybenull_ IRawElementProviderSimple** ppProvider) noexcept override; // IRawElementProviderFragment methods virtual IFACEMETHODIMP Navigate(_In_ NavigateDirection direction, diff --git a/src/cascadia/TerminalControl/TermControlUiaProvider.cpp b/src/types/TermControlUiaProvider.cpp similarity index 73% rename from src/cascadia/TerminalControl/TermControlUiaProvider.cpp rename to src/types/TermControlUiaProvider.cpp index 353d30a28bf..bb738641346 100644 --- a/src/cascadia/TerminalControl/TermControlUiaProvider.cpp +++ b/src/types/TermControlUiaProvider.cpp @@ -1,22 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -#include "pch.h" +#include "precomp.h" #include "TermControlUiaProvider.hpp" -#include "TermControl.h" using namespace Microsoft::Terminal; using namespace Microsoft::Console::Types; using namespace Microsoft::WRL; -HRESULT TermControlUiaProvider::RuntimeClassInitialize(_In_ winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl* termControl, - _In_ std::function GetBoundingRect) +HRESULT TermControlUiaProvider::RuntimeClassInitialize(_In_ ::Microsoft::Console::Types::IUiaData* const uiaData, + _In_ ::Microsoft::Console::Types::IControlInfo* controlInfo) { - RETURN_HR_IF_NULL(E_INVALIDARG, termControl); - RETURN_IF_FAILED(ScreenInfoUiaProviderBase::RuntimeClassInitialize(termControl->GetUiaData())); + RETURN_HR_IF_NULL(E_INVALIDARG, uiaData); + RETURN_IF_FAILED(ScreenInfoUiaProviderBase::RuntimeClassInitialize(uiaData)); - _getBoundingRect = GetBoundingRect; - _termControl = termControl; + _controlInfo = controlInfo; // TODO GitHub #1914: Re-attach Tracing to UIA Tree //Tracing::s_TraceUia(nullptr, ApiCall::Constructor, nullptr); @@ -56,7 +54,7 @@ IFACEMETHODIMP TermControlUiaProvider::get_BoundingRectangle(_Out_ UiaRect* pRec // TODO GitHub #1914: Re-attach Tracing to UIA Tree //Tracing::s_TraceUia(this, ApiCall::GetBoundingRectangle, nullptr); - RECT rc = _getBoundingRect(); + RECT rc = _controlInfo->GetBounds(); pRect->left = rc.left; pRect->top = rc.top; @@ -66,6 +64,11 @@ IFACEMETHODIMP TermControlUiaProvider::get_BoundingRectangle(_Out_ UiaRect* pRec return S_OK; } +IFACEMETHODIMP TermControlUiaProvider::get_HostRawElementProvider(_COM_Outptr_result_maybenull_ IRawElementProviderSimple** ppProvider) noexcept +{ + return _controlInfo->GetHostUiaProvider(ppProvider); +} + IFACEMETHODIMP TermControlUiaProvider::get_FragmentRoot(_COM_Outptr_result_maybenull_ IRawElementProviderFragmentRoot** ppProvider) { // TODO GitHub #1914: Re-attach Tracing to UIA Tree @@ -87,12 +90,12 @@ IFACEMETHODIMP TermControlUiaProvider::get_FragmentRoot(_COM_Outptr_result_maybe const COORD TermControlUiaProvider::GetFontSize() const { - return _termControl->GetActualFont().GetSize(); + return _controlInfo->GetFontSize(); } -const winrt::Windows::UI::Xaml::Thickness TermControlUiaProvider::GetPadding() const +const RECT TermControlUiaProvider::GetPadding() const { - return _termControl->GetPadding(); + return _controlInfo->GetPadding(); } HRESULT TermControlUiaProvider::GetSelectionRanges(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _Out_ std::deque>& result) @@ -102,8 +105,8 @@ HRESULT TermControlUiaProvider::GetSelectionRanges(_In_ IRawElementProviderSimpl result.clear(); typename std::remove_reference::type temporaryResult; - std::deque> ranges; - RETURN_IF_FAILED(UiaTextRange::GetSelectionRanges(_pData, pProvider, wordDelimiters, ranges)); + std::deque> ranges; + RETURN_IF_FAILED(TermControlUiaTextRange::GetSelectionRanges(_pData, pProvider, wordDelimiters, ranges)); while (!ranges.empty()) { @@ -121,8 +124,8 @@ HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple* { RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr); *ppUtr = nullptr; - UiaTextRange* result = nullptr; - RETURN_IF_FAILED(MakeAndInitialize(&result, _pData, pProvider, wordDelimiters)); + TermControlUiaTextRange* result = nullptr; + RETURN_IF_FAILED(MakeAndInitialize(&result, _pData, pProvider, wordDelimiters)); *ppUtr = result; return S_OK; } @@ -134,8 +137,8 @@ HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple* { RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr); *ppUtr = nullptr; - UiaTextRange* result = nullptr; - RETURN_IF_FAILED(MakeAndInitialize(&result, _pData, pProvider, cursor, wordDelimiters)); + TermControlUiaTextRange* result = nullptr; + RETURN_IF_FAILED(MakeAndInitialize(&result, _pData, pProvider, cursor, wordDelimiters)); *ppUtr = result; return S_OK; } @@ -148,8 +151,8 @@ HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple* { RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr); *ppUtr = nullptr; - UiaTextRange* result = nullptr; - RETURN_IF_FAILED(MakeAndInitialize(&result, _pData, pProvider, start, end, wordDelimiters)); + TermControlUiaTextRange* result = nullptr; + RETURN_IF_FAILED(MakeAndInitialize(&result, _pData, pProvider, start, end, wordDelimiters)); *ppUtr = result; return S_OK; } @@ -161,8 +164,8 @@ HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple* { RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr); *ppUtr = nullptr; - UiaTextRange* result = nullptr; - RETURN_IF_FAILED(MakeAndInitialize(&result, _pData, pProvider, point, wordDelimiters)); + TermControlUiaTextRange* result = nullptr; + RETURN_IF_FAILED(MakeAndInitialize(&result, _pData, pProvider, point, wordDelimiters)); *ppUtr = result; return S_OK; } diff --git a/src/cascadia/TerminalControl/TermControlUiaProvider.hpp b/src/types/TermControlUiaProvider.hpp similarity index 79% rename from src/cascadia/TerminalControl/TermControlUiaProvider.hpp rename to src/types/TermControlUiaProvider.hpp index c90d3bf6ca3..ed6525e727f 100644 --- a/src/cascadia/TerminalControl/TermControlUiaProvider.hpp +++ b/src/types/TermControlUiaProvider.hpp @@ -19,32 +19,28 @@ Author(s): #pragma once -#include "..\types\ScreenInfoUiaProviderBase.h" -#include "..\types\UiaTextRangeBase.hpp" -#include "UiaTextRange.hpp" - -namespace winrt::Microsoft::Terminal::TerminalControl::implementation -{ - struct TermControl; -} - +#include "ScreenInfoUiaProviderBase.h" +#include "UiaTextRangeBase.hpp" +#include "IControlInfo.h" +#include "TermControlUiaTextRange.hpp" namespace Microsoft::Terminal { class TermControlUiaProvider : public Microsoft::Console::Types::ScreenInfoUiaProviderBase { public: TermControlUiaProvider() = default; - HRESULT RuntimeClassInitialize(_In_ winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl* termControl, - _In_ std::function GetBoundingRect); + HRESULT RuntimeClassInitialize(_In_ ::Microsoft::Console::Types::IUiaData* const uiaData, + _In_ ::Microsoft::Console::Types::IControlInfo* controlInfo); // IRawElementProviderFragment methods IFACEMETHODIMP Navigate(_In_ NavigateDirection direction, _COM_Outptr_result_maybenull_ IRawElementProviderFragment** ppProvider) override; + IFACEMETHODIMP get_HostRawElementProvider(IRawElementProviderSimple** ppProvider) noexcept override; IFACEMETHODIMP get_BoundingRectangle(_Out_ UiaRect* pRect) override; IFACEMETHODIMP get_FragmentRoot(_COM_Outptr_result_maybenull_ IRawElementProviderFragmentRoot** ppProvider) override; const COORD GetFontSize() const; - const winrt::Windows::UI::Xaml::Thickness GetPadding() const; + const RECT GetPadding() const; protected: HRESULT GetSelectionRanges(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _Out_ std::deque>& selectionRanges) override; @@ -72,7 +68,6 @@ namespace Microsoft::Terminal _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr) override; private: - std::function _getBoundingRect; - winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl* _termControl; + ::Microsoft::Console::Types::IControlInfo* _controlInfo; }; } diff --git a/src/cascadia/TerminalControl/UiaTextRange.cpp b/src/types/TermControlUiaTextRange.cpp similarity index 73% rename from src/cascadia/TerminalControl/UiaTextRange.cpp rename to src/types/TermControlUiaTextRange.cpp index 45e907bd856..14e44943735 100644 --- a/src/cascadia/TerminalControl/UiaTextRange.cpp +++ b/src/types/TermControlUiaTextRange.cpp @@ -1,18 +1,18 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -#include "pch.h" -#include "UiaTextRange.hpp" +#include "precomp.h" +#include "TermControlUiaTextRange.hpp" #include "TermControlUiaProvider.hpp" using namespace Microsoft::Terminal; using namespace Microsoft::Console::Types; using namespace Microsoft::WRL; -HRESULT UiaTextRange::GetSelectionRanges(_In_ IUiaData* pData, +HRESULT TermControlUiaTextRange::GetSelectionRanges(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* pProvider, _In_ const std::wstring_view wordDelimiters, - _Out_ std::deque>& ranges) + _Out_ std::deque>& ranges) { try { @@ -27,8 +27,8 @@ HRESULT UiaTextRange::GetSelectionRanges(_In_ IUiaData* pData, const auto start = rect.Origin(); const auto end = rect.EndExclusive(); - ComPtr range; - RETURN_IF_FAILED(MakeAndInitialize(&range, pData, pProvider, start, end, wordDelimiters)); + ComPtr range; + RETURN_IF_FAILED(MakeAndInitialize(&range, pData, pProvider, start, end, wordDelimiters)); temporaryResult.emplace_back(std::move(range)); } std::swap(temporaryResult, ranges); @@ -38,12 +38,12 @@ HRESULT UiaTextRange::GetSelectionRanges(_In_ IUiaData* pData, } // degenerate range constructor. -HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* const pProvider, _In_ const std::wstring_view wordDelimiters) +HRESULT TermControlUiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* const pProvider, _In_ const std::wstring_view wordDelimiters) { return UiaTextRangeBase::RuntimeClassInitialize(pData, pProvider, wordDelimiters); } -HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, +HRESULT TermControlUiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* const pProvider, const Cursor& cursor, const std::wstring_view wordDelimiters) @@ -51,7 +51,7 @@ HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, return UiaTextRangeBase::RuntimeClassInitialize(pData, pProvider, cursor, wordDelimiters); } -HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, +HRESULT TermControlUiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* const pProvider, const COORD start, const COORD end, @@ -61,7 +61,7 @@ HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, } // returns a degenerate text range of the start of the row closest to the y value of point -HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, +HRESULT TermControlUiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* const pProvider, const UiaPoint point, const std::wstring_view wordDelimiters) @@ -71,16 +71,16 @@ HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, return S_OK; } -HRESULT UiaTextRange::RuntimeClassInitialize(const UiaTextRange& a) +HRESULT TermControlUiaTextRange::RuntimeClassInitialize(const TermControlUiaTextRange& a) { return UiaTextRangeBase::RuntimeClassInitialize(a); } -IFACEMETHODIMP UiaTextRange::Clone(_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) +IFACEMETHODIMP TermControlUiaTextRange::Clone(_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) { RETURN_HR_IF(E_INVALIDARG, ppRetVal == nullptr); *ppRetVal = nullptr; - auto hr = MakeAndInitialize(ppRetVal, *this); + auto hr = MakeAndInitialize(ppRetVal, *this); if (hr != S_OK) { @@ -105,7 +105,7 @@ IFACEMETHODIMP UiaTextRange::Clone(_Outptr_result_maybenull_ ITextRangeProvider* return S_OK; } -void UiaTextRange::_ChangeViewport(const SMALL_RECT /*NewWindow*/) +void TermControlUiaTextRange::_ChangeViewport(const SMALL_RECT /*NewWindow*/) { // TODO GitHub #2361: Update viewport when calling UiaTextRangeBase::ScrollIntoView() } @@ -117,7 +117,7 @@ void UiaTextRange::_ChangeViewport(const SMALL_RECT /*NewWindow*/) // (0,0) is the top-left of the app window // Return Value: // - -void UiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const +void TermControlUiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const { auto provider = static_cast(_pProvider); @@ -129,16 +129,16 @@ void UiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const // update based on TermControl padding auto padding = provider->GetPadding(); - clientPoint->x += gsl::narrow(padding.Left); - clientPoint->y += gsl::narrow(padding.Top); + clientPoint->x += gsl::narrow(padding.left); + clientPoint->y += gsl::narrow(padding.top); } -void UiaTextRange::_TranslatePointFromScreen(LPPOINT /*screenPoint*/) const +void TermControlUiaTextRange::_TranslatePointFromScreen(LPPOINT /*screenPoint*/) const { // TODO GitHub #2103: NON-HWND IMPLEMENTATION OF SCREENTOCLIENT() } -const COORD UiaTextRange::_getScreenFontSize() const +const COORD TermControlUiaTextRange::_getScreenFontSize() const { // Do NOT get the font info from IRenderData. It is a dummy font info. // Instead, the font info is saved in the TermControl. So we have to diff --git a/src/cascadia/TerminalControl/UiaTextRange.hpp b/src/types/TermControlUiaTextRange.hpp similarity index 88% rename from src/cascadia/TerminalControl/UiaTextRange.hpp rename to src/types/TermControlUiaTextRange.hpp index 8f70b24114c..7aae3d7a6a5 100644 --- a/src/cascadia/TerminalControl/UiaTextRange.hpp +++ b/src/types/TermControlUiaTextRange.hpp @@ -3,7 +3,7 @@ Copyright (c) Microsoft Corporation Licensed under the MIT license. Module Name: -- UiaTextRange.hpp +- TermControlUiaTextRange.hpp Abstract: - This module provides UI Automation access to the text of the console @@ -20,15 +20,15 @@ Author(s): namespace Microsoft::Terminal { - class UiaTextRange final : public Microsoft::Console::Types::UiaTextRangeBase + class TermControlUiaTextRange final : public Microsoft::Console::Types::UiaTextRangeBase { public: static HRESULT GetSelectionRanges(_In_ Microsoft::Console::Types::IUiaData* pData, _In_ IRawElementProviderSimple* pProvider, _In_ const std::wstring_view wordDelimiters, - _Out_ std::deque>& ranges); + _Out_ std::deque>& ranges); - UiaTextRange() = default; + TermControlUiaTextRange() = default; // degenerate range HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData, @@ -54,7 +54,7 @@ namespace Microsoft::Terminal const UiaPoint point, const std::wstring_view wordDelimiters = DefaultWordDelimiter); - HRESULT RuntimeClassInitialize(const UiaTextRange& a); + HRESULT RuntimeClassInitialize(const TermControlUiaTextRange& a); IFACEMETHODIMP Clone(_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override; diff --git a/src/types/lib/types.vcxproj b/src/types/lib/types.vcxproj index 0be89f36654..2b587e1b534 100644 --- a/src/types/lib/types.vcxproj +++ b/src/types/lib/types.vcxproj @@ -23,6 +23,8 @@ + + @@ -47,6 +49,8 @@ + + diff --git a/src/types/lib/types.vcxproj.filters b/src/types/lib/types.vcxproj.filters index eacc3b11b73..77645284478 100644 --- a/src/types/lib/types.vcxproj.filters +++ b/src/types/lib/types.vcxproj.filters @@ -72,6 +72,12 @@ Source Files + + Source Files + + + Source Files + @@ -134,6 +140,12 @@ Header Files + + Header Files + + + Header Files + Header Files @@ -159,4 +171,4 @@ - + \ No newline at end of file diff --git a/src/types/sources.inc b/src/types/sources.inc index 96a663dde9b..0834197df9d 100644 --- a/src/types/sources.inc +++ b/src/types/sources.inc @@ -45,6 +45,8 @@ SOURCES= \ ..\WindowUiaProviderBase.cpp \ ..\ScreenInfoUiaProviderBase.cpp \ ..\UiaTextRangeBase.cpp \ + ..\TermControlUiaProvider.cpp \ + ..\TermControlUiaTextRange.cpp \ INCLUDES= \ $(INCLUDES); \