hook up UIA tree to WPF control (#4548)

This PR hooks up the existing UIA implementation to the WPF control. Some existing code that was specific to the UWP terminal control could be shared so that has been refactored to a common location as well.

## Validation Steps Performed
WPF control was brought up in UISpy and the UIA tree was verified. NVDA was then used to check that screen readers were operating properly.
This commit is contained in:
Zoey Riordan 2020-02-24 15:17:55 -08:00 committed by GitHub
parent b8e33560f9
commit 4def49c45e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 419 additions and 139 deletions

View file

@ -3,6 +3,7 @@
#include "pch.h"
#include "HwndTerminal.hpp"
#include "../../types/TermControlUiaProvider.hpp"
#include <DefaultSettings.h>
#include "../../renderer/base/Renderer.hpp"
#include "../../renderer/dx/DxRenderer.hpp"
@ -14,13 +15,27 @@ 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
{
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
#pragma warning(suppress : 26490) // Win32 APIs can only store void*, have to use reinterpret_cast
HwndTerminal* terminal = reinterpret_cast<HwndTerminal*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (terminal)
{
switch (uMsg)
{
case WM_GETOBJECT:
if (lParam == UiaRootObjectId)
{
return UiaReturnRawElementProvider(hwnd, wParam, lParam, terminal->_GetUiaProvider());
}
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
static bool RegisterTermClass(HINSTANCE hInstance) noexcept
@ -32,7 +47,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 +62,10 @@ 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 },
_uiaProviderInitialized{ false },
_currentDpi{ USER_DEFAULT_SCREEN_DPI }
{
HINSTANCE hInstance = wil::GetModuleInstanceHandle();
@ -69,6 +87,9 @@ HwndTerminal::HwndTerminal(HWND parentHwnd) :
nullptr,
hInstance,
nullptr));
#pragma warning(suppress : 26490) // Win32 APIs can only store void*, have to use reinterpret_cast
SetWindowLongPtr(_hwnd.get(), GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
}
}
@ -141,8 +162,19 @@ void HwndTerminal::RegisterWriteCallback(const void _stdcall callback(wchar_t*))
});
}
::Microsoft::Console::Types::IUiaData* HwndTerminal::GetUiaData() const noexcept
{
return _terminal.get();
}
HWND HwndTerminal::GetHwnd() const noexcept
{
return _hwnd.get();
}
void HwndTerminal::_UpdateFont(int newDpi)
{
_currentDpi = newDpi;
auto lock = _terminal->LockForWriting();
// TODO: MSFT:20895307 If the font doesn't exist, this doesn't
@ -150,6 +182,33 @@ void HwndTerminal::_UpdateFont(int newDpi)
_renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont);
}
IRawElementProviderSimple* HwndTerminal::_GetUiaProvider() noexcept
{
if (nullptr == _uiaProvider && !_uiaProviderInitialized)
{
std::unique_lock<std::shared_mutex> lock;
try
{
#pragma warning(suppress : 26441) // The lock is named, this appears to be a false positive
lock = _terminal->LockForWriting();
if (_uiaProviderInitialized)
{
return _uiaProvider.Get();
}
LOG_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, this->GetUiaData(), this));
}
catch (...)
{
LOG_HR(wil::ResultFromCaughtException());
_uiaProvider = nullptr;
}
_uiaProviderInitialized = true;
}
return _uiaProvider.Get();
}
HRESULT HwndTerminal::Refresh(const SIZE windowSize, _Out_ COORD* dimensions)
{
RETURN_HR_IF_NULL(E_INVALIDARG, dimensions);
@ -186,10 +245,29 @@ void HwndTerminal::SendOutput(std::wstring_view data)
HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal)
{
auto _terminal = std::make_unique<HwndTerminal>(parentHwnd);
// In order for UIA to hook up properly there needs to be a "static" window hosting the
// inner win32 control. If the static window is not present then WM_GETOBJECT messages
// will not reach the child control, and the uia element will not be present in the tree.
auto _hostWindow = CreateWindowEx(
0,
L"static",
nullptr,
WS_CHILD |
WS_CLIPCHILDREN |
WS_CLIPSIBLINGS |
WS_VISIBLE,
0,
0,
0,
0,
parentHwnd,
nullptr,
nullptr,
0);
auto _terminal = std::make_unique<HwndTerminal>(_hostWindow);
RETURN_IF_FAILED(_terminal->Initialize());
*hwnd = _terminal->_hwnd.get();
*hwnd = _hostWindow;
*terminal = _terminal.release();
return S_OK;
@ -217,6 +295,15 @@ HRESULT _stdcall TerminalTriggerResize(void* terminal, double width, double heig
{
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
LOG_IF_WIN32_BOOL_FALSE(SetWindowPos(
publicTerminal->GetHwnd(),
nullptr,
0,
0,
static_cast<int>(width),
static_cast<int>(height),
0));
const SIZE windowSize{ static_cast<short>(width), static_cast<short>(height) };
return publicTerminal->Refresh(windowSize, dimensions);
}
@ -413,3 +500,35 @@ void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible)
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
publicTerminal->_terminal->SetCursorVisible(visible);
}
COORD HwndTerminal::GetFontSize() const
{
return _actualFont.GetSize();
}
RECT HwndTerminal::GetBounds() const noexcept
{
RECT windowRect;
GetWindowRect(_hwnd.get(), &windowRect);
return windowRect;
}
RECT HwndTerminal::GetPadding() const noexcept
{
return { 0 };
}
double HwndTerminal::GetScaleFactor() const noexcept
{
return static_cast<double>(_currentDpi) / static_cast<double>(USER_DEFAULT_SCREEN_DPI);
}
void HwndTerminal::ChangeViewport(const SMALL_RECT NewWindow)
{
_terminal->UserScrollViewport(NewWindow.Top);
}
HRESULT HwndTerminal::GetHostUiaProvider(IRawElementProviderSimple** provider) noexcept
{
return UiaHostProviderFromHwnd(_hwnd.get(), provider);
}

View file

@ -6,6 +6,9 @@
#include "../../renderer/base/Renderer.hpp"
#include "../../renderer/dx/DxRenderer.hpp"
#include "../../cascadia/TerminalCore/Terminal.hpp"
#include <UIAutomationCore.h>
#include "../../types/IControlAccessibilityInfo.h"
#include "../../types/TermControlUiaProvider.hpp"
using namespace Microsoft::Console::VirtualTerminal;
@ -39,20 +42,35 @@ __declspec(dllexport) void _stdcall TerminalBlinkCursor(void* terminal);
__declspec(dllexport) void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
};
struct HwndTerminal
struct HwndTerminal : ::Microsoft::Console::Types::IControlAccessibilityInfo
{
public:
HwndTerminal(HWND hwnd);
HwndTerminal(const HwndTerminal&) = default;
HwndTerminal(HwndTerminal&&) = default;
HwndTerminal& operator=(const HwndTerminal&) = default;
HwndTerminal& operator=(HwndTerminal&&) = default;
~HwndTerminal() = default;
HRESULT Initialize();
void SendOutput(std::wstring_view data);
HRESULT Refresh(const SIZE windowSize, _Out_ COORD* dimensions);
void RegisterScrollCallback(std::function<void(int, int, int)> callback);
void RegisterWriteCallback(const void _stdcall callback(wchar_t*));
::Microsoft::Console::Types::IUiaData* GetUiaData() const noexcept;
HWND GetHwnd() const noexcept;
static LRESULT CALLBACK HwndTerminalWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) noexcept;
private:
wil::unique_hwnd _hwnd;
FontInfoDesired _desiredFont;
FontInfo _actualFont;
int _currentDpi;
bool _uiaProviderInitialized;
::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider;
std::unique_ptr<::Microsoft::Terminal::Core::Terminal> _terminal;
@ -74,4 +92,13 @@ private:
friend void _stdcall TerminalBlinkCursor(void* terminal);
friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
void _UpdateFont(int newDpi);
IRawElementProviderSimple* _GetUiaProvider() noexcept;
// Inherited via IControlAccessibilityInfo
COORD GetFontSize() const override;
RECT GetBounds() const noexcept override;
double GetScaleFactor() const noexcept override;
void ChangeViewport(const SMALL_RECT NewWindow) override;
HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) noexcept override;
RECT GetPadding() const noexcept override;
};

View file

@ -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 <LibraryIncludes.h>

View file

@ -11,6 +11,7 @@
using namespace Microsoft::Console::Types;
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
using namespace winrt::Windows::Graphics::Display;
namespace UIA
{
@ -28,9 +29,10 @@ namespace XamlAutomation
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
TermControlAutomationPeer::TermControlAutomationPeer(winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl* owner) :
TermControlAutomationPeerT<TermControlAutomationPeer>(*owner) // pass owner to FrameworkElementAutomationPeer
TermControlAutomationPeerT<TermControlAutomationPeer>(*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 +161,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
#pragma endregion
RECT TermControlAutomationPeer::GetBoundingRectWrapped()
#pragma region IControlAccessibilityInfo
COORD TermControlAutomationPeer::GetFontSize() const
{
return _termControl->GetActualFont().GetSize();
}
RECT TermControlAutomationPeer::GetBounds() const
{
auto rect = GetBoundingRectangle();
return {
@ -170,6 +178,36 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
};
}
HRESULT TermControlAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider)
{
RETURN_HR_IF(E_INVALIDARG, provider == nullptr);
*provider = nullptr;
return S_OK;
}
RECT TermControlAutomationPeer::GetPadding() const
{
auto padding = _termControl->GetPadding();
return {
gsl::narrow_cast<LONG>(padding.Left),
gsl::narrow_cast<LONG>(padding.Top),
gsl::narrow_cast<LONG>(padding.Right),
gsl::narrow_cast<LONG>(padding.Bottom)
};
}
double TermControlAutomationPeer::GetScaleFactor() const
{
return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
}
void TermControlAutomationPeer::ChangeViewport(const SMALL_RECT NewWindow)
{
_termControl->ScrollViewport(NewWindow.Top);
}
#pragma endregion
// Method Description:
// - extracts the UiaTextRanges from the SAFEARRAY and converts them to Xaml ITextRangeProviders
// Arguments:
@ -179,7 +217,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
winrt::com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges)
{
// transfer ownership of UiaTextRanges to this new vector
auto providers = SafeArrayToOwningVector<::Microsoft::Terminal::UiaTextRange>(textRanges);
auto providers = SafeArrayToOwningVector<::Microsoft::Terminal::TermControlUiaTextRange>(textRanges);
int count = gsl::narrow<int>(providers.size());
std::vector<XamlAutomation::ITextRangeProvider> vec;

View file

@ -27,14 +27,16 @@ Author(s):
#include "TermControl.h"
#include "TermControlAutomationPeer.g.h"
#include <winrt/Microsoft.Terminal.TerminalControl.h>
#include "TermControlUiaProvider.hpp"
#include "../types/TermControlUiaProvider.hpp"
#include "../types/IUiaEventDispatcher.h"
#include "../types/IControlAccessibilityInfo.h"
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
struct TermControlAutomationPeer :
public TermControlAutomationPeerT<TermControlAutomationPeer>,
::Microsoft::Console::Types::IUiaEventDispatcher
::Microsoft::Console::Types::IUiaEventDispatcher,
::Microsoft::Console::Types::IControlAccessibilityInfo
{
public:
TermControlAutomationPeer(winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl* owner);
@ -59,11 +61,21 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange();
#pragma endregion
#pragma region IControlAccessibilityInfo Pattern
// Inherited via IControlAccessibilityInfo
virtual COORD GetFontSize() const override;
virtual RECT GetBounds() const override;
virtual RECT GetPadding() const override;
virtual double GetScaleFactor() const override;
virtual void ChangeViewport(SMALL_RECT NewWindow) 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<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges);
};
}

View file

@ -36,7 +36,6 @@
<ClInclude Include="SearchBoxControl.h">
<DependentUpon>SearchBoxControl.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="TermControlUiaProvider.hpp" />
<ClInclude Include="TermControl.h">
<DependentUpon>TermControl.idl</DependentUpon>
</ClInclude>
@ -46,7 +45,6 @@
<ClInclude Include="TSFInputControl.h">
<DependentUpon>TSFInputControl.idl</DependentUpon>
</ClInclude>
<ClInclude Include="UiaTextRange.hpp" />
<ClInclude Include="XamlUiaTextRange.h" />
</ItemGroup>
<ItemGroup>
@ -57,7 +55,6 @@
<ClCompile Include="SearchBoxControl.cpp">
<DependentUpon>SearchBoxControl.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="TermControlUiaProvider.cpp" />
<ClCompile Include="TermControl.cpp">
<DependentUpon>TermControl.idl</DependentUpon>
</ClCompile>
@ -68,7 +65,6 @@
<ClCompile Include="TermControlAutomationPeer.cpp">
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
</ClCompile>
<ClCompile Include="UiaTextRange.cpp" />
<ClCompile Include="XamlUiaTextRange.cpp" />
</ItemGroup>
<ItemGroup>

View file

@ -3,7 +3,7 @@
#include "pch.h"
#include "XamlUiaTextRange.h"
#include "UiaTextRange.hpp"
#include "../types/TermControlUiaTextRange.hpp"
#include <UIAutomationClient.h>
// the same as COR_E_NOTSUPPORTED

View file

@ -22,7 +22,7 @@ Author(s):
#include "TermControlAutomationPeer.h"
#include <UIAutomationCore.h>
#include "UiaTextRange.hpp"
#include "../types/TermControlUiaTextRange.hpp"
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{

View file

@ -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 @@ namespace Microsoft.Terminal.Wpf
/// </summary>
WM_MOUSEACTIVATE = 0x0021,
WM_GETOBJECT = 0x003D,
/// <summary>
/// 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.
/// </summary>

View file

@ -26,7 +26,7 @@ namespace Microsoft.Terminal.Wpf
private DispatcherTimer blinkTimer;
private NativeMethods.ScrollCallback scrollCallback;
private NativeMethods.WriteCallback writeCallback;
/// <summary>
/// Initializes a new instance of the <see cref="TerminalContainer"/> class.
/// </summary>
@ -35,7 +35,7 @@ namespace Microsoft.Terminal.Wpf
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 @@ namespace Microsoft.Terminal.Wpf
/// </summary>
internal int Columns { get; private set; }
internal IntPtr Hwnd => this.hwnd;
/// <summary>
/// Sets the connection to the terminal backend.
/// </summary>
@ -172,7 +174,6 @@ namespace Microsoft.Terminal.Wpf
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;

View file

@ -9,7 +9,7 @@ namespace Microsoft.Terminal.Wpf
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
/// <summary>
/// A basic terminal control. This control can receive and render standard VT100 sequences.
/// </summary>

View file

@ -13,7 +13,7 @@ using namespace Microsoft::WRL;
using Microsoft::Console::Interactivity::ServiceLocator;
// degenerate range constructor.
HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* const pProvider, _In_ const std::wstring_view wordDelimiters)
HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* const pProvider, _In_ const std::wstring_view wordDelimiters) noexcept
{
return UiaTextRangeBase::RuntimeClassInitialize(pData, pProvider, wordDelimiters);
}
@ -22,7 +22,7 @@ HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ IRawElem
HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const Cursor& cursor,
const std::wstring_view wordDelimiters)
const std::wstring_view wordDelimiters) noexcept
{
return UiaTextRangeBase::RuntimeClassInitialize(pData, pProvider, cursor, wordDelimiters);
}
@ -32,7 +32,7 @@ HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const COORD start,
const COORD end,
const std::wstring_view wordDelimiters)
const std::wstring_view wordDelimiters) noexcept
{
return UiaTextRangeBase::RuntimeClassInitialize(pData, pProvider, start, end, wordDelimiters);
}

View file

@ -29,20 +29,20 @@ namespace Microsoft::Console::Interactivity::Win32
// degenerate range
HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ const std::wstring_view wordDelimiters = DefaultWordDelimiter);
_In_ const std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept override;
// degenerate range at cursor position
HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const Cursor& cursor,
_In_ const std::wstring_view wordDelimiters = DefaultWordDelimiter);
_In_ const std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept override;
// specific endpoint range
HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ const COORD start,
_In_ const COORD end,
_In_ const std::wstring_view wordDelimiters = DefaultWordDelimiter);
_In_ const std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept override;
// range from a UiaPoint
HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData,

View file

@ -0,0 +1,43 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- IControlAccessibilityInfo.h
Abstract:
- This serves as the interface defining all information known by the control
hosting the terminal renderer that is needed for the UI Automation Tree.
Author(s):
- Zoey Riordan (zorio) Feb-2020
--*/
#pragma once
#include <wtypes.h>
namespace Microsoft::Console::Types
{
class IControlAccessibilityInfo
{
public:
virtual ~IControlAccessibilityInfo() = 0;
virtual COORD GetFontSize() const = 0;
virtual RECT GetBounds() const = 0;
virtual RECT GetPadding() const = 0;
virtual double GetScaleFactor() const = 0;
virtual void ChangeViewport(const SMALL_RECT NewWindow) = 0;
virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) = 0;
protected:
IControlAccessibilityInfo() = default;
IControlAccessibilityInfo(const IControlAccessibilityInfo&) = default;
IControlAccessibilityInfo(IControlAccessibilityInfo&&) = default;
IControlAccessibilityInfo& operator=(const IControlAccessibilityInfo&) = default;
IControlAccessibilityInfo& operator=(IControlAccessibilityInfo&&) = default;
};
inline IControlAccessibilityInfo::~IControlAccessibilityInfo() {}
}

View file

@ -38,7 +38,7 @@ namespace Microsoft::Console::Types
public WRL::RuntimeClass<WRL::RuntimeClassFlags<WRL::ClassicCom | WRL::InhibitFtmBase>, IRawElementProviderSimple, IRawElementProviderFragment, ITextProvider>
{
public:
HRESULT RuntimeClassInitialize(_In_ IUiaData* pData, _In_ std::wstring_view wordDelimiters = UiaTextRangeBase::DefaultWordDelimiter) noexcept;
virtual HRESULT RuntimeClassInitialize(_In_ IUiaData* pData, _In_ std::wstring_view wordDelimiters = UiaTextRangeBase::DefaultWordDelimiter) noexcept;
ScreenInfoUiaProviderBase(const ScreenInfoUiaProviderBase&) = default;
ScreenInfoUiaProviderBase(ScreenInfoUiaProviderBase&&) = default;
@ -104,9 +104,9 @@ namespace Microsoft::Console::Types
_COM_Outptr_result_maybenull_ UiaTextRangeBase** ppUtr) = 0;
// weak reference to IUiaData
IUiaData* _pData;
IUiaData* _pData{ nullptr };
std::wstring _wordDelimiters;
std::wstring _wordDelimiters{};
private:
// this is used to prevent the object from
@ -120,7 +120,7 @@ namespace Microsoft::Console::Types
// eventually overflowing the stack.
// We aren't using this as a cheap locking
// mechanism for multi-threaded code.
std::map<EVENTID, bool> _signalFiringMapping;
std::map<EVENTID, bool> _signalFiringMapping{};
const COORD _getScreenBufferCoords() const;
const TextBuffer& _getTextBuffer() const noexcept;

View file

@ -1,22 +1,21 @@
// 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<RECT(void)> GetBoundingRect)
#pragma warning(suppress : 26434) // WRL RuntimeClassInitialize base is a no-op and we need this for MakeAndInitialize
HRESULT TermControlUiaProvider::RuntimeClassInitialize(_In_ ::Microsoft::Console::Types::IUiaData* const uiaData,
_In_ ::Microsoft::Console::Types::IControlAccessibilityInfo* controlInfo) noexcept
{
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);
@ -24,8 +23,10 @@ HRESULT TermControlUiaProvider::RuntimeClassInitialize(_In_ winrt::Microsoft::Te
}
IFACEMETHODIMP TermControlUiaProvider::Navigate(_In_ NavigateDirection direction,
_COM_Outptr_result_maybenull_ IRawElementProviderFragment** ppProvider)
_COM_Outptr_result_maybenull_ IRawElementProviderFragment** ppProvider) noexcept
{
RETURN_HR_IF_NULL(E_INVALIDARG, ppProvider);
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
/*ApiMsgNavigate apiMsg;
apiMsg.Direction = direction;
@ -56,18 +57,29 @@ 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();
const RECT rc = _controlInfo->GetBounds();
pRect->left = rc.left;
pRect->top = rc.top;
pRect->width = rc.right - rc.left;
pRect->height = rc.bottom - rc.top;
pRect->width = static_cast<double>(rc.right) - static_cast<double>(rc.left);
pRect->height = static_cast<double>(rc.bottom) - static_cast<double>(rc.top);
return S_OK;
}
IFACEMETHODIMP TermControlUiaProvider::get_FragmentRoot(_COM_Outptr_result_maybenull_ IRawElementProviderFragmentRoot** ppProvider)
IFACEMETHODIMP TermControlUiaProvider::get_HostRawElementProvider(_COM_Outptr_result_maybenull_ IRawElementProviderSimple** ppProvider) noexcept
{
try
{
return _controlInfo->GetHostUiaProvider(ppProvider);
}
CATCH_RETURN();
}
IFACEMETHODIMP TermControlUiaProvider::get_FragmentRoot(_COM_Outptr_result_maybenull_ IRawElementProviderFragmentRoot** ppProvider) noexcept
{
RETURN_HR_IF_NULL(E_INVALIDARG, ppProvider);
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
//Tracing::s_TraceUia(this, ApiCall::GetFragmentRoot, nullptr);
try
@ -87,17 +99,22 @@ 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();
}
const double TermControlUiaProvider::GetScaleFactor() const
{
return _controlInfo->GetScaleFactor();
}
void TermControlUiaProvider::ChangeViewport(const SMALL_RECT NewWindow)
{
_termControl->ScrollViewport(NewWindow.Top);
_controlInfo->ChangeViewport(NewWindow);
}
HRESULT TermControlUiaProvider::GetSelectionRange(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ UiaTextRangeBase** ppUtr)
@ -112,8 +129,8 @@ HRESULT TermControlUiaProvider::GetSelectionRange(_In_ IRawElementProviderSimple
_pData->GetTextBuffer().GetSize().IncrementInBounds(end, true);
// TODO GH #4509: Box Selection is misrepresented here as a line selection.
UiaTextRange* result = nullptr;
RETURN_IF_FAILED(MakeAndInitialize<UiaTextRange>(&result, _pData, pProvider, start, end, wordDelimiters));
TermControlUiaTextRange* result = nullptr;
RETURN_IF_FAILED(MakeAndInitialize<TermControlUiaTextRange>(&result, _pData, pProvider, start, end, wordDelimiters));
*ppUtr = result;
return S_OK;
}
@ -122,8 +139,8 @@ HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple*
{
RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr);
*ppUtr = nullptr;
UiaTextRange* result = nullptr;
RETURN_IF_FAILED(MakeAndInitialize<UiaTextRange>(&result, _pData, pProvider, wordDelimiters));
TermControlUiaTextRange* result = nullptr;
RETURN_IF_FAILED(MakeAndInitialize<TermControlUiaTextRange>(&result, _pData, pProvider, wordDelimiters));
*ppUtr = result;
return S_OK;
}
@ -135,8 +152,8 @@ HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple*
{
RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr);
*ppUtr = nullptr;
UiaTextRange* result = nullptr;
RETURN_IF_FAILED(MakeAndInitialize<UiaTextRange>(&result, _pData, pProvider, cursor, wordDelimiters));
TermControlUiaTextRange* result = nullptr;
RETURN_IF_FAILED(MakeAndInitialize<TermControlUiaTextRange>(&result, _pData, pProvider, cursor, wordDelimiters));
*ppUtr = result;
return S_OK;
}
@ -149,8 +166,8 @@ HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple*
{
RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr);
*ppUtr = nullptr;
UiaTextRange* result = nullptr;
RETURN_IF_FAILED(MakeAndInitialize<UiaTextRange>(&result, _pData, pProvider, start, end, wordDelimiters));
TermControlUiaTextRange* result = nullptr;
RETURN_IF_FAILED(MakeAndInitialize<TermControlUiaTextRange>(&result, _pData, pProvider, start, end, wordDelimiters));
*ppUtr = result;
return S_OK;
}
@ -162,8 +179,8 @@ HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple*
{
RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr);
*ppUtr = nullptr;
UiaTextRange* result = nullptr;
RETURN_IF_FAILED(MakeAndInitialize<UiaTextRange>(&result, _pData, pProvider, point, wordDelimiters));
TermControlUiaTextRange* result = nullptr;
RETURN_IF_FAILED(MakeAndInitialize<TermControlUiaTextRange>(&result, _pData, pProvider, point, wordDelimiters));
*ppUtr = result;
return S_OK;
}

View file

@ -19,32 +19,29 @@ 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 "IControlAccessibilityInfo.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<RECT()> GetBoundingRect);
HRESULT RuntimeClassInitialize(_In_ ::Microsoft::Console::Types::IUiaData* const uiaData,
_In_ ::Microsoft::Console::Types::IControlAccessibilityInfo* controlInfo) noexcept;
// IRawElementProviderFragment methods
IFACEMETHODIMP Navigate(_In_ NavigateDirection direction,
_COM_Outptr_result_maybenull_ IRawElementProviderFragment** ppProvider) override;
_COM_Outptr_result_maybenull_ IRawElementProviderFragment** ppProvider) noexcept 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;
IFACEMETHODIMP get_FragmentRoot(_COM_Outptr_result_maybenull_ IRawElementProviderFragmentRoot** ppProvider) noexcept override;
const COORD GetFontSize() const;
const winrt::Windows::UI::Xaml::Thickness GetPadding() const;
const RECT GetPadding() const;
const double GetScaleFactor() const;
void ChangeViewport(const SMALL_RECT NewWindow) override;
protected:
@ -73,7 +70,6 @@ namespace Microsoft::Terminal
_COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr) override;
private:
std::function<RECT(void)> _getBoundingRect;
winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl* _termControl;
::Microsoft::Console::Types::IControlAccessibilityInfo* _controlInfo{ nullptr };
};
}

View file

@ -1,59 +1,60 @@
// 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;
using namespace winrt::Windows::Graphics::Display;
// 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) noexcept
{
return UiaTextRangeBase::RuntimeClassInitialize(pData, pProvider, wordDelimiters);
}
HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const Cursor& cursor,
const std::wstring_view wordDelimiters)
HRESULT TermControlUiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const Cursor& cursor,
const std::wstring_view wordDelimiters) noexcept
{
return UiaTextRangeBase::RuntimeClassInitialize(pData, pProvider, cursor, wordDelimiters);
}
HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const COORD start,
const COORD end,
const std::wstring_view wordDelimiters)
HRESULT TermControlUiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const COORD start,
const COORD end,
const std::wstring_view wordDelimiters) noexcept
{
return UiaTextRangeBase::RuntimeClassInitialize(pData, pProvider, start, end, wordDelimiters);
}
// returns a degenerate text range of the start of the row closest to the y value of point
HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const UiaPoint point,
const std::wstring_view wordDelimiters)
#pragma warning(suppress : 26434) // WRL RuntimeClassInitialize base is a no-op and we need this for MakeAndInitialize
HRESULT TermControlUiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const UiaPoint point,
const std::wstring_view wordDelimiters)
{
RETURN_IF_FAILED(UiaTextRangeBase::RuntimeClassInitialize(pData, pProvider, wordDelimiters));
Initialize(point);
return S_OK;
}
HRESULT UiaTextRange::RuntimeClassInitialize(const UiaTextRange& a)
#pragma warning(suppress : 26434) // WRL RuntimeClassInitialize base is a no-op and we need this for MakeAndInitialize
HRESULT TermControlUiaTextRange::RuntimeClassInitialize(const TermControlUiaTextRange& a) noexcept
{
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<UiaTextRange>(ppRetVal, *this);
const auto hr = MakeAndInitialize<TermControlUiaTextRange>(ppRetVal, *this);
if (hr != S_OK)
{
@ -78,9 +79,9 @@ IFACEMETHODIMP UiaTextRange::Clone(_Outptr_result_maybenull_ ITextRangeProvider*
return S_OK;
}
void UiaTextRange::_ChangeViewport(const SMALL_RECT NewWindow)
void TermControlUiaTextRange::_ChangeViewport(const SMALL_RECT NewWindow)
{
auto provider = static_cast<TermControlUiaProvider*>(_pProvider);
const gsl::not_null<TermControlUiaProvider*> provider = static_cast<TermControlUiaProvider*>(_pProvider);
provider->ChangeViewport(NewWindow);
}
@ -91,11 +92,11 @@ void UiaTextRange::_ChangeViewport(const SMALL_RECT NewWindow)
// (0,0) is the top-left of the app window
// Return Value:
// - <none>
void UiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const
void TermControlUiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const
{
auto provider = static_cast<TermControlUiaProvider*>(_pProvider);
const gsl::not_null<TermControlUiaProvider*> provider = static_cast<TermControlUiaProvider*>(_pProvider);
auto includeOffsets = [](long clientPos, double termControlPos, double padding, double scaleFactor) {
const auto includeOffsets = [](long clientPos, double termControlPos, double padding, double scaleFactor) {
auto result = base::ClampedNumeric<double>(clientPos);
result += padding;
result *= scaleFactor;
@ -111,10 +112,10 @@ void UiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const
const auto padding = provider->GetPadding();
// Get scale factor for display
const auto scaleFactor = DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
const auto scaleFactor = provider->GetScaleFactor();
clientPoint->x = includeOffsets(clientPoint->x, boundingRect.left, padding.Left, scaleFactor);
clientPoint->y = includeOffsets(clientPoint->y, boundingRect.top, padding.Top, scaleFactor);
clientPoint->x = includeOffsets(clientPoint->x, boundingRect.left, padding.left, scaleFactor);
clientPoint->y = includeOffsets(clientPoint->y, boundingRect.top, padding.top, scaleFactor);
}
// Method Description:
@ -124,11 +125,11 @@ void UiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const
// (0,0) is the top-left of the screen
// Return Value:
// - <none>
void UiaTextRange::_TranslatePointFromScreen(LPPOINT screenPoint) const
void TermControlUiaTextRange::_TranslatePointFromScreen(LPPOINT screenPoint) const
{
auto provider = static_cast<TermControlUiaProvider*>(_pProvider);
const gsl::not_null<TermControlUiaProvider*> provider = static_cast<TermControlUiaProvider*>(_pProvider);
auto includeOffsets = [](long screenPos, double termControlPos, double padding, double scaleFactor) {
const auto includeOffsets = [](long screenPos, double termControlPos, double padding, double scaleFactor) {
auto result = base::ClampedNumeric<double>(screenPos);
result -= termControlPos;
result /= scaleFactor;
@ -144,17 +145,17 @@ void UiaTextRange::_TranslatePointFromScreen(LPPOINT screenPoint) const
const auto padding = provider->GetPadding();
// Get scale factor for display
const auto scaleFactor = DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
const auto scaleFactor = provider->GetScaleFactor();
screenPoint->x = includeOffsets(screenPoint->x, boundingRect.left, padding.Left, scaleFactor);
screenPoint->y = includeOffsets(screenPoint->y, boundingRect.top, padding.Top, scaleFactor);
screenPoint->x = includeOffsets(screenPoint->x, boundingRect.left, padding.left, scaleFactor);
screenPoint->y = includeOffsets(screenPoint->y, boundingRect.top, padding.top, scaleFactor);
}
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
// ask our parent to get it for us.
auto provider = static_cast<TermControlUiaProvider*>(_pProvider);
const gsl::not_null<const TermControlUiaProvider*> provider = static_cast<TermControlUiaProvider*>(_pProvider);
return provider->GetFontSize();
}

View file

@ -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,28 +20,28 @@ Author(s):
namespace Microsoft::Terminal
{
class UiaTextRange final : public Microsoft::Console::Types::UiaTextRangeBase
class TermControlUiaTextRange final : public Microsoft::Console::Types::UiaTextRangeBase
{
public:
UiaTextRange() = default;
TermControlUiaTextRange() = default;
// degenerate range
HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ const std::wstring_view wordDelimiters = DefaultWordDelimiter);
_In_ const std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept override;
// degenerate range at cursor position
HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const Cursor& cursor,
const std::wstring_view wordDelimiters = DefaultWordDelimiter);
const std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept override;
// specific endpoint range
HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
const COORD start,
const COORD end,
const std::wstring_view wordDelimiters = DefaultWordDelimiter);
const std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept override;
// range from a UiaPoint
HRESULT RuntimeClassInitialize(_In_ Microsoft::Console::Types::IUiaData* pData,
@ -49,7 +49,7 @@ namespace Microsoft::Terminal
const UiaPoint point,
const std::wstring_view wordDelimiters = DefaultWordDelimiter);
HRESULT RuntimeClassInitialize(const UiaTextRange& a);
HRESULT RuntimeClassInitialize(const TermControlUiaTextRange& a) noexcept;
IFACEMETHODIMP Clone(_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override;

View file

@ -58,25 +58,26 @@ namespace Microsoft::Console::Types
static constexpr std::wstring_view DefaultWordDelimiter{ &UNICODE_SPACE, 1 };
// degenerate range
HRESULT RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept;
virtual HRESULT RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept;
// degenerate range at cursor position
HRESULT RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ const Cursor& cursor,
_In_ std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept;
virtual HRESULT RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ const Cursor& cursor,
_In_ std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept;
// specific endpoint range
HRESULT RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ const COORD start,
_In_ const COORD end,
_In_ std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept;
virtual HRESULT RuntimeClassInitialize(_In_ IUiaData* pData,
_In_ IRawElementProviderSimple* const pProvider,
_In_ const COORD start,
_In_ const COORD end,
_In_ std::wstring_view wordDelimiters = DefaultWordDelimiter) noexcept;
HRESULT RuntimeClassInitialize(const UiaTextRangeBase& a) noexcept;
virtual HRESULT RuntimeClassInitialize(const UiaTextRangeBase& a) noexcept;
UiaTextRangeBase(const UiaTextRangeBase&) = default;
UiaTextRangeBase(UiaTextRangeBase&&) = default;
UiaTextRangeBase& operator=(const UiaTextRangeBase&) = default;
UiaTextRangeBase& operator=(UiaTextRangeBase&&) = default;
@ -127,11 +128,11 @@ namespace Microsoft::Console::Types
protected:
UiaTextRangeBase() = default;
IUiaData* _pData;
IUiaData* _pData{ nullptr };
IRawElementProviderSimple* _pProvider;
IRawElementProviderSimple* _pProvider{ nullptr };
std::wstring _wordDelimiters;
std::wstring _wordDelimiters{};
virtual void _ChangeViewport(const SMALL_RECT NewWindow) = 0;
virtual void _TranslatePointToScreen(LPPOINT clientPoint) const = 0;
@ -141,13 +142,13 @@ namespace Microsoft::Console::Types
// used to debug objects passed back and forth
// between the provider and the client
IdType _id;
IdType _id{};
// measure units in the form [_start, _end).
// These are in the TextBuffer coordinate space.
// NOTE: _start is inclusive, but _end is exclusive
COORD _start;
COORD _end;
COORD _start{};
COORD _end{};
// This is used by tracing to extract the text value
// that the UiaTextRange currently encompasses.

View file

@ -24,6 +24,8 @@
<ClCompile Include="..\ThemeUtils.cpp" />
<ClCompile Include="..\UiaTextRangeBase.cpp" />
<ClCompile Include="..\UiaTracing.cpp" />
<ClCompile Include="..\TermControlUiaTextRange.cpp" />
<ClCompile Include="..\TermControlUiaProvider.cpp" />
<ClCompile Include="..\Utf16Parser.cpp" />
<ClCompile Include="..\Viewport.cpp" />
<ClCompile Include="..\WindowBufferSizeEvent.cpp" />
@ -36,6 +38,7 @@
<ItemGroup>
<ClInclude Include="..\IBaseData.h" />
<ClInclude Include="..\IConsoleWindow.hpp" />
<ClInclude Include="..\IControlAccessibilityInfo.h" />
<ClInclude Include="..\inc\CodepointWidthDetector.hpp" />
<ClInclude Include="..\inc\convert.hpp" />
<ClInclude Include="..\inc\Environment.hpp" />
@ -48,6 +51,8 @@
<ClInclude Include="..\IUiaData.h" />
<ClInclude Include="..\IUiaEventDispatcher.h" />
<ClInclude Include="..\IUiaWindow.h" />
<ClInclude Include="..\TermControlUiaTextRange.hpp" />
<ClInclude Include="..\TermControlUiaProvider.hpp" />
<ClInclude Include="..\precomp.h" />
<ClInclude Include="..\ScreenInfoUiaProviderBase.h" />
<ClInclude Include="..\UiaTextRangeBase.hpp" />

View file

@ -75,6 +75,12 @@
<ClCompile Include="..\UiaTracing.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\TermControlUiaProvider.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\TermControlUiaTextRange.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\inc\IInputEvent.hpp">
@ -101,6 +107,9 @@
<ClInclude Include="..\IConsoleWindow.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\IControlAccessibilityInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\UiaTextRangeBase.hpp">
<Filter>Header Files</Filter>
</ClInclude>
@ -137,6 +146,12 @@
<ClInclude Include="..\WindowUiaProviderBase.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TermControlUiaProvider.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TermControlUiaTextRange.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\IUiaWindow.h">
<Filter>Header Files</Filter>
</ClInclude>

View file

@ -45,6 +45,8 @@ SOURCES= \
..\WindowUiaProviderBase.cpp \
..\ScreenInfoUiaProviderBase.cpp \
..\UiaTextRangeBase.cpp \
..\TermControlUiaProvider.cpp \
..\TermControlUiaTextRange.cpp \
INCLUDES= \
$(INCLUDES); \