diff --git a/src/UIAutomation/Microsoft.UI.UIAutomation/Microsoft.UI.UIAutomation.idl b/src/UIAutomation/Microsoft.UI.UIAutomation/Microsoft.UI.UIAutomation.idl index a13c99f..1fbfb9d 100644 --- a/src/UIAutomation/Microsoft.UI.UIAutomation/Microsoft.UI.UIAutomation.idl +++ b/src/UIAutomation/Microsoft.UI.UIAutomation/Microsoft.UI.UIAutomation.idl @@ -144,9 +144,10 @@ namespace Microsoft.UI.UIAutomation unsealed runtimeclass AutomationRemoteExtensionTarget : AutomationRemoteObject { - AutomationRemoteBool IsExtensionTarget(); + /* Deprecated */ AutomationRemoteBool IsExtensionTarget(); void CallExtension(AutomationRemoteGuid extensionId, AutomationRemoteObject[] operands); AutomationRemoteBool IsExtensionSupported(AutomationRemoteGuid extensionId); + void Set(AutomationRemoteExtensionTarget rhs); } runtimeclass AutomationRemoteArray : AutomationRemoteObject @@ -268,6 +269,8 @@ namespace Microsoft.UI.UIAutomation AutomationRemoteCacheRequest AsCacheRequest(); AutomationRemoteBool IsByteArray(); AutomationRemoteByteArray AsByteArray(); + AutomationRemoteBool IsExtensionTarget(); + AutomationRemoteExtensionTarget AsExtensionTarget(); } enum AutomationActiveEnd diff --git a/src/UIAutomation/Microsoft.UI.UIAutomation/Standins.cpp b/src/UIAutomation/Microsoft.UI.UIAutomation/Standins.cpp index ec76f20..b9ba4fa 100644 --- a/src/UIAutomation/Microsoft.UI.UIAutomation/Standins.cpp +++ b/src/UIAutomation/Microsoft.UI.UIAutomation/Standins.cpp @@ -694,7 +694,7 @@ namespace winrt::Microsoft::UI::UIAutomation::implementation winrt::AutomationRemoteElement AutomationRemoteElement::GetUpdatedCacheElement(const winrt::AutomationRemoteCacheRequest& cacheRequest) { auto result = m_parent->NewNull().AsElement(); - result.Set(*this); + result.Set(static_cast(*this)); result.PopulateCache(cacheRequest); return result; } @@ -1008,4 +1008,21 @@ namespace winrt::Microsoft::UI::UIAutomation::implementation { return As(); } + + winrt::AutomationRemoteBool AutomationRemoteAnyObject::IsExtensionTarget() + { + const auto resultId = m_parent->GetNextId(); + m_parent->InsertInstruction(bytecode::IsExtensionTarget{ + resultId, + m_operandId + }); + + const auto result = Make(resultId); + return result; + } + + winrt::AutomationRemoteExtensionTarget AutomationRemoteAnyObject::AsExtensionTarget() + { + return As(); + } } diff --git a/src/UIAutomation/Microsoft.UI.UIAutomation/Standins.h b/src/UIAutomation/Microsoft.UI.UIAutomation/Standins.h index 8bc2e2a..358af60 100644 --- a/src/UIAutomation/Microsoft.UI.UIAutomation/Standins.h +++ b/src/UIAutomation/Microsoft.UI.UIAutomation/Standins.h @@ -541,9 +541,14 @@ namespace winrt::Microsoft::UI::UIAutomation::implementation public: AutomationRemoteExtensionTarget(bytecode::OperandId operandId, AutomationRemoteOperation& parent); - winrt::AutomationRemoteBool IsExtensionTarget(); + /* Deprecated */ winrt::AutomationRemoteBool IsExtensionTarget(); void CallExtension(const winrt::AutomationRemoteGuid& extensionId, winrt::array_view operands); winrt::AutomationRemoteBool IsExtensionSupported(const winrt::AutomationRemoteGuid& extensionId); + + void Set(const class_type& rhs) + { + AutomationRemoteObject::Set(rhs); + } }; struct AutomationRemoteStringMap : AutomationRemoteStringMapT @@ -654,6 +659,8 @@ namespace winrt::Microsoft::UI::UIAutomation::implementation winrt::AutomationRemoteCacheRequest AsCacheRequest(); winrt::AutomationRemoteBool IsByteArray(); winrt::AutomationRemoteByteArray AsByteArray(); + winrt::AutomationRemoteBool IsExtensionTarget(); + winrt::AutomationRemoteExtensionTarget AsExtensionTarget(); #include "AutomationRemoteAnyObjectMethods.g.h" diff --git a/src/UIAutomation/UiaOperationAbstraction/UiaOperationAbstraction.cpp b/src/UIAutomation/UiaOperationAbstraction/UiaOperationAbstraction.cpp index f9442a4..1a5b1af 100644 --- a/src/UIAutomation/UiaOperationAbstraction/UiaOperationAbstraction.cpp +++ b/src/UIAutomation/UiaOperationAbstraction/UiaOperationAbstraction.cpp @@ -1045,6 +1045,25 @@ namespace UiaOperationAbstraction } } + void UiaOperationDelegator::ConvertVariantDataToRemote(std::variant, + winrt::Microsoft::UI::UIAutomation::AutomationRemoteExtensionTarget>& localExtensionTargetVariant) const + { + if (m_useRemoteApi && m_remoteOperation) + { + if (auto localExtensionTarget = std::get_if>(&localExtensionTargetVariant)) + { + if (*localExtensionTarget) + { + localExtensionTargetVariant = m_remoteOperation.ImportConnectionBoundObject(FromAbi(localExtensionTarget->get())); + } + else + { + localExtensionTargetVariant = m_remoteOperation.NewNull().AsExtensionTarget(); + } + } + } + } + void UiaOperationDelegator::ConvertVariantDataToRemote(std::variant, winrt::Microsoft::UI::UIAutomation::AutomationRemoteElement>& localElementVariant) const { diff --git a/src/UIAutomation/UiaOperationAbstraction/UiaOperationAbstraction.h b/src/UIAutomation/UiaOperationAbstraction/UiaOperationAbstraction.h index 2e5b444..a174da2 100644 --- a/src/UIAutomation/UiaOperationAbstraction/UiaOperationAbstraction.h +++ b/src/UIAutomation/UiaOperationAbstraction/UiaOperationAbstraction.h @@ -435,6 +435,9 @@ namespace UiaOperationAbstraction void ConvertVariantDataToRemote(std::variant< std::shared_ptr, winrt::Microsoft::UI::UIAutomation::AutomationRemoteObject>& localVariantVariant) const; + void ConvertVariantDataToRemote(std::variant< + winrt::com_ptr, + winrt::Microsoft::UI::UIAutomation::AutomationRemoteExtensionTarget>& localExtensionTargetVariant) const; void ConvertVariantDataToRemote(std::variant< winrt::com_ptr, winrt::Microsoft::UI::UIAutomation::AutomationRemoteElement>& localElementVariant) const; diff --git a/src/UIAutomation/UiaOperationAbstraction/UiaTypeAbstraction.g.h b/src/UIAutomation/UiaOperationAbstraction/UiaTypeAbstraction.g.h index 35f7948..1257845 100644 --- a/src/UIAutomation/UiaOperationAbstraction/UiaTypeAbstraction.g.h +++ b/src/UIAutomation/UiaOperationAbstraction/UiaTypeAbstraction.g.h @@ -806,7 +806,99 @@ } }; - class UiaTextRange: public UiaTypeBase< + template class UiaTypeBaseWithExtensionSupport: public UiaTypeBase< + typename LocalType, + typename RemoteType> + { + public: + static constexpr VARTYPE c_comVariantType = VT_UNKNOWN; + static constexpr auto c_variantMember = &VARIANT::punkVal; + + using UiaTypeBase::UiaTypeBase; + + UiaBool IsExtensionSupported(UiaGuid guid) + { + if (UiaOperationAbstraction::ShouldUseRemoteApi()) + { + this->ToRemote(); + guid.ToRemote(); + auto remoteValue = std::get(m_member); + return remoteValue.IsExtensionSupported(guid); + } + + // No local equivalent + throw winrt::hresult_not_implemented(); + } + + template void CallExtension(UiaGuid guid, ArgTypes&... args) + { + if (UiaOperationAbstraction::ShouldUseRemoteApi()) + { + this->ToRemote(); + guid.ToRemote(); + auto remoteValue = std::get(m_member); + (args.ToRemote(),...); + remoteValue.CallExtension(guid, {static_cast(args)...}); + return; + } + + // No local equivalent + throw winrt::hresult_not_implemented(); + } + }; + + class UiaConnectionBoundObject: public UiaTypeBaseWithExtensionSupport< + winrt::com_ptr, + winrt::Microsoft::UI::UIAutomation::AutomationRemoteExtensionTarget> + { + public: + static constexpr VARTYPE c_comVariantType = VT_UNKNOWN; + static constexpr auto c_variantMember = &VARIANT::punkVal; + static constexpr auto c_anyTest = &winrt::Microsoft::UI::UIAutomation::AutomationRemoteAnyObject::IsExtensionTarget; + static constexpr auto c_anyCast = &winrt::Microsoft::UI::UIAutomation::AutomationRemoteAnyObject::AsExtensionTarget; + + UiaConnectionBoundObject(_In_ IUnknown* connectionBoundObject); + UiaConnectionBoundObject(winrt::com_ptr const& connectionBoundObject); + UiaConnectionBoundObject(winrt::Microsoft::UI::UIAutomation::AutomationRemoteExtensionTarget const& extentionTarget); + explicit UiaConnectionBoundObject(winrt::Microsoft::UI::UIAutomation::AutomationRemoteAnyObject const& extensionTarget); + UiaConnectionBoundObject(const UiaConnectionBoundObject& other) = default; + UiaConnectionBoundObject& operator=(const UiaConnectionBoundObject& other); + + operator winrt::com_ptr() const; + operator wil::com_ptr() const; + + IUnknown* get() const; + IUnknown* operator->() const {return get();} + void reset(); + IUnknown** operator&(); + operator bool() const {return !!get();} + UiaBool operator!() const {return IsNull();} + operator UiaBool() const {return !IsNull();} + + template + void copy_to(T** to) const try + { + std::get>(m_member).as(to); + } + catch(...) + { + THROW_HR(static_cast(winrt::to_hresult())); + } + + template <> + void copy_to(IUnknown** to) const try + { + std::get>(m_member).copy_to(to); + } + catch(...) + { + THROW_HR(static_cast(winrt::to_hresult())); + } + + UiaBool IsNull() const; + }; + + class UiaTextRange: public UiaTypeBaseWithExtensionSupport< winrt::com_ptr, winrt::Microsoft::UI::UIAutomation::AutomationRemoteTextRange> { @@ -2010,7 +2102,7 @@ } }; - class UiaElement: public UiaTypeBase< + class UiaElement: public UiaTypeBaseWithExtensionSupport< winrt::com_ptr, winrt::Microsoft::UI::UIAutomation::AutomationRemoteElement> { @@ -2154,24 +2246,6 @@ UiaVariant GetMetadataValue(UiaPropertyId propertyId, UiaMetadata metadataId); - UiaBool IsExtensionSupported(UiaGuid guid); - - template void CallExtension(UiaGuid guid, ArgTypes&... args) - { - if (UiaOperationAbstraction::ShouldUseRemoteApi()) - { - this->ToRemote(); - guid.ToRemote(); - auto remoteValue = std::get(m_member); - (args.ToRemote(),...); - remoteValue.CallExtension(guid, {static_cast(args)...}); - return; - } - - // No local equivalent - throw winrt::hresult_not_implemented(); - } - void FromRemoteResult(const winrt::Windows::Foundation::IInspectable& result) { m_member = result.as(); diff --git a/src/UIAutomation/UiaOperationAbstraction/UiaTypeAbstractionImpl.g.cpp b/src/UIAutomation/UiaOperationAbstraction/UiaTypeAbstractionImpl.g.cpp index 1310412..03ead01 100644 --- a/src/UIAutomation/UiaOperationAbstraction/UiaTypeAbstractionImpl.g.cpp +++ b/src/UIAutomation/UiaOperationAbstraction/UiaTypeAbstractionImpl.g.cpp @@ -2008,24 +2008,24 @@ } UiaTextRange::UiaTextRange(_In_ IUIAutomationTextRange* object): - UiaTypeBase(MakeWinrtComPtr(object)) + UiaTypeBaseWithExtensionSupport(MakeWinrtComPtr(object)) { ToRemote(); } UiaTextRange::UiaTextRange(winrt::com_ptr const& object): - UiaTypeBase(object) + UiaTypeBaseWithExtensionSupport(object) { ToRemote(); } UiaTextRange::UiaTextRange(winrt::Microsoft::UI::UIAutomation::AutomationRemoteTextRange const& object): - UiaTypeBase(object) + UiaTypeBaseWithExtensionSupport(object) { } UiaTextRange::UiaTextRange(winrt::Microsoft::UI::UIAutomation::AutomationRemoteAnyObject const& object): - UiaTypeBase(object.AsTextRange()) + UiaTypeBaseWithExtensionSupport(object.AsTextRange()) { } @@ -5031,24 +5031,24 @@ } UiaElement::UiaElement(_In_ IUIAutomationElement* element): - UiaTypeBase(MakeWinrtComPtr(element)) + UiaTypeBaseWithExtensionSupport(MakeWinrtComPtr(element)) { ToRemote(); } UiaElement::UiaElement(winrt::com_ptr const& element): - UiaTypeBase(element) + UiaTypeBaseWithExtensionSupport(element) { ToRemote(); } UiaElement::UiaElement(winrt::Microsoft::UI::UIAutomation::AutomationRemoteElement const& element): - UiaTypeBase(element) + UiaTypeBaseWithExtensionSupport(element) { } UiaElement::UiaElement(winrt::Microsoft::UI::UIAutomation::AutomationRemoteAnyObject const& element): - UiaTypeBase(element.AsElement()) + UiaTypeBaseWithExtensionSupport(element.AsElement()) { } @@ -7224,16 +7224,71 @@ return metadataValue; } - UiaBool UiaElement::IsExtensionSupported(UiaGuid guid) + UiaConnectionBoundObject::UiaConnectionBoundObject(_In_ IUnknown* target): + UiaTypeBaseWithExtensionSupport(MakeWinrtComPtr(target)) + { + ToRemote(); + } + + UiaConnectionBoundObject::UiaConnectionBoundObject(winrt::com_ptr const& target): + UiaTypeBaseWithExtensionSupport(target) + { + ToRemote(); + } + + UiaConnectionBoundObject::UiaConnectionBoundObject(winrt::Microsoft::UI::UIAutomation::AutomationRemoteExtensionTarget const& target): + UiaTypeBaseWithExtensionSupport(target) + { + } + + UiaConnectionBoundObject::UiaConnectionBoundObject(winrt::Microsoft::UI::UIAutomation::AutomationRemoteAnyObject const& target): + UiaTypeBaseWithExtensionSupport(target.AsExtensionTarget()) + { + } + + UiaConnectionBoundObject& UiaConnectionBoundObject::operator=(const UiaConnectionBoundObject& other) + { + AssignCopyTo(m_member, other.m_member); + return *this; + } + + UiaConnectionBoundObject::operator winrt::com_ptr() const + { + return std::get>(m_member); + } + + UiaConnectionBoundObject::operator wil::com_ptr() const + { + return wil::com_ptr(std::get>(m_member).get()); + } + + IUnknown* UiaConnectionBoundObject::get() const + { + return std::get>(m_member).get(); + } + + void UiaConnectionBoundObject::reset() + { + std::get>(m_member) = nullptr; + } + + IUnknown** UiaConnectionBoundObject::operator&() + { + reset(); + return std::get>(m_member).put(); + } + + UiaBool UiaConnectionBoundObject::IsNull() const { if (UiaOperationAbstraction::ShouldUseRemoteApi()) { - this->ToRemote(); - guid.ToRemote(); - auto remoteValue = std::get(m_member); - return remoteValue.IsExtensionSupported(guid); + auto remoteValue = std::get_if(&m_member); + if (remoteValue) + { + return remoteValue->IsNull(); + } } - // No local equivalent - throw winrt::hresult_not_implemented(); - } + return !get(); + } +