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:
parent
29c32e7cdc
commit
89ba182737
@ -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
|
||||
|
43
src/corelib/platform/windows/qcomptr_p.h
Normal file
43
src/corelib/platform/windows/qcomptr_p.h
Normal 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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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{};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user