Introduce UiaTextRangeBase::FindText() for Accessibility (#4373)
Moved `FindText` to `UiaTextRangeBase`. Now that Search is a shared component (thanks #3279), I can just reuse it basically as-is. #3279 - Make Search a shared component #4018 - UiaTextRange Refactor I removed it from the two different kinds of UiaTextRange and put it in the base class. I needed a very minor change to ensure we convert from an inclusive end (from Search) to an exclusive end (in UTR). Worked with `FindText` was globally messed with in windows.h. So we had to do a few weird things there (thanks Michael). No need for additional tests because it _literally_ just sets up a Searcher and calls it.
This commit is contained in:
parent
29df540174
commit
55b638801b
|
@ -105,15 +105,6 @@ IFACEMETHODIMP UiaTextRange::Clone(_Outptr_result_maybenull_ ITextRangeProvider*
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP UiaTextRange::FindText(_In_ BSTR /*text*/,
|
||||
_In_ BOOL /*searchBackward*/,
|
||||
_In_ BOOL /*ignoreCase*/,
|
||||
_Outptr_result_maybenull_ ITextRangeProvider** /*ppRetVal*/)
|
||||
{
|
||||
// TODO GitHub #605: Search functionality
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
void UiaTextRange::_ChangeViewport(const SMALL_RECT /*NewWindow*/)
|
||||
{
|
||||
// TODO GitHub #2361: Update viewport when calling UiaTextRangeBase::ScrollIntoView()
|
||||
|
|
|
@ -57,10 +57,6 @@ namespace Microsoft::Terminal
|
|||
HRESULT RuntimeClassInitialize(const UiaTextRange& a);
|
||||
|
||||
IFACEMETHODIMP Clone(_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override;
|
||||
IFACEMETHODIMP FindText(_In_ BSTR text,
|
||||
_In_ BOOL searchBackward,
|
||||
_In_ BOOL ignoreCase,
|
||||
_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override;
|
||||
|
||||
protected:
|
||||
void _ChangeViewport(const SMALL_RECT NewWindow) override;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "pch.h"
|
||||
#include "XamlUiaTextRange.h"
|
||||
#include "UiaTextRange.hpp"
|
||||
#include <UIAutomationClient.h>
|
||||
|
||||
// the same as COR_E_NOTSUPPORTED
|
||||
// we don't want to import the CLR headers to get it
|
||||
|
@ -73,14 +74,17 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
throw winrt::hresult_not_implemented();
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider XamlUiaTextRange::FindText(winrt::hstring /*text*/,
|
||||
bool /*searchBackward*/,
|
||||
bool /*ignoreCase*/)
|
||||
XamlAutomation::ITextRangeProvider XamlUiaTextRange::FindText(winrt::hstring text,
|
||||
bool searchBackward,
|
||||
bool ignoreCase)
|
||||
{
|
||||
// TODO GitHub #605: Search functionality
|
||||
// we need to wrap this around the UiaTextRange FindText() function
|
||||
// but right now it returns E_NOTIMPL, so let's just return nullptr for now.
|
||||
return nullptr;
|
||||
UIA::ITextRangeProvider* pReturn;
|
||||
const auto queryText = wil::make_bstr(text.c_str());
|
||||
|
||||
THROW_IF_FAILED(_uiaProvider->FindText(queryText.get(), searchBackward, ignoreCase, &pReturn));
|
||||
|
||||
auto xutr = winrt::make_self<XamlUiaTextRange>(pReturn, _parentProvider);
|
||||
return *xutr;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable XamlUiaTextRange::GetAttributeValue(int32_t textAttributeId) const
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
// clang-format off
|
||||
|
||||
#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
|
||||
|
||||
// Define and then undefine WIN32_NO_STATUS because windows.h has no guard to prevent it from double defing certain statuses
|
||||
// when included with ntstatus.h
|
||||
#define WIN32_NO_STATUS
|
||||
|
|
|
@ -19,7 +19,8 @@ Author(s):
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "precomp.h"
|
||||
#include <UIAutomationCore.h>
|
||||
|
||||
#include "..\types\ScreenInfoUiaProviderBase.h"
|
||||
#include "..\types\UiaTextRangeBase.hpp"
|
||||
#include "uiaTextRange.hpp"
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "uiaTextRange.hpp"
|
||||
#include "screenInfoUiaProvider.hpp"
|
||||
#include "..\buffer\out\search.h"
|
||||
#include "..\interactivity\inc\ServiceLocator.hpp"
|
||||
|
||||
using namespace Microsoft::Console::Types;
|
||||
|
@ -105,58 +104,6 @@ IFACEMETHODIMP UiaTextRange::Clone(_Outptr_result_maybenull_ ITextRangeProvider*
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP UiaTextRange::FindText(_In_ BSTR text,
|
||||
_In_ BOOL searchBackward,
|
||||
_In_ BOOL ignoreCase,
|
||||
_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal)
|
||||
{
|
||||
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
|
||||
//Tracing::s_TraceUia(this, ApiCall::FindText, nullptr);
|
||||
RETURN_HR_IF(E_INVALIDARG, ppRetVal == nullptr);
|
||||
*ppRetVal = nullptr;
|
||||
try
|
||||
{
|
||||
const std::wstring wstr{ text, SysStringLen(text) };
|
||||
const auto sensitivity = ignoreCase ? Search::Sensitivity::CaseInsensitive : Search::Sensitivity::CaseSensitive;
|
||||
|
||||
auto searchDirection = Search::Direction::Forward;
|
||||
auto searchAnchor = _start;
|
||||
if (searchBackward)
|
||||
{
|
||||
searchDirection = Search::Direction::Backward;
|
||||
searchAnchor = _end;
|
||||
}
|
||||
|
||||
CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
THROW_HR_IF(E_POINTER, !gci.HasActiveOutputBuffer());
|
||||
Search searcher{ gci.renderData, wstr, searchDirection, sensitivity, searchAnchor };
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
if (searcher.FindNext())
|
||||
{
|
||||
const auto foundLocation = searcher.GetFoundLocation();
|
||||
const auto start = foundLocation.first;
|
||||
const auto end = foundLocation.second;
|
||||
const auto bufferSize = _pData->GetTextBuffer().GetSize();
|
||||
|
||||
// make sure what was found is within the bounds of the current range
|
||||
if ((searchDirection == Search::Direction::Forward && bufferSize.CompareInBounds(end, _end) < 0) ||
|
||||
(searchDirection == Search::Direction::Backward && bufferSize.CompareInBounds(start, _start) > 0))
|
||||
{
|
||||
hr = Clone(ppRetVal);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
UiaTextRange& range = static_cast<UiaTextRange&>(**ppRetVal);
|
||||
range._start = start;
|
||||
range._end = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
}
|
||||
|
||||
void UiaTextRange::_ChangeViewport(const SMALL_RECT NewWindow)
|
||||
{
|
||||
auto provider = static_cast<ScreenInfoUiaProvider*>(_pProvider);
|
||||
|
|
|
@ -58,10 +58,6 @@ namespace Microsoft::Console::Interactivity::Win32
|
|||
HRESULT RuntimeClassInitialize(const UiaTextRange& a);
|
||||
|
||||
IFACEMETHODIMP Clone(_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override;
|
||||
IFACEMETHODIMP FindText(_In_ BSTR text,
|
||||
_In_ BOOL searchBackward,
|
||||
_In_ BOOL ignoreCase,
|
||||
_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) override;
|
||||
|
||||
protected:
|
||||
void _ChangeViewport(const SMALL_RECT NewWindow) override;
|
||||
|
|
|
@ -21,11 +21,12 @@ Author(s):
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "precomp.h"
|
||||
#include "../buffer/out/textBuffer.hpp"
|
||||
#include "UiaTextRangeBase.hpp"
|
||||
#include "IUiaData.h"
|
||||
|
||||
#include <UIAutomationCore.h>
|
||||
|
||||
#include <wrl/implements.h>
|
||||
|
||||
namespace Microsoft::Console::Types
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "precomp.h"
|
||||
#include "UiaTextRangeBase.hpp"
|
||||
#include "ScreenInfoUiaProviderBase.h"
|
||||
#include "..\buffer\out\search.h"
|
||||
|
||||
using namespace Microsoft::Console::Types;
|
||||
using namespace Microsoft::Console::Types::UiaTextRangeBaseTracing;
|
||||
|
@ -346,6 +347,58 @@ IFACEMETHODIMP UiaTextRangeBase::FindAttribute(_In_ TEXTATTRIBUTEID /*textAttrib
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP UiaTextRangeBase::FindText(_In_ BSTR text,
|
||||
_In_ BOOL searchBackward,
|
||||
_In_ BOOL ignoreCase,
|
||||
_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) noexcept
|
||||
try
|
||||
{
|
||||
// TODO GitHub #1914: Re-attach Tracing to UIA Tree
|
||||
//Tracing::s_TraceUia(this, ApiCall::FindText, nullptr);
|
||||
RETURN_HR_IF(E_INVALIDARG, ppRetVal == nullptr);
|
||||
*ppRetVal = nullptr;
|
||||
|
||||
const std::wstring queryText{ text, SysStringLen(text) };
|
||||
const auto bufferSize = _pData->GetTextBuffer().GetSize();
|
||||
const auto sensitivity = ignoreCase ? Search::Sensitivity::CaseInsensitive : Search::Sensitivity::CaseSensitive;
|
||||
|
||||
auto searchDirection = Search::Direction::Forward;
|
||||
auto searchAnchor = _start;
|
||||
if (searchBackward)
|
||||
{
|
||||
searchDirection = Search::Direction::Backward;
|
||||
|
||||
// we need to convert the end to inclusive
|
||||
// because Search operates with an inclusive COORD
|
||||
searchAnchor = _end;
|
||||
bufferSize.DecrementInBounds(searchAnchor, true);
|
||||
}
|
||||
|
||||
Search searcher{ *_pData, queryText, searchDirection, sensitivity, searchAnchor };
|
||||
|
||||
if (searcher.FindNext())
|
||||
{
|
||||
const auto foundLocation = searcher.GetFoundLocation();
|
||||
const auto start = foundLocation.first;
|
||||
|
||||
// we need to increment the position of end because it's exclusive
|
||||
auto end = foundLocation.second;
|
||||
bufferSize.IncrementInBounds(end, true);
|
||||
|
||||
// make sure what was found is within the bounds of the current range
|
||||
if ((searchDirection == Search::Direction::Forward && bufferSize.CompareInBounds(end, _end, true) < 0) ||
|
||||
(searchDirection == Search::Direction::Backward && bufferSize.CompareInBounds(start, _start) > 0))
|
||||
{
|
||||
RETURN_IF_FAILED(Clone(ppRetVal));
|
||||
UiaTextRangeBase& range = static_cast<UiaTextRangeBase&>(**ppRetVal);
|
||||
range._start = start;
|
||||
range._end = end;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
IFACEMETHODIMP UiaTextRangeBase::GetAttributeValue(_In_ TEXTATTRIBUTEID textAttributeId,
|
||||
_Out_ VARIANT* pRetVal) noexcept
|
||||
{
|
||||
|
@ -930,7 +983,7 @@ const unsigned int UiaTextRangeBase::_getViewportHeight(const SMALL_RECT viewpor
|
|||
void UiaTextRangeBase::_getBoundingRect(_In_ const COORD startAnchor, _In_ const COORD endAnchor, _Inout_ std::vector<double>& coords) const
|
||||
{
|
||||
FAIL_FAST_IF(startAnchor.Y != endAnchor.Y);
|
||||
FAIL_FAST_IF(startAnchor.X <= endAnchor.X);
|
||||
FAIL_FAST_IF(startAnchor.X >= endAnchor.X);
|
||||
|
||||
const auto viewport = _pData->GetViewport();
|
||||
const auto currentFontSize = _getScreenFontSize();
|
||||
|
|
|
@ -18,13 +18,12 @@ Author(s):
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include "inc/viewport.hpp"
|
||||
#include "../buffer/out/textBuffer.hpp"
|
||||
#include "IUiaData.h"
|
||||
#include "unicode.hpp"
|
||||
|
||||
#include <UIAutomationCore.h>
|
||||
#include <deque>
|
||||
#include <tuple>
|
||||
#include <wrl/implements.h>
|
||||
|
@ -103,10 +102,10 @@ namespace Microsoft::Console::Types
|
|||
_In_ VARIANT val,
|
||||
_In_ BOOL searchBackward,
|
||||
_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) noexcept override;
|
||||
virtual IFACEMETHODIMP FindText(_In_ BSTR text,
|
||||
_In_ BOOL searchBackward,
|
||||
_In_ BOOL ignoreCase,
|
||||
_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) = 0;
|
||||
IFACEMETHODIMP FindText(_In_ BSTR text,
|
||||
_In_ BOOL searchBackward,
|
||||
_In_ BOOL ignoreCase,
|
||||
_Outptr_result_maybenull_ ITextRangeProvider** ppRetVal) noexcept override;
|
||||
IFACEMETHODIMP GetAttributeValue(_In_ TEXTATTRIBUTEID textAttributeId,
|
||||
_Out_ VARIANT* pRetVal) noexcept override;
|
||||
IFACEMETHODIMP GetBoundingRectangles(_Outptr_result_maybenull_ SAFEARRAY** ppRetVal) noexcept override;
|
||||
|
|
|
@ -20,7 +20,7 @@ Author(s):
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "precomp.h"
|
||||
#include <UIAutomationCore.h>
|
||||
|
||||
#include <wrl/implements.h>
|
||||
|
||||
|
|
Loading…
Reference in a new issue