diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 4d2f0a0d54b..0ec1e899356 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -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 diff --git a/src/cascadia/TerminalControl/TermControlUiaProvider.cpp b/src/cascadia/TerminalControl/TermControlUiaProvider.cpp index b2a30e43511..0f7edfb5cbd 100644 --- a/src/cascadia/TerminalControl/TermControlUiaProvider.cpp +++ b/src/cascadia/TerminalControl/TermControlUiaProvider.cpp @@ -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>& 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::type temporaryResult; + RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr); + *ppUtr = nullptr; - std::deque> 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(&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) diff --git a/src/cascadia/TerminalControl/TermControlUiaProvider.hpp b/src/cascadia/TerminalControl/TermControlUiaProvider.hpp index 0c41fa53d21..599983b6389 100644 --- a/src/cascadia/TerminalControl/TermControlUiaProvider.hpp +++ b/src/cascadia/TerminalControl/TermControlUiaProvider.hpp @@ -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>& 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; diff --git a/src/cascadia/TerminalControl/UiaTextRange.cpp b/src/cascadia/TerminalControl/UiaTextRange.cpp index 35169adcc36..e5647cea342 100644 --- a/src/cascadia/TerminalControl/UiaTextRange.cpp +++ b/src/cascadia/TerminalControl/UiaTextRange.cpp @@ -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>& ranges) -{ - try - { - typename std::remove_reference::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 range; - RETURN_IF_FAILED(MakeAndInitialize(&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) { diff --git a/src/cascadia/TerminalControl/UiaTextRange.hpp b/src/cascadia/TerminalControl/UiaTextRange.hpp index 8f70b24114c..f0fe6e90ef9 100644 --- a/src/cascadia/TerminalControl/UiaTextRange.hpp +++ b/src/cascadia/TerminalControl/UiaTextRange.hpp @@ -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>& ranges); - UiaTextRange() = default; // degenerate range diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 2df547e13ca..335e1ee469d 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -141,7 +141,8 @@ class Microsoft::Terminal::Core::Terminal final : 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 diff --git a/src/cascadia/TerminalCore/TerminalSelection.cpp b/src/cascadia/TerminalCore/TerminalSelection.cpp index 9a8445007e0..cdf229f9722 100644 --- a/src/cascadia/TerminalCore/TerminalSelection.cpp +++ b/src/cascadia/TerminalCore/TerminalSelection.cpp @@ -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: diff --git a/src/cascadia/TerminalCore/terminalrenderdata.cpp b/src/cascadia/TerminalCore/terminalrenderdata.cpp index 5cae603791b..81794c4fba2 100644 --- a/src/cascadia/TerminalCore/terminalrenderdata.cpp +++ b/src/cascadia/TerminalCore/terminalrenderdata.cpp @@ -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 diff --git a/src/host/renderData.cpp b/src/host/renderData.cpp index 0f652719fd6..36c3fb259fb 100644 --- a/src/host/renderData.cpp +++ b/src/host/renderData.cpp @@ -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, diff --git a/src/host/renderData.hpp b/src/host/renderData.hpp index b2700339180..3a548e0a812 100644 --- a/src/host/renderData.hpp +++ b/src/host/renderData.hpp @@ -60,7 +60,8 @@ class RenderData final : 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 }; diff --git a/src/interactivity/win32/screenInfoUiaProvider.cpp b/src/interactivity/win32/screenInfoUiaProvider.cpp index b8feb5589f4..6aa03a32e63 100644 --- a/src/interactivity/win32/screenInfoUiaProvider.cpp +++ b/src/interactivity/win32/screenInfoUiaProvider.cpp @@ -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>& 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::type temporaryResult; + RETURN_HR_IF_NULL(E_INVALIDARG, ppUtr); + *ppUtr = nullptr; - std::deque> 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(&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) diff --git a/src/interactivity/win32/screenInfoUiaProvider.hpp b/src/interactivity/win32/screenInfoUiaProvider.hpp index 7984621835d..c1b608e9520 100644 --- a/src/interactivity/win32/screenInfoUiaProvider.hpp +++ b/src/interactivity/win32/screenInfoUiaProvider.hpp @@ -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>& 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; diff --git a/src/interactivity/win32/uiaTextRange.cpp b/src/interactivity/win32/uiaTextRange.cpp index c5b7f645885..c65c2272a8b 100644 --- a/src/interactivity/win32/uiaTextRange.cpp +++ b/src/interactivity/win32/uiaTextRange.cpp @@ -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>& ranges) -{ - try - { - typename std::remove_reference::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 range; - RETURN_IF_FAILED(MakeAndInitialize(&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) { diff --git a/src/interactivity/win32/uiaTextRange.hpp b/src/interactivity/win32/uiaTextRange.hpp index 660746230be..6939f407880 100644 --- a/src/interactivity/win32/uiaTextRange.hpp +++ b/src/interactivity/win32/uiaTextRange.hpp @@ -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>& ranges); - UiaTextRange() = default; // degenerate range diff --git a/src/types/IUiaData.h b/src/types/IUiaData.h index efc3c078ea7..3106cce532b 100644 --- a/src/types/IUiaData.h +++ b/src/types/IUiaData.h @@ -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; }; diff --git a/src/types/ScreenInfoUiaProviderBase.cpp b/src/types/ScreenInfoUiaProviderBase.cpp index bc95e3ba972..18520ff2994 100644 --- a/src/types/ScreenInfoUiaProviderBase.cpp +++ b/src/types/ScreenInfoUiaProviderBase.cpp @@ -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 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 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> ranges; - RETURN_IF_FAILED(GetSelectionRanges(this, _wordDelimiters, ranges)); - // TODO GitHub #1914: Re-attach Tracing to UIA Tree //apiMsg.AreaSelected = true; - //apiMsg.SelectionRowCount = static_cast(ranges.size()); - // make a safe array - *ppRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, gsl::narrow(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(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 diff --git a/src/types/ScreenInfoUiaProviderBase.h b/src/types/ScreenInfoUiaProviderBase.h index 97c7a8f698c..c57419a6789 100644 --- a/src/types/ScreenInfoUiaProviderBase.h +++ b/src/types/ScreenInfoUiaProviderBase.h @@ -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>& 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; diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp index 9326809b8fc..3b16177242a 100644 --- a/src/types/UiaTextRangeBase.cpp +++ b/src/types/UiaTextRangeBase.cpp @@ -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) {