Use Microsoft::WRL::ComPtr to manage lifetime of QWindowsUiaMainProvider

Using smart pointers for managing COM object lifetimes reduces risk of
introducing reference counting regressions.

Task-number: QTBUG-126530
Change-Id: If487b78eae6403c762205ecc042e8872e3a6b940
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit f51896b74e57459748313af750c013353d013821)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Jøger Hansegård 2024-06-27 10:51:11 +02:00 committed by Qt Cherry-pick Bot
parent 29c32e7cdc
commit 89ba182737
15 changed files with 126 additions and 100 deletions

View File

@ -561,6 +561,7 @@ qt_internal_extend_target(Core CONDITION WIN32
plugin/qsystemlibrary.cpp plugin/qsystemlibrary_p.h
thread/qthread_win.cpp
platform/windows/qcomobject_p.h
platform/windows/qcomptr_p.h
LIBRARIES
advapi32
authz

View File

@ -0,0 +1,43 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCOMPTR_P_H
#define QCOMPTR_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/private/qglobal_p.h>
#if defined(Q_OS_WIN) || defined(Q_QDOC)
#include <QtCore/qt_windows.h>
#include <wrl/client.h>
QT_BEGIN_NAMESPACE
using Microsoft::WRL::ComPtr;
template <typename T, typename... Args>
ComPtr<T> makeComObject(Args &&...args)
{
ComPtr<T> p;
// Don't use Attach because of MINGW64 bug
// #892 Microsoft::WRL::ComPtr::Attach leaks references
*p.GetAddressOf() = new T(std::forward<Args>(args)...);
return p;
}
QT_END_NAMESPACE
#endif // Q_OS_WIN
#endif // QCOMPTR_P_H

View File

@ -46,9 +46,8 @@ bool QWindowsUiaAccessibility::handleWmGetObject(HWND hwnd, WPARAM wParam, LPARA
if (QWindow *window = QWindowsContext::instance()->findWindow(hwnd)) {
if (QAccessibleInterface *accessible = window->accessibleRoot()) {
QWindowsUiaMainProvider *provider = QWindowsUiaMainProvider::providerForAccessible(accessible);
*lResult = UiaReturnRawElementProvider(hwnd, wParam, lParam, provider);
provider->Release();
auto provider = QWindowsUiaMainProvider::providerForAccessible(accessible);
*lResult = UiaReturnRawElementProvider(hwnd, wParam, lParam, provider.Get());
return true;
}
}

View File

@ -129,7 +129,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaGridItemProvider::get_ContainingGrid(IRawEl
return UIA_E_ELEMENTNOTAVAILABLE;
if (QAccessibleInterface *table = tableCellInterface->table()) {
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(table); // Detach
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(table).Detach();
}
return S_OK;
}

View File

@ -45,9 +45,8 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaGridProvider::GetItem(int row, int column,
return UIA_E_ELEMENTNOTAVAILABLE;
if ((row >= 0) && (row < tableInterface->rowCount()) && (column >= 0) && (column < tableInterface->columnCount())) {
if (QAccessibleInterface *cell = tableInterface->cellAt(row, column)) {
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(cell); // Detach
}
if (QAccessibleInterface *cell = tableInterface->cellAt(row, column))
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(cell).Detach();
}
return S_OK;
}

View File

@ -40,18 +40,18 @@ QT_BEGIN_NAMESPACE
using namespace QWindowsUiAutomation;
// Returns a cached instance of the provider for a specific accessible interface.
QWindowsUiaMainProvider *QWindowsUiaMainProvider::providerForAccessible(QAccessibleInterface *accessible)
ComPtr<QWindowsUiaMainProvider> QWindowsUiaMainProvider::providerForAccessible(QAccessibleInterface *accessible)
{
if (!accessible)
return nullptr;
QAccessible::Id id = QAccessible::uniqueId(accessible);
QWindowsUiaProviderCache *providerCache = QWindowsUiaProviderCache::instance();
QWindowsUiaMainProvider *provider = providerCache->providerForId(id);
ComPtr<QWindowsUiaMainProvider> provider = providerCache->providerForId(id);
if (!provider) {
provider = new QWindowsUiaMainProvider(accessible);
providerCache->insert(id, provider);
provider = makeComObject<QWindowsUiaMainProvider>(accessible);
providerCache->insert(id, provider.Get()); // Cache holds weak references
}
return provider;
}
@ -73,10 +73,8 @@ void QWindowsUiaMainProvider::notifyFocusChange(QAccessibleEvent *event)
if (QAccessibleInterface *child = accessible->focusChild())
accessible = child;
}
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
UiaRaiseAutomationEvent(provider, UIA_AutomationFocusChangedEventId);
provider->Release();
}
if (auto provider = providerForAccessible(accessible))
UiaRaiseAutomationEvent(provider.Get(), UIA_AutomationFocusChangedEventId);
}
}
@ -86,34 +84,33 @@ void QWindowsUiaMainProvider::notifyStateChange(QAccessibleStateChangeEvent *eve
if (event->changedStates().checked || event->changedStates().checkStateMixed) {
// Notifies states changes in checkboxes.
if (accessible->role() == QAccessible::CheckBox) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
if (auto provider = providerForAccessible(accessible)) {
VARIANT oldVal, newVal;
clearVariant(&oldVal);
int toggleState = ToggleState_Off;
if (accessible->state().checked)
toggleState = accessible->state().checkStateMixed ? ToggleState_Indeterminate : ToggleState_On;
setVariantI4(toggleState, &newVal);
UiaRaiseAutomationPropertyChangedEvent(provider, UIA_ToggleToggleStatePropertyId, oldVal, newVal);
provider->Release();
UiaRaiseAutomationPropertyChangedEvent(
provider.Get(), UIA_ToggleToggleStatePropertyId, oldVal, newVal);
}
}
}
if (event->changedStates().active) {
if (accessible->role() == QAccessible::Window) {
// Notifies window opened/closed.
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
if (auto provider = providerForAccessible(accessible)) {
if (accessible->state().active) {
UiaRaiseAutomationEvent(provider, UIA_Window_WindowOpenedEventId);
UiaRaiseAutomationEvent(provider.Get(), UIA_Window_WindowOpenedEventId);
if (QAccessibleInterface *focused = accessible->focusChild()) {
if (QWindowsUiaMainProvider *focusedProvider = providerForAccessible(focused)) {
UiaRaiseAutomationEvent(focusedProvider, UIA_AutomationFocusChangedEventId);
focusedProvider->Release();
if (auto focusedProvider = providerForAccessible(focused)) {
UiaRaiseAutomationEvent(focusedProvider.Get(),
UIA_AutomationFocusChangedEventId);
}
}
} else {
UiaRaiseAutomationEvent(provider, UIA_Window_WindowClosedEventId);
UiaRaiseAutomationEvent(provider.Get(), UIA_Window_WindowClosedEventId);
}
provider->Release();
}
}
}
@ -140,26 +137,26 @@ void QWindowsUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *eve
}
}
if (event->value().typeId() == QMetaType::QString) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
if (auto provider = providerForAccessible(accessible)) {
// Notifies changes in string values.
VARIANT oldVal, newVal;
clearVariant(&oldVal);
setVariantString(event->value().toString(), &newVal);
UiaRaiseAutomationPropertyChangedEvent(provider, UIA_ValueValuePropertyId, oldVal, newVal);
provider->Release();
UiaRaiseAutomationPropertyChangedEvent(provider.Get(), UIA_ValueValuePropertyId,
oldVal, newVal);
HRESULT hr = VariantClear(&newVal); // Free string allocated by setVariantString
Q_ASSERT(hr == S_OK);
Q_UNUSED(hr)
}
} else if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
if (auto provider = providerForAccessible(accessible)) {
// Notifies changes in values of controls supporting the value interface.
VARIANT oldVal, newVal;
clearVariant(&oldVal);
setVariantDouble(valueInterface->currentValue().toDouble(), &newVal);
UiaRaiseAutomationPropertyChangedEvent(provider, UIA_RangeValueValuePropertyId, oldVal, newVal);
provider->Release();
UiaRaiseAutomationPropertyChangedEvent(
provider.Get(), UIA_RangeValueValuePropertyId, oldVal, newVal);
}
}
}
@ -171,13 +168,13 @@ void QWindowsUiaMainProvider::notifyNameChange(QAccessibleEvent *event)
// Restrict notification to combo boxes, which need it for accessibility,
// in order to avoid slowdowns with unnecessary notifications.
if (accessible->role() == QAccessible::ComboBox) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
if (auto provider = providerForAccessible(accessible)) {
VARIANT oldVal, newVal;
clearVariant(&oldVal);
setVariantString(accessible->text(QAccessible::Name), &newVal);
UiaRaiseAutomationPropertyChangedEvent(provider, UIA_NamePropertyId, oldVal, newVal);
UiaRaiseAutomationPropertyChangedEvent(provider.Get(), UIA_NamePropertyId, oldVal,
newVal);
::SysFreeString(newVal.bstrVal);
provider->Release();
}
}
}
@ -186,10 +183,8 @@ void QWindowsUiaMainProvider::notifyNameChange(QAccessibleEvent *event)
void QWindowsUiaMainProvider::notifySelectionChange(QAccessibleEvent *event)
{
if (QAccessibleInterface *accessible = event->accessibleInterface()) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
UiaRaiseAutomationEvent(provider, UIA_SelectionItem_ElementSelectedEventId);
provider->Release();
}
if (auto provider = providerForAccessible(accessible))
UiaRaiseAutomationEvent(provider.Get(), UIA_SelectionItem_ElementSelectedEventId);
}
}
@ -198,17 +193,17 @@ void QWindowsUiaMainProvider::notifyTextChange(QAccessibleEvent *event)
{
if (QAccessibleInterface *accessible = event->accessibleInterface()) {
if (accessible->textInterface()) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
if (auto provider = providerForAccessible(accessible)) {
if (event->type() == QAccessible::TextSelectionChanged) {
UiaRaiseAutomationEvent(provider, UIA_Text_TextSelectionChangedEventId);
UiaRaiseAutomationEvent(provider.Get(), UIA_Text_TextSelectionChangedEventId);
} else if (event->type() == QAccessible::TextCaretMoved) {
if (!accessible->state().readOnly) {
UiaRaiseAutomationEvent(provider, UIA_Text_TextSelectionChangedEventId);
UiaRaiseAutomationEvent(provider.Get(),
UIA_Text_TextSelectionChangedEventId);
}
} else {
UiaRaiseAutomationEvent(provider, UIA_Text_TextChangedEventId);
UiaRaiseAutomationEvent(provider.Get(), UIA_Text_TextChangedEventId);
}
provider->Release();
}
}
}
@ -217,18 +212,18 @@ void QWindowsUiaMainProvider::notifyTextChange(QAccessibleEvent *event)
void QWindowsUiaMainProvider::raiseNotification(QAccessibleAnnouncementEvent *event)
{
if (QAccessibleInterface *accessible = event->accessibleInterface()) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
if (auto provider = providerForAccessible(accessible)) {
BSTR message = bStrFromQString(event->message());
QAccessible::AnnouncementPoliteness prio = event->politeness();
NotificationProcessing processing = (prio == QAccessible::AnnouncementPoliteness::Assertive)
? NotificationProcessing_ImportantAll
: NotificationProcessing_All;
BSTR activityId = bStrFromQString(QString::fromLatin1(""));
UiaRaiseNotificationEvent(provider, NotificationKind_Other, processing, message, activityId);
UiaRaiseNotificationEvent(provider.Get(), NotificationKind_Other, processing, message,
activityId);
::SysFreeString(message);
::SysFreeString(activityId);
provider->Release();
}
}
}
@ -383,9 +378,9 @@ void QWindowsUiaMainProvider::fillVariantArrayForRelation(QAccessibleInterface*
SAFEARRAY *elements = SafeArrayCreateVector(VT_UNKNOWN, 0, relationInterfaces.size());
for (LONG i = 0; i < relationInterfaces.size(); ++i) {
if (QWindowsUiaMainProvider *childProvider = QWindowsUiaMainProvider::providerForAccessible(relationInterfaces.at(i).first)) {
SafeArrayPutElement(elements, &i, static_cast<IRawElementProviderSimple*>(childProvider));
childProvider->Release();
if (ComPtr<IRawElementProviderSimple> provider =
providerForAccessible(relationInterfaces.at(i).first)) {
SafeArrayPutElement(elements, &i, provider.Get());
}
}
@ -697,7 +692,7 @@ HRESULT QWindowsUiaMainProvider::Navigate(NavigateDirection direction, IRawEleme
}
if (targetacc)
*pRetVal = providerForAccessible(targetacc); // Detach
*pRetVal = providerForAccessible(targetacc).Detach();
return S_OK;
}
@ -785,9 +780,8 @@ HRESULT QWindowsUiaMainProvider::get_FragmentRoot(IRawElementProviderFragmentRoo
// non-native controls/fragments.
if (QAccessibleInterface *accessible = accessibleInterface()) {
if (QWindow *window = windowForAccessible(accessible)) {
if (QAccessibleInterface *rootacc = window->accessibleRoot()) {
*pRetVal = providerForAccessible(rootacc); // Detach
}
if (QAccessibleInterface *rootacc = window->accessibleRoot())
*pRetVal = providerForAccessible(rootacc).Detach();
}
}
return S_OK;
@ -827,7 +821,7 @@ HRESULT QWindowsUiaMainProvider::ElementProviderFromPoint(double x, double y, IR
if (targetacc->textInterface()) break;
acc = acc->childAt(point.x(), point.y());
}
*pRetVal = providerForAccessible(targetacc); // Detach
*pRetVal = providerForAccessible(targetacc).Detach();
}
return S_OK;
}
@ -843,7 +837,7 @@ HRESULT QWindowsUiaMainProvider::GetFocus(IRawElementProviderFragment **pRetVal)
if (QAccessibleInterface *accessible = accessibleInterface()) {
if (QAccessibleInterface *focusacc = accessible->focusChild()) {
*pRetVal = providerForAccessible(focusacc); // Detach
*pRetVal = providerForAccessible(focusacc).Detach();
}
}
return S_OK;

View File

@ -14,6 +14,7 @@
#include <QtCore/qmutex.h>
#include <QtCore/qt_windows.h>
#include <QtGui/qaccessible.h>
#include <QtCore/private/qcomptr_p.h>
QT_BEGIN_NAMESPACE
@ -25,7 +26,7 @@ class QWindowsUiaMainProvider :
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWindowsUiaMainProvider)
public:
static QWindowsUiaMainProvider *providerForAccessible(QAccessibleInterface *accessible);
static ComPtr<QWindowsUiaMainProvider> providerForAccessible(QAccessibleInterface *accessible);
explicit QWindowsUiaMainProvider(QAccessibleInterface *a);
virtual ~QWindowsUiaMainProvider();
static void notifyFocusChange(QAccessibleEvent *event);

View File

@ -26,12 +26,13 @@ QWindowsUiaProviderCache *QWindowsUiaProviderCache::instance()
}
// Returns the provider instance associated with the ID, or nullptr.
QWindowsUiaMainProvider *QWindowsUiaProviderCache::providerForId(QAccessible::Id id) const
ComPtr<QWindowsUiaMainProvider> QWindowsUiaProviderCache::providerForId(QAccessible::Id id) const
{
QMutexLocker guard{ &m_tableMutex };
QWindowsUiaMainProvider *provider = m_providerTable.value(id);
if (provider)
provider->AddRef(); // Make sure lifetime is extended while holding the mutex
// Make sure lifetime is extended while holding the mutex
ComPtr<QWindowsUiaMainProvider> provider = m_providerTable.value(id);
return provider;
}

View File

@ -12,6 +12,7 @@
#include <QtCore/qhash.h>
#include <QtCore/qmutex.h>
#include <QtGui/qaccessible.h>
#include <QtCore/private/qcomptr_p.h>
QT_BEGIN_NAMESPACE
@ -22,7 +23,7 @@ class QWindowsUiaProviderCache : public QObject
Q_OBJECT
public:
static QWindowsUiaProviderCache *instance();
QWindowsUiaMainProvider *providerForId(QAccessible::Id id) const;
ComPtr<QWindowsUiaMainProvider> providerForId(QAccessible::Id id) const;
void insert(QAccessible::Id id, QWindowsUiaMainProvider *provider);
private Q_SLOTS:

View File

@ -178,7 +178,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::get_SelectionContain
QAccessibleInterface *parent = accessible->parent();
if (parent && parent->selectionInterface()) {
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(parent); // Detach
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(parent).Detach();
return S_OK;
}
@ -190,7 +190,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::get_SelectionContain
if (parent) {
if ((accessible->role() == QAccessible::ListItem && parent->role() == QAccessible::List)
|| (accessible->role() == QAccessible::PageTab && parent->role() == QAccessible::PageTabList)) {
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(parent); // Detach
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(parent).Detach();
}
}
return S_OK;

View File

@ -65,9 +65,9 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::GetSelection(SAFEARRAY *
if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, selectedList.size()))) {
for (LONG i = 0; i < selectedList.size(); ++i) {
if (QWindowsUiaMainProvider *childProvider = QWindowsUiaMainProvider::providerForAccessible(selectedList.at(i))) {
SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(childProvider));
childProvider->Release();
if (ComPtr<IRawElementProviderSimple> provider =
QWindowsUiaMainProvider::providerForAccessible(selectedList.at(i))) {
SafeArrayPutElement(*pRetVal, &i, provider.Get());
}
}
}
@ -161,9 +161,9 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_FirstSelectedItem(__
if (!firstSelectedChild)
return UIA_E_ELEMENTNOTAVAILABLE;
if (QWindowsUiaMainProvider *childProvider = QWindowsUiaMainProvider::providerForAccessible(firstSelectedChild))
{
*pRetVal = static_cast<IRawElementProviderSimple *>(childProvider); // Detach
if (ComPtr<IRawElementProviderSimple> childProvider =
QWindowsUiaMainProvider::providerForAccessible(firstSelectedChild)) {
*pRetVal = childProvider.Detach();
return S_OK;
}
@ -206,9 +206,9 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_LastSelectedItem(__R
if (!lastSelectedChild)
return UIA_E_ELEMENTNOTAVAILABLE;
if (QWindowsUiaMainProvider *childProvider = QWindowsUiaMainProvider::providerForAccessible(lastSelectedChild))
{
*pRetVal = static_cast<IRawElementProviderSimple *>(childProvider); // Detach
if (ComPtr<IRawElementProviderSimple> childProvider =
QWindowsUiaMainProvider::providerForAccessible(lastSelectedChild)) {
*pRetVal = childProvider.Detach();
return S_OK;
}

View File

@ -48,9 +48,9 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTableItemProvider::GetRowHeaderItems(SAFEAR
if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) {
for (LONG i = 0; i < headers.size(); ++i) {
if (QWindowsUiaMainProvider *headerProvider = QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) {
SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(headerProvider));
headerProvider->Release();
if (ComPtr<IRawElementProviderSimple> provider =
QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) {
SafeArrayPutElement(*pRetVal, &i, provider.Get());
}
}
}
@ -78,9 +78,9 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTableItemProvider::GetColumnHeaderItems(SAF
if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) {
for (LONG i = 0; i < headers.size(); ++i) {
if (QWindowsUiaMainProvider *headerProvider = QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) {
SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(headerProvider));
headerProvider->Release();
if (ComPtr<IRawElementProviderSimple> provider =
QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) {
SafeArrayPutElement(*pRetVal, &i, provider.Get());
}
}
}

View File

@ -55,9 +55,9 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTableProvider::GetRowHeaders(SAFEARRAY **pR
}
if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) {
for (LONG i = 0; i < headers.size(); ++i) {
if (QWindowsUiaMainProvider *headerProvider = QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) {
SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(headerProvider));
headerProvider->Release();
if (ComPtr<IRawElementProviderSimple> provider =
QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) {
SafeArrayPutElement(*pRetVal, &i, provider.Get());
}
}
}
@ -92,9 +92,9 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTableProvider::GetColumnHeaders(SAFEARRAY *
}
if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) {
for (LONG i = 0; i < headers.size(); ++i) {
if (QWindowsUiaMainProvider *headerProvider = QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) {
SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(headerProvider));
headerProvider->Release();
if (ComPtr<IRawElementProviderSimple> provider =
QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) {
SafeArrayPutElement(*pRetVal, &i, provider.Get());
}
}
}

View File

@ -265,7 +265,7 @@ HRESULT QWindowsUiaTextRangeProvider::GetEnclosingElement(IRawElementProviderSim
if (!accessible)
return UIA_E_ELEMENTNOTAVAILABLE;
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(accessible); // Detach
*pRetVal = QWindowsUiaMainProvider::providerForAccessible(accessible).Detach();
return S_OK;
}

View File

@ -5,24 +5,11 @@
#ifdef Q_OS_WIN
# include <private/qcomobject_p.h>
# include <wrl/client.h>
using Microsoft::WRL::ComPtr;
#include <private/qcomobject_p.h>
#include <QtCore/private/qcomptr_p.h>
QT_BEGIN_NAMESPACE
template <typename T, typename... Args>
ComPtr<T> makeComObject(Args &&...args)
{
ComPtr<T> p;
// Don't use Attach because of MINGW64 bug
// #892 Microsoft::WRL::ComPtr::Attach leaks references
*p.GetAddressOf() = new T(std::forward<Args>(args)...);
return p;
}
MIDL_INTERFACE("878fab04-7da0-41ea-9c49-058c7fa0d80a")
IIntermediate : public IUnknown{};