Enable IAccessible2 for MinGW

MinGW 5.3 is able to compile the IAccessible2 classes. All that is needed
is some way to provide the missing IIDs, which is done via specialization
of a function template (similar to the MinGW's __uuidof operator).

[ChangeLog][Windows][Accessibility] MinGW builds now support IAccessible2.

Change-Id: I218a4b89c81b54aa96f7c743544388631ca9a53e
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
bb10
Friedemann Kleint 2017-07-11 10:27:56 +02:00
parent a06148e341
commit 4f599c5ea1
8 changed files with 49 additions and 38 deletions

View File

@ -16,7 +16,9 @@
*/
/* @@MIDL_FILE_HEADING( ) */
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#ifdef _MSC_VER
# pragma warning( disable: 4049 ) /* more than 64k source lines */
#endif
/* verify that the <rpcndr.h> version is high enough to compile this file*/

View File

@ -18,7 +18,9 @@
*/
/* @@MIDL_FILE_HEADING( ) */
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#ifdef _MSC_VER
# pragma warning( disable: 4049 ) /* more than 64k source lines */
#endif
#ifdef __cplusplus
@ -65,7 +67,7 @@ typedef IID CLSID;
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
#endif !_MIDL_USE_GUIDDEF_
#endif // !_MIDL_USE_GUIDDEF_
MIDL_DEFINE_GUID(IID, IID_IAccessibleRelation,0x7CDF86EE,0xC3DA,0x496a,0xBD,0xA4,0x28,0x1B,0x33,0x6E,0x1F,0xDC);

View File

@ -6,13 +6,14 @@ HEADERS += \
$$PWD/qwindowsaccessibility.h \
$$PWD/comutils.h
SOURCES += $$PWD/qwindowsmsaaaccessible.cpp
HEADERS += $$PWD/qwindowsmsaaaccessible.h
SOURCES += \
$$PWD/qwindowsmsaaaccessible.cpp \
$$PWD/iaccessible2.cpp
!mingw: {
SOURCES += $$PWD/iaccessible2.cpp
HEADERS += $$PWD/iaccessible2.h
include(../../../../3rdparty/iaccessible2/iaccessible2.pri)
}
HEADERS += \
$$PWD/qwindowsmsaaaccessible.h \
$$PWD/iaccessible2.h
include(../../../../3rdparty/iaccessible2/iaccessible2.pri)
mingw: LIBS *= -luuid

View File

@ -52,6 +52,12 @@
QT_BEGIN_NAMESPACE
#ifdef Q_CC_MINGW
// MinGW's __uuidof operator does not work for the Accessible2 interfaces
template <>
IID qUuidOf<IAccessibleComponent>() { return IID_IAccessibleComponent; }
#endif // Q_CC_MINGW
class QWindowsIA2Accessible : public QWindowsMsaaAccessible,
public IAccessibleAction,
public IAccessibleComponent,
@ -258,6 +264,19 @@ private:
/**************************************************************\
* AccessibleApplication *
**************************************************************/
#ifdef Q_CC_MINGW
// MinGW's __uuidof operator does not work for the IAccessible2 interfaces
template <>
IID qUuidOf<IAccessibleApplication>() { return IID_IAccessibleApplication; }
template <>
IID qUuidOf<IAccessible2>() { return IID_IAccessible2; }
template <>
IID qUuidOf<IAccessibleRelation>() { return IID_IAccessibleRelation; }
#endif // Q_CC_MINGW
class AccessibleApplication : public QWindowsComBase<IAccessibleApplication>
{
public:
@ -277,6 +296,9 @@ public:
/**************************************************************\
* AccessibleRelation *
**************************************************************/
class AccessibleRelation : public QWindowsComBase<IAccessibleRelation>
{
public:

View File

@ -56,11 +56,7 @@
#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h> // registry helper
#include "qwindowsaccessibility.h"
#ifdef Q_CC_MINGW
# include "qwindowsmsaaaccessible.h"
#else
# include "iaccessible2.h"
#endif
#include "iaccessible2.h"
#include "comutils.h"
#include <oleacc.h>
@ -198,11 +194,7 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc)
if (!QAccessible::uniqueId(acc))
QAccessible::registerAccessibleInterface(acc);
# ifdef Q_CC_MINGW
QWindowsMsaaAccessible *wacc = new QWindowsMsaaAccessible(acc);
# else
QWindowsIA2Accessible *wacc = new QWindowsIA2Accessible(acc);
# endif
IAccessible *iacc = 0;
wacc->QueryInterface(IID_IAccessible, reinterpret_cast<void **>(&iacc));
return iacc;

View File

@ -156,7 +156,7 @@ void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleIn
HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::QueryInterface(REFIID id, LPVOID *iface)
{
*iface = nullptr;
const bool result = qWindowsComQueryUnknownInterfaceMulti<AccessibleBase>(this, id, iface)
const bool result = qWindowsComQueryUnknownInterfaceMulti<IAccessible2>(this, id, iface)
|| qWindowsComQueryInterface<IDispatch>(this, id, iface)
|| qWindowsComQueryInterface<IAccessible>(this, id, iface)
|| qWindowsComQueryInterface<IOleWindow>(this, id, iface);
@ -1172,7 +1172,6 @@ const char *QWindowsAccessibleGuid::iidToString(const GUID &id)
result = "IID_IOleWindow";
else if (id == IID_IServiceProvider)
result = "IID_IServiceProvider";
#ifndef Q_CC_MINGW
else if (id == IID_IAccessible2)
result = "IID_IAccessible2";
else if (id == IID_IAccessibleAction)
@ -1201,7 +1200,6 @@ const char *QWindowsAccessibleGuid::iidToString(const GUID &id)
result = "IID_IAccessibleText";
else if (id == IID_IAccessibleValue)
result = "IID_IAccessibleValue";
#endif // !Q_CC_MINGW
return result;
}

View File

@ -46,14 +46,8 @@
#include <QtCore/qt_windows.h>
#include <QtCore/qsharedpointer.h>
#include <QtGui/qaccessible.h>
#ifndef Q_CC_MINGW
# include <oleacc.h>
# include "ia2_api_all.h" // IAccessible2 inherits from IAccessible
#else
// MinGW
# include <basetyps.h>
# include <oleacc.h>
#endif
#include <oleacc.h>
#include "ia2_api_all.h" // IAccessible2 inherits from IAccessible
QT_BEGIN_NAMESPACE
@ -88,13 +82,7 @@ QDebug operator<<(QDebug d, const QWindowsAccessibleGuid &aguid);
* QWindowsAccessible *
**************************************************************/
#ifndef Q_CC_MINGW
typedef IAccessible2 AccessibleBase;
#else
typedef IAccessible AccessibleBase;
#endif
class QWindowsMsaaAccessible : public AccessibleBase, public IOleWindow
class QWindowsMsaaAccessible : public IAccessible2, public IOleWindow
{
public:
QWindowsMsaaAccessible(QAccessibleInterface *a)

View File

@ -46,11 +46,17 @@
QT_BEGIN_NAMESPACE
// The __uuidof operator of MinGW does not work for all interfaces (for example,
// IAccessible2). Specializations of this function can be provides to work
// around this.
template <class DesiredInterface>
static IID qUuidOf() { return __uuidof(DesiredInterface); }
// Helper for implementing IUnknown::QueryInterface.
template <class DesiredInterface, class Derived>
bool qWindowsComQueryInterface(Derived *d, REFIID id, LPVOID *iface)
{
if (id == __uuidof(DesiredInterface)) {
if (id == qUuidOf<DesiredInterface>()) {
*iface = static_cast<DesiredInterface *>(d);
d->AddRef();
return true;