Make ScreenInfoUiaProvider::GetSelection() Return One Selection (#4466)
## Summary of the Pull Request We used to return multiple text ranges to represent one selection. We only support one selection at a time, so we should only return one range. Additionally, I moved all TriggerSelection() calls to the renderer from Terminal to TermControl for consistency. This ensures we only call it _once_ when we make a change to our selection state. ## References #2447 - helps polish Signaling for Selection #4465 - This is more apparent as the problem holding back Signaling for Selection ## PR Checklist * [x] Closes #4452 Tested using Accessibility Insights.
This commit is contained in:
parent
ce39b63f46
commit
d0c8221c6e
|
@ -852,6 +852,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
if (_terminal->IsSelectionActive())
|
||||
{
|
||||
_terminal->ClearSelection();
|
||||
_renderer->TriggerSelection();
|
||||
|
||||
if (vkey == VK_ESCAPE)
|
||||
{
|
||||
|
@ -1744,6 +1745,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
if (!_terminal->IsCopyOnSelectActive())
|
||||
{
|
||||
_terminal->ClearSelection();
|
||||
_renderer->TriggerSelection();
|
||||
}
|
||||
|
||||
// send data up for clipboard
|
||||
|
|
|
@ -100,26 +100,22 @@ void TermControlUiaProvider::ChangeViewport(const SMALL_RECT NewWindow)
|
|||
_termControl->ScrollViewport(NewWindow.Top);
|
||||
}
|
||||
|
||||
HRESULT TermControlUiaProvider::GetSelectionRanges(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _Out_ std::deque<ComPtr<UiaTextRangeBase>>& result)
|
||||
HRESULT TermControlUiaProvider::GetSelectionRange(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ UiaTextRangeBase** ppUtr)
|
||||
{
|
||||
try
|
||||
{
|
||||
result.clear();
|
||||
typename std::remove_reference<decltype(result)>::type temporaryResult;
|
||||
RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr);
|
||||
*ppUtr = nullptr;
|
||||
|
||||
std::deque<ComPtr<UiaTextRange>> ranges;
|
||||
RETURN_IF_FAILED(UiaTextRange::GetSelectionRanges(_pData, pProvider, wordDelimiters, ranges));
|
||||
const auto start = _pData->GetSelectionAnchor();
|
||||
|
||||
while (!ranges.empty())
|
||||
{
|
||||
temporaryResult.emplace_back(std::move(ranges.back()));
|
||||
ranges.pop_back();
|
||||
}
|
||||
// we need to make end exclusive
|
||||
auto end = _pData->GetEndSelectionPosition();
|
||||
_pData->GetTextBuffer().GetSize().IncrementInBounds(end, true);
|
||||
|
||||
std::swap(result, temporaryResult);
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
// 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));
|
||||
*ppUtr = result;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT TermControlUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple* const pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ UiaTextRangeBase** ppUtr)
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace Microsoft::Terminal
|
|||
void ChangeViewport(const SMALL_RECT NewWindow) override;
|
||||
|
||||
protected:
|
||||
HRESULT GetSelectionRanges(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _Out_ std::deque<WRL::ComPtr<Microsoft::Console::Types::UiaTextRangeBase>>& selectionRanges) override;
|
||||
HRESULT GetSelectionRange(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr) override;
|
||||
|
||||
// degenerate range
|
||||
HRESULT CreateTextRange(_In_ IRawElementProviderSimple* const pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr) override;
|
||||
|
|
|
@ -10,34 +10,6 @@ using namespace Microsoft::Console::Types;
|
|||
using namespace Microsoft::WRL;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
|
||||
HRESULT UiaTextRange::GetSelectionRanges(_In_ IUiaData* pData,
|
||||
_In_ IRawElementProviderSimple* pProvider,
|
||||
_In_ const std::wstring_view wordDelimiters,
|
||||
_Out_ std::deque<ComPtr<UiaTextRange>>& ranges)
|
||||
{
|
||||
try
|
||||
{
|
||||
typename std::remove_reference<decltype(ranges)>::type temporaryResult;
|
||||
|
||||
// get the selection rects
|
||||
const auto rectangles = pData->GetSelectionRects();
|
||||
|
||||
// create a range for each row
|
||||
for (const auto& rect : rectangles)
|
||||
{
|
||||
const auto start = rect.Origin();
|
||||
const auto end = rect.EndExclusive();
|
||||
|
||||
ComPtr<UiaTextRange> range;
|
||||
RETURN_IF_FAILED(MakeAndInitialize<UiaTextRange>(&range, pData, pProvider, start, end, wordDelimiters));
|
||||
temporaryResult.emplace_back(std::move(range));
|
||||
}
|
||||
std::swap(temporaryResult, ranges);
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
}
|
||||
|
||||
// degenerate range constructor.
|
||||
HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* const pProvider, _In_ const std::wstring_view wordDelimiters)
|
||||
{
|
||||
|
|
|
@ -23,11 +23,6 @@ namespace Microsoft::Terminal
|
|||
class UiaTextRange 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<WRL::ComPtr<UiaTextRange>>& ranges);
|
||||
|
||||
UiaTextRange() = default;
|
||||
|
||||
// degenerate range
|
||||
|
|
|
@ -141,7 +141,8 @@ public:
|
|||
const bool IsSelectionActive() const noexcept override;
|
||||
void ClearSelection() override;
|
||||
void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
|
||||
const COORD GetSelectionAnchor() const override;
|
||||
const COORD GetSelectionAnchor() const noexcept override;
|
||||
const COORD GetEndSelectionPosition() const noexcept override;
|
||||
const std::wstring GetConsoleTitle() const noexcept override;
|
||||
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute) override;
|
||||
#pragma endregion
|
||||
|
|
|
@ -113,14 +113,26 @@ SMALL_RECT Terminal::_GetSelectionRow(const SHORT row, const COORD higherCoord,
|
|||
// - None
|
||||
// Return Value:
|
||||
// - None
|
||||
const COORD Terminal::GetSelectionAnchor() const
|
||||
const COORD Terminal::GetSelectionAnchor() const noexcept
|
||||
{
|
||||
COORD selectionAnchorPos{ _selectionAnchor };
|
||||
THROW_IF_FAILED(ShortAdd(selectionAnchorPos.Y, _selectionVerticalOffset, &selectionAnchorPos.Y));
|
||||
|
||||
selectionAnchorPos.Y = base::ClampAdd(selectionAnchorPos.Y, _selectionVerticalOffset);
|
||||
return selectionAnchorPos;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the current end anchor position relative to the whole text buffer
|
||||
// Arguments:
|
||||
// - None
|
||||
// Return Value:
|
||||
// - None
|
||||
const COORD Terminal::GetEndSelectionPosition() const noexcept
|
||||
{
|
||||
COORD endSelectionPos{ _endSelectionPosition };
|
||||
endSelectionPos.Y = base::ClampAdd(endSelectionPos.Y, _selectionVerticalOffset);
|
||||
return endSelectionPos;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Expand the selection row according to selection mode and wide glyphs
|
||||
// - this is particularly useful for box selections (ALT + selection)
|
||||
|
@ -325,6 +337,7 @@ void Terminal::SetBoxSelection(const bool isEnabled) noexcept
|
|||
|
||||
// Method Description:
|
||||
// - clear selection data and disable rendering it
|
||||
#pragma warning(disable : 26440) // changing this to noexcept would require a change to ConHost's selection model
|
||||
void Terminal::ClearSelection()
|
||||
{
|
||||
_selectionActive = false;
|
||||
|
@ -332,8 +345,6 @@ void Terminal::ClearSelection()
|
|||
_selectionAnchor = { 0, 0 };
|
||||
_endSelectionPosition = { 0, 0 };
|
||||
_selectionVerticalOffset = 0;
|
||||
|
||||
_buffer->GetRenderTarget().TriggerSelection();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
|
|
@ -174,7 +174,6 @@ void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
|
|||
|
||||
SetSelectionAnchor(realCoordStart);
|
||||
SetEndSelectionPosition(realCoordEnd);
|
||||
_buffer->GetRenderTarget().TriggerSelection();
|
||||
}
|
||||
|
||||
const std::wstring Terminal::GetConsoleTitle() const noexcept
|
||||
|
|
|
@ -389,11 +389,50 @@ void RenderData::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
|
|||
// - none
|
||||
// Return Value:
|
||||
// - current selection anchor
|
||||
const COORD RenderData::GetSelectionAnchor() const
|
||||
const COORD RenderData::GetSelectionAnchor() const noexcept
|
||||
{
|
||||
return Selection::Instance().GetSelectionAnchor();
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Gets the current end selection anchor position
|
||||
// Arguments:
|
||||
// - none
|
||||
// Return Value:
|
||||
// - current selection anchor
|
||||
const COORD RenderData::GetEndSelectionPosition() const noexcept
|
||||
{
|
||||
// The selection area in ConHost is encoded as two things...
|
||||
// - SelectionAnchor: the initial position where the selection was started
|
||||
// - SelectionRect: the rectangular region denoting a portion of the buffer that is selected
|
||||
|
||||
// The following is an exerpt from Selection::s_GetSelectionRects
|
||||
// if the anchor (start of select) was in the top right or bottom left of the box,
|
||||
// we need to remove rectangular overlap in the middle.
|
||||
// e.g.
|
||||
// For selections with the anchor in the top left (A) or bottom right (B),
|
||||
// it is valid to maintain the inner rectangle (+) as part of the selection
|
||||
// A+++++++================
|
||||
// ==============++++++++B
|
||||
// + and = are valid highlights in this scenario.
|
||||
// For selections with the anchor in in the top right (A) or bottom left (B),
|
||||
// we must remove a portion of the first/last line that lies within the rectangle (+)
|
||||
// +++++++A=================
|
||||
// ==============B+++++++
|
||||
// Only = is valid for highlight in this scenario.
|
||||
// This is only needed for line selection. Box selection doesn't need to account for this.
|
||||
const auto selectionRect = Selection::Instance().GetSelectionRectangle();
|
||||
|
||||
// To extract the end anchor from this rect, we need to know which corner of the rect is the SelectionAnchor
|
||||
// Then choose the opposite corner.
|
||||
const auto anchor = Selection::Instance().GetSelectionAnchor();
|
||||
|
||||
const short x_pos = (selectionRect.Left == anchor.X) ? selectionRect.Right : selectionRect.Left;
|
||||
const short y_pos = (selectionRect.Top == anchor.Y) ? selectionRect.Bottom : selectionRect.Top;
|
||||
|
||||
return { x_pos, y_pos };
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Given two points in the buffer space, color the selection between the two with the given attribute.
|
||||
// - This will create an internal selection rectangle covering the two points, assume a line selection,
|
||||
|
|
|
@ -60,7 +60,8 @@ public:
|
|||
const bool IsSelectionActive() const override;
|
||||
void ClearSelection() override;
|
||||
void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
|
||||
const COORD GetSelectionAnchor() const;
|
||||
const COORD GetSelectionAnchor() const noexcept;
|
||||
const COORD GetEndSelectionPosition() const noexcept;
|
||||
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr);
|
||||
#pragma endregion
|
||||
};
|
||||
|
|
|
@ -97,26 +97,22 @@ void ScreenInfoUiaProvider::ChangeViewport(const SMALL_RECT NewWindow)
|
|||
_pUiaParent->ChangeViewport(NewWindow);
|
||||
}
|
||||
|
||||
HRESULT ScreenInfoUiaProvider::GetSelectionRanges(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _Out_ std::deque<ComPtr<UiaTextRangeBase>>& result)
|
||||
HRESULT ScreenInfoUiaProvider::GetSelectionRange(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr)
|
||||
{
|
||||
try
|
||||
{
|
||||
result.clear();
|
||||
typename std::remove_reference<decltype(result)>::type temporaryResult;
|
||||
RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr);
|
||||
*ppUtr = nullptr;
|
||||
|
||||
std::deque<ComPtr<UiaTextRange>> ranges;
|
||||
RETURN_IF_FAILED(UiaTextRange::GetSelectionRanges(_pData, pProvider, wordDelimiters, ranges));
|
||||
const auto start = _pData->GetSelectionAnchor();
|
||||
|
||||
while (!ranges.empty())
|
||||
{
|
||||
temporaryResult.emplace_back(std::move(ranges.back()));
|
||||
ranges.pop_back();
|
||||
}
|
||||
// we need to make end exclusive
|
||||
auto end = _pData->GetEndSelectionPosition();
|
||||
_pData->GetTextBuffer().GetSize().IncrementInBounds(end, true);
|
||||
|
||||
std::swap(result, temporaryResult);
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
// TODO GH #4509: Box Selection is misrepresented here as a line selection.
|
||||
UiaTextRange* result;
|
||||
RETURN_IF_FAILED(MakeAndInitialize<UiaTextRange>(&result, _pData, pProvider, start, end, wordDelimiters));
|
||||
*ppUtr = result;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ScreenInfoUiaProvider::CreateTextRange(_In_ IRawElementProviderSimple* const pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ UiaTextRangeBase** ppUtr)
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace Microsoft::Console::Interactivity::Win32
|
|||
void ChangeViewport(const SMALL_RECT NewWindow) override;
|
||||
|
||||
protected:
|
||||
HRESULT GetSelectionRanges(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _Out_ std::deque<WRL::ComPtr<Microsoft::Console::Types::UiaTextRangeBase>>& selectionRanges) override;
|
||||
HRESULT GetSelectionRange(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr) override;
|
||||
|
||||
// degenerate range
|
||||
HRESULT CreateTextRange(_In_ IRawElementProviderSimple* const pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ Microsoft::Console::Types::UiaTextRangeBase** ppUtr) override;
|
||||
|
|
|
@ -12,34 +12,6 @@ using namespace Microsoft::Console::Interactivity::Win32;
|
|||
using namespace Microsoft::WRL;
|
||||
using Microsoft::Console::Interactivity::ServiceLocator;
|
||||
|
||||
HRESULT UiaTextRange::GetSelectionRanges(_In_ IUiaData* pData,
|
||||
_In_ IRawElementProviderSimple* pProvider,
|
||||
const std::wstring_view wordDelimiters,
|
||||
_Out_ std::deque<ComPtr<UiaTextRange>>& ranges)
|
||||
{
|
||||
try
|
||||
{
|
||||
typename std::remove_reference<decltype(ranges)>::type temporaryResult;
|
||||
|
||||
// get the selection rects
|
||||
const auto rectangles = pData->GetSelectionRects();
|
||||
|
||||
// create a range for each row
|
||||
for (const auto& rect : rectangles)
|
||||
{
|
||||
const auto start = rect.Origin();
|
||||
const auto end = rect.EndExclusive();
|
||||
|
||||
ComPtr<UiaTextRange> range;
|
||||
RETURN_IF_FAILED(MakeAndInitialize<UiaTextRange>(&range, pData, pProvider, start, end, wordDelimiters));
|
||||
temporaryResult.emplace_back(std::move(range));
|
||||
}
|
||||
std::swap(temporaryResult, ranges);
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
}
|
||||
|
||||
// degenerate range constructor.
|
||||
HRESULT UiaTextRange::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* const pProvider, _In_ const std::wstring_view wordDelimiters)
|
||||
{
|
||||
|
|
|
@ -24,11 +24,6 @@ namespace Microsoft::Console::Interactivity::Win32
|
|||
class UiaTextRange 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<WRL::ComPtr<UiaTextRange>>& ranges);
|
||||
|
||||
UiaTextRange() = default;
|
||||
|
||||
// degenerate range
|
||||
|
|
|
@ -36,7 +36,8 @@ namespace Microsoft::Console::Types
|
|||
virtual const bool IsSelectionActive() const = 0;
|
||||
virtual void ClearSelection() = 0;
|
||||
virtual void SelectNewRegion(const COORD coordStart, const COORD coordEnd) = 0;
|
||||
virtual const COORD GetSelectionAnchor() const = 0;
|
||||
virtual const COORD GetSelectionAnchor() const noexcept = 0;
|
||||
virtual const COORD GetEndSelectionPosition() const noexcept = 0;
|
||||
virtual void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -251,75 +251,46 @@ IFACEMETHODIMP ScreenInfoUiaProviderBase::GetSelection(_Outptr_result_maybenull_
|
|||
*ppRetVal = nullptr;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// make a safe array
|
||||
*ppRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1);
|
||||
if (*ppRetVal == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
WRL::ComPtr<UiaTextRangeBase> range;
|
||||
if (!_pData->IsSelectionActive())
|
||||
{
|
||||
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
|
||||
//apiMsg.AreaSelected = false;
|
||||
//apiMsg.SelectionRowCount = 1;
|
||||
|
||||
// return a degenerate range at the cursor position
|
||||
const Cursor& cursor = _getTextBuffer().GetCursor();
|
||||
|
||||
// make a safe array
|
||||
*ppRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1);
|
||||
if (*ppRetVal == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
SafeArrayDestroy(*ppRetVal);
|
||||
*ppRetVal = nullptr;
|
||||
return hr;
|
||||
}
|
||||
|
||||
WRL::ComPtr<UiaTextRangeBase> range;
|
||||
hr = CreateTextRange(this, cursor, _wordDelimiters, &range);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
SafeArrayDestroy(*ppRetVal);
|
||||
*ppRetVal = nullptr;
|
||||
return hr;
|
||||
}
|
||||
|
||||
LONG currentIndex = 0;
|
||||
hr = SafeArrayPutElement(*ppRetVal, ¤tIndex, range.Detach());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
SafeArrayDestroy(*ppRetVal);
|
||||
*ppRetVal = nullptr;
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the selection ranges
|
||||
std::deque<WRL::ComPtr<UiaTextRangeBase>> ranges;
|
||||
RETURN_IF_FAILED(GetSelectionRanges(this, _wordDelimiters, ranges));
|
||||
|
||||
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
|
||||
//apiMsg.AreaSelected = true;
|
||||
//apiMsg.SelectionRowCount = static_cast<unsigned int>(ranges.size());
|
||||
|
||||
// make a safe array
|
||||
*ppRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, gsl::narrow<ULONG>(ranges.size()));
|
||||
if (*ppRetVal == nullptr)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
// get the selection range
|
||||
hr = GetSelectionRange(this, _wordDelimiters, &range);
|
||||
}
|
||||
|
||||
// fill the safe array
|
||||
for (LONG i = 0; i < gsl::narrow<LONG>(ranges.size()); ++i)
|
||||
{
|
||||
hr = SafeArrayPutElement(*ppRetVal, &i, ranges.at(i).Detach());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
SafeArrayDestroy(*ppRetVal);
|
||||
*ppRetVal = nullptr;
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
if (FAILED(hr))
|
||||
{
|
||||
SafeArrayDestroy(*ppRetVal);
|
||||
*ppRetVal = nullptr;
|
||||
return hr;
|
||||
}
|
||||
|
||||
LONG currentIndex = 0;
|
||||
hr = SafeArrayPutElement(*ppRetVal, ¤tIndex, range.Detach());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
SafeArrayDestroy(*ppRetVal);
|
||||
*ppRetVal = nullptr;
|
||||
return hr;
|
||||
}
|
||||
|
||||
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace Microsoft::Console::Types
|
|||
protected:
|
||||
ScreenInfoUiaProviderBase() = default;
|
||||
|
||||
virtual HRESULT GetSelectionRanges(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _Out_ std::deque<WRL::ComPtr<UiaTextRangeBase>>& selectionRanges) = 0;
|
||||
virtual HRESULT GetSelectionRange(_In_ IRawElementProviderSimple* pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ UiaTextRangeBase** ppUtr) = 0;
|
||||
|
||||
// degenerate range
|
||||
virtual HRESULT CreateTextRange(_In_ IRawElementProviderSimple* const pProvider, const std::wstring_view wordDelimiters, _COM_Outptr_result_maybenull_ UiaTextRangeBase** ppUtr) = 0;
|
||||
|
|
|
@ -91,11 +91,22 @@ HRESULT UiaTextRangeBase::RuntimeClassInitialize(_In_ IUiaData* pData,
|
|||
_In_ const COORD start,
|
||||
_In_ const COORD end,
|
||||
_In_ std::wstring_view wordDelimiters) noexcept
|
||||
try
|
||||
{
|
||||
RETURN_IF_FAILED(RuntimeClassInitialize(pData, pProvider, wordDelimiters));
|
||||
|
||||
_start = start;
|
||||
_end = end;
|
||||
// start is before/at end, so this is valid
|
||||
if (_pData->GetTextBuffer().GetSize().CompareInBounds(start, end, true) <= 0)
|
||||
{
|
||||
_start = start;
|
||||
_end = end;
|
||||
}
|
||||
else
|
||||
{
|
||||
// start is after end, so we need to flip our concept of start/end
|
||||
_start = end;
|
||||
_end = start;
|
||||
}
|
||||
|
||||
#if defined(_DEBUG) && defined(UIATEXTRANGE_DEBUG_MSGS)
|
||||
OutputDebugString(L"Constructor\n");
|
||||
|
@ -104,6 +115,7 @@ HRESULT UiaTextRangeBase::RuntimeClassInitialize(_In_ IUiaData* pData,
|
|||
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
void UiaTextRangeBase::Initialize(_In_ const UiaPoint point)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue