diff options
Diffstat (limited to 'src/activeqt/container/qaxbase.cpp')
-rw-r--r-- | src/activeqt/container/qaxbase.cpp | 310 |
1 files changed, 160 insertions, 150 deletions
diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index 21b94e1..3463f3c 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -1,52 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the ActiveQt framework of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause //#define QAX_NO_CLASSINFO @@ -68,7 +21,8 @@ #include <qsettings.h> #include <qdebug.h> #include <QGuiApplication> -#include <qpa/qplatformnativeinterface.h> +#include <private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> #ifndef QT_NO_THREAD # include <qmutex.h> @@ -77,6 +31,7 @@ #include <private/qobject_p.h> #include <private/qmetaobject_p.h> #include <private/qmetaobjectbuilder_p.h> +#include <private/qtools_p.h> #include <qt_windows.h> #include <ocidl.h> @@ -185,7 +140,7 @@ int QMetaObjectExtra::numParameter(const QByteArray &prototype) const if (!memberInfo.contains(prototype)) parsePrototype(prototype); - return memberInfo.value(prototype).count(); + return memberInfo.value(prototype).size(); } QByteArray QMetaObjectExtra::paramType(const QByteArray &prototype, int index, bool *out) const @@ -197,7 +152,7 @@ QByteArray QMetaObjectExtra::paramType(const QByteArray &prototype, int index, b *out = false; const auto plist = memberInfo.value(prototype); - if (index > plist.count() - 1) + if (index > plist.size() - 1) return QByteArray(); QByteArray param(plist.at(index)); @@ -387,7 +342,7 @@ public: if (qobject->signalsBlocked()) return S_OK; - const QMetaObject *meta = combase->axBaseMetaObject(); + const QMetaObject *meta = qobject->metaObject(); const QMetaObjectExtra &moExtra = moextra_cache.value(meta); int index = -1; @@ -444,7 +399,7 @@ public: varp[p + 1] = VARIANTToQVariant(pDispParams->rgvarg[pcount - p - 1], ptype); argv_pointer[p + 1] = nullptr; if (varp[p + 1].isValid()) { - if (varp[p + 1].type() == QVariant::UserType) { + if (varp[p + 1].metaType().id() >= QMetaType::User) { argv[p + 1] = varp[p + 1].data(); } else if (ptype == "QVariant") { argv[p + 1] = varp + p + 1; @@ -496,7 +451,11 @@ public: if (dispID == DISPID_UNKNOWN || !combase) return S_OK; - const QMetaObject *meta = combase->axBaseMetaObject(); + QObject *qobject = combase->qObject(); + if (qobject->signalsBlocked()) + return S_OK; + + const QMetaObject *meta = qobject->metaObject(); if (!meta) return S_OK; @@ -504,10 +463,6 @@ public: if (propname.isEmpty()) return S_OK; - QObject *qobject = combase->qObject(); - if (qobject->signalsBlocked()) - return S_OK; - // emit the generic signal combase->d->emitPropertyChanged(QString::fromLatin1(propname)); @@ -528,7 +483,7 @@ public: const QMetaProperty metaProp = meta->property(meta->indexOfProperty(propname)); void *argv[] = {nullptr, var.data()}; - if (metaProp.type() == QVariant::Type(QMetaType::QVariant) || metaProp.type() == QVariant::LastType) + if (metaProp.metaType().id() == QMetaType::QVariant) argv[1] = &var; // emit the "changed" signal @@ -581,8 +536,8 @@ QAxBasePrivate::QAxBasePrivate() QMutexLocker locker(&cache_mutex); mo_cache_ref++; - qRegisterMetaType<IUnknown*>("IUnknown*", &ptr); - qRegisterMetaType<IDispatch*>("IDispatch*", &disp); + qRegisterMetaType<IUnknown*>("IUnknown*"); + qRegisterMetaType<IDispatch*>("IDispatch*"); } QAxBasePrivate::~QAxBasePrivate() @@ -623,7 +578,7 @@ QByteArray QAxEventSink::findProperty(DISPID dispID) typeinfo->Release(); QByteArray propsignal(propname + "Changed("); - const QMetaObject *mo = combase->axBaseMetaObject(); + const QMetaObject *mo = combase->qObject()->metaObject(); int index = mo->indexOfProperty(propname); const QMetaProperty prop = mo->property(index); propsignal += prop.typeName(); @@ -818,7 +773,7 @@ QVariant QAxBasePrivate::VARIANTToQVariant(const VARIANT &arg, const QByteArray */ /*! - \typedef QAxBase::PropertyBag + \typealias QAxBase::PropertyBag A QMap<QString,QVariant> that can store properties as name:value pairs. */ @@ -920,6 +875,9 @@ bool QAxBase::setControl(const QString &c) return true; } +/*! + Returns the ActiveX control. +*/ QString QAxBase::control() const { return d->ctrl; @@ -1114,6 +1072,8 @@ long QAxBase::indexOfVerb(const QString &verb) const */ bool QAxBase::initialize(IUnknown **ptr) { + using QWindowsApplication = QNativeInterface::Private::QWindowsApplication; + if (*ptr || control().isEmpty()) return false; @@ -1121,11 +1081,8 @@ bool QAxBase::initialize(IUnknown **ptr) // Otherwise painter can get corrupted if Invoke or some other COM method that cause Windows // messages to be processed is called during an existing paint operation when WM_PAINT is // also in the queue. - static bool asyncExposeSet = false; - if (!asyncExposeSet && QGuiApplication::platformNativeInterface()) { - QGuiApplication::platformNativeInterface()->setProperty("asyncExpose", QVariant(true)); - asyncExposeSet = true; - } + if (auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration())) + nativeWindowsApp->setAsyncExpose(true); *ptr = nullptr; @@ -1800,6 +1757,63 @@ MetaObjectGenerator::~MetaObjectGenerator() bool qax_dispatchEqualsIDispatch = true; QByteArrayList qax_qualified_usertypes; +// Value strings for enums +QHash<QByteArray, QByteArray> qax_enum_values; + +// Read enum values +QList<QPair<QByteArray, int> > qax_readEnumValues(ITypeLib *typelib, UINT index) +{ + QList<QPair<QByteArray, int> > result; + + // Get the type information for the enum + ITypeInfo *enuminfo = nullptr; + typelib->GetTypeInfo(index, &enuminfo); + if (!enuminfo) + return result; + + // Get the attributes of the enum type + TYPEATTR *typeattr = nullptr; + enuminfo->GetTypeAttr(&typeattr); + if (typeattr == nullptr) { + enuminfo->Release(); + return result; + } + + // Get all values of the enumeration + result.reserve(typeattr->cVars); + for (UINT vd = 0; vd < typeattr->cVars; ++vd) { + VARDESC *vardesc = nullptr; + enuminfo->GetVarDesc(vd, &vardesc); + if (vardesc != nullptr) { + if (vardesc->varkind == VAR_CONST) { + const int value = vardesc->lpvarValue->lVal; + QByteArray valueName = qaxTypeInfoName(enuminfo, vardesc->memid); + result.append({valueName, value}); + } + enuminfo->ReleaseVarDesc(vardesc); + } + } + enuminfo->ReleaseTypeAttr(typeattr); + enuminfo->Release(); + return result; +} + +// Format enum values into a string v1=1, v2=2,... +static QByteArray enumValueString(ITypeLib *typelib, UINT index) +{ + QByteArray result; + const auto enumValues = qax_readEnumValues(typelib, index); + const auto last = enumValues.size() - 1; + for (qsizetype i = 0; i <= last; ++i) { + const auto &enumValue = enumValues.at(i); + result += " " + enumValue.first + '=' + + QByteArray::number(enumValue.second); + if (i < last) + result += ','; + result += '\n'; + } + return result; +} QByteArray MetaObjectGenerator::usertypeToString(const TYPEDESC &tdesc, ITypeInfo *info, const QByteArray &function) { @@ -1856,8 +1870,11 @@ QByteArray MetaObjectGenerator::usertypeToString(const TYPEDESC &tdesc, ITypeInf } break; case TKIND_ENUM: - if (typeLibName != current_typelib) + if (typeLibName != current_typelib) { userTypeName.prepend(typeLibName + "::"); + // For dumpcpp + qax_enum_values.insert(userTypeName, enumValueString(usertypelib, index)); + } if (!qax_qualified_usertypes.contains("enum " + userTypeName)) qax_qualified_usertypes << "enum " + userTypeName; break; @@ -2092,7 +2109,7 @@ void MetaObjectGenerator::readClassInfo() if (dispInfo && !typelib) dispInfo->GetContainingTypeLib(&typelib, &index); - if (!typelib) { + if (!typelib && !that->control().isEmpty()) { QSettings controls(QLatin1String("HKEY_LOCAL_MACHINE\\Software"), QSettings::NativeFormat); QString tlid = controls.value(QLatin1String("/Classes/CLSID/") + that->control() + QLatin1String("/TypeLib/.")).toString(); QString tlfile; @@ -2159,8 +2176,11 @@ void MetaObjectGenerator::readClassInfo() } } - if (!d || !dispInfo || !cacheKey.isEmpty() || !d->tryCache) + if (!d || !dispInfo || !cacheKey.isEmpty() || !d->tryCache) { + if (disp && !dispInfo) + qWarning("%s: IDispatch %p does not provide interface information", Q_FUNC_INFO, disp); return; + } TYPEATTR *typeattr = nullptr; dispInfo->GetTypeAttr(&typeattr); @@ -2207,10 +2227,9 @@ void MetaObjectGenerator::readEnumInfo() TYPEKIND typekind; typelib->GetTypeInfoType(i, &typekind); if (typekind == TKIND_ENUM) { - // Get the type information for the enum - ITypeInfo *enuminfo = nullptr; - typelib->GetTypeInfo(i, &enuminfo); - if (!enuminfo) + // Get the values of the enum + const auto values = qax_readEnumValues(typelib, i); + if (values.isEmpty()) continue; // Get the name of the enumeration @@ -2224,31 +2243,15 @@ void MetaObjectGenerator::readEnumInfo() } // Get the attributes of the enum type - TYPEATTR *typeattr = nullptr; - enuminfo->GetTypeAttr(&typeattr); - if (typeattr) { - // Get all values of the enumeration - for (UINT vd = 0; vd < typeattr->cVars; ++vd) { - VARDESC *vardesc = nullptr; - enuminfo->GetVarDesc(vd, &vardesc); - if (vardesc && vardesc->varkind == VAR_CONST) { - int value = vardesc->lpvarValue->lVal; - int memid = vardesc->memid; - // Get the name of the value - QByteArray valueName = qaxTypeInfoName(enuminfo, memid); - if (valueName.isEmpty()) - valueName = "value" + QByteArray::number(valueindex++); - if (clashCheck.contains(QString::fromLatin1(valueName))) - valueName += QByteArray::number(++clashIndex); - - clashCheck.insert(QString::fromLatin1(valueName)); - addEnumValue(enumName, valueName, value); - } - enuminfo->ReleaseVarDesc(vardesc); - } + for (const auto &value : values) { + QByteArray valueName = value.first; + if (valueName.isEmpty()) + valueName = "value" + QByteArray::number(valueindex++); + if (clashCheck.contains(QString::fromLatin1(valueName))) + valueName += QByteArray::number(++clashIndex); + clashCheck.insert(QString::fromLatin1(valueName)); + addEnumValue(enumName, valueName, value.second); } - enuminfo->ReleaseTypeAttr(typeattr); - enuminfo->Release(); } } @@ -2282,7 +2285,7 @@ void MetaObjectGenerator::addSetterSlot(const QByteArray &property) if (isupper(prototype.at(0))) { prototype.insert(0, "Set"); } else { - prototype[0] = char(toupper(prototype[0])); + prototype[0] = QtMiscUtils::toAsciiUpper(prototype[0]); prototype.insert(0, "set"); } const QByteArray type = propertyType(property); @@ -2315,8 +2318,8 @@ QByteArray MetaObjectGenerator::createPrototype(FUNCDESC *funcdesc, ITypeInfo *t if (funcdesc->invkind == INVOKE_FUNC && type == hresult) type = nullptr; - int p; - for (p = 1; p < names.count(); ++p) { + qsizetype p; + for (p = 1; p < names.size(); ++p) { // parameter QByteArray paramName = names.at(p); bool optional = p > (funcdesc->cParams - funcdesc->cParamsOpt); @@ -2415,7 +2418,7 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) if (funcdesc->cParams - funcdesc->cParamsOpt <= 1) { bool dontBreak = false; // getter with non-default-parameters -> fall through to function handling - if (funcdesc->invkind == INVOKE_PROPERTYGET && parameters.count() && funcdesc->cParams - funcdesc->cParamsOpt) { + if (funcdesc->invkind == INVOKE_PROPERTYGET && !parameters.isEmpty() && funcdesc->cParams - funcdesc->cParamsOpt) { dontBreak = true; } else { uint flags = Readable; @@ -2480,7 +2483,7 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) set = "Set"; } else { set = "set"; - prototype[0] = char(toupper(prototype[0])); + prototype[0] = QtMiscUtils::toAsciiUpper(prototype[0]); } prototype = set + prototype; @@ -2492,9 +2495,9 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) bool defargs; do { QByteArray pnames; - for (int p = 0; p < parameters.count(); ++p) { + for (qsizetype p = 0; p < parameters.size(); ++p) { pnames += parameters.at(p); - if (p < parameters.count() - 1) + if (p < parameters.size() - 1) pnames += ','; } defargs = pnames.contains("=0"); @@ -2506,7 +2509,7 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) if (defargs) { parameters.takeLast(); - int lastParam = prototype.lastIndexOf(','); + qsizetype lastParam = prototype.lastIndexOf(','); if (lastParam == -1) lastParam = prototype.indexOf('(') + 1; prototype.truncate(lastParam); @@ -2719,9 +2722,9 @@ void MetaObjectGenerator::readEventInterface(ITypeInfo *eventinfo, IConnectionPo prototype = createPrototype(/*in*/ funcdesc, eventinfo, names, /*out*/type, parameters); if (!hasSignal(prototype)) { QByteArray pnames; - for (int p = 0; p < parameters.count(); ++p) { + for (qsizetype p = 0; p < parameters.size(); ++p) { pnames += parameters.at(p); - if (p < parameters.count() - 1) + if (p < parameters.size() - 1) pnames += ','; } addSignal(prototype, pnames); @@ -2942,6 +2945,7 @@ void MetaObjectGenerator::buildMethods(const QMap<QByteArray, Method> &map, QMetaObject *MetaObjectGenerator::metaObject(const QMetaObject *parentObject, const QByteArray &className) { + QSignalBlocker blockSignals(that ? that->qObject() : nullptr); if (that) { readClassInfo(); if (typelib) { @@ -2992,7 +2996,7 @@ QMetaObject *MetaObjectGenerator::metaObject(const QMetaObject *parentObject, co // each enum in form name\0 for (auto it = enum_list.cbegin(), end = enum_list.cend(); it != end; ++it) { QMetaEnumBuilder enumBuilder = builder.addEnumerator(it.key()); - for (auto v : it.value()) + for (const auto &v : it.value()) enumBuilder.addKey(v.first, v.second); } @@ -3065,7 +3069,7 @@ const QMetaObject *QAxBase::axBaseMetaObject() const */ void QAxBase::connectNotify() { - if (d->eventSink.count()) // already listening + if (!d->eventSink.isEmpty()) // already listening return; IEnumConnectionPoints *epoints = nullptr; @@ -3112,7 +3116,7 @@ void QAxBase::connectNotify() IID conniid; cpoint->GetConnectionInterface(&conniid); // workaround for typelibrary bug of Word.Application - QString connuuid(QUuid(conniid).toString()); + const QUuid connuuid(conniid); if (d->eventSink.contains(connuuid)) break; @@ -3162,8 +3166,8 @@ void QAxBase::connectNotify() typelib->Release(); // make sure we don't try again - if (!d->eventSink.count()) - d->eventSink.insert(QString(), 0); + if (d->eventSink.isEmpty()) + d->eventSink.insert(QUuid{}, nullptr); } /*! @@ -3259,7 +3263,7 @@ bool QAxBasePrivate::checkHRESULT(HRESULT hres, EXCEPINFO *exc, const QString &n */ int QAxBase::internalProperty(QMetaObject::Call call, int index, void **v) { - const QMetaObject *mo = axBaseMetaObject(); + const QMetaObject *mo = qObject()->metaObject(); const QMetaProperty prop = mo->property(index + mo->propertyOffset()); QByteArray propname = prop.name(); @@ -3298,11 +3302,12 @@ int QAxBase::internalProperty(QMetaObject::Call call, int index, void **v) hres = Invoke(disp, dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &arg, &excepinfo, nullptr); // map result VARIANTARG to void* - uint type = QVariant::Int; + int type = QMetaType::Int; if (!prop.isEnumType()) - type = prop.type(); + type = prop.metaType().id(); QVariantToVoidStar(VARIANTToQVariant(arg, proptype, type), *v, proptype, type); - if ((arg.vt != VT_DISPATCH && arg.vt != VT_UNKNOWN) || type == QVariant::Pixmap || type == QVariant::Font) + if ((arg.vt != VT_DISPATCH && arg.vt != VT_UNKNOWN) + || type == QMetaType::QPixmap || type == QMetaType::QFont) clearVARIANT(&arg); } break; @@ -3329,7 +3334,7 @@ int QAxBase::internalProperty(QMetaObject::Call call, int index, void **v) qvar = *reinterpret_cast<const QVariant *>(v[0]); proptype = nullptr; } else { - qvar = QVariant(typeId, v[0]); + qvar = QVariant(prop.metaType(), v[0]); if (typeId < QMetaType::User) proptype = moExtra.propertyType(propname); } @@ -3363,7 +3368,7 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) if (!disp) return index; - const QMetaObject *mo = axBaseMetaObject(); + const QMetaObject *mo = qObject()->metaObject(); // get the slot information const QMetaMethod slot = mo->method(index + mo->methodOffset()); Q_ASSERT(slot.methodType() == QMetaMethod::Slot); @@ -3409,11 +3414,11 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) int p; for (p = 0; p < int(params.cArgs); ++p) { bool out; - QByteArray type = moExtra.paramType(signature, p, &out); - QVariant::Type vt = QVariant::nameToType(type); + const QByteArray type = moExtra.paramType(signature, p, &out); + const QMetaType metaType = QMetaType::fromName(type); QVariant qvar; - if (vt != QVariant::UserType && vt != int(QMetaType::QVariant)) - qvar = QVariant(vt, v[p + 1]); + if (metaType.id() != QMetaType::User && metaType.id() != QMetaType::QVariant) + qvar = QVariant(metaType, v[p + 1]); if (!qvar.isValid()) { if (type == "IDispatch*") { @@ -3428,7 +3433,7 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) } else if (mo->indexOfEnumerator(type) != -1) { qvar = *reinterpret_cast<const int *>(v[p + 1]); } else { - qvar = QVariant(QMetaType::type(type), v[p + 1]); + qvar = QVariant(metaType, v[p + 1]); } } @@ -3448,7 +3453,7 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) // get return value if (hres == S_OK && ret.vt != VT_EMPTY) { - QVariantToVoidStar(VARIANTToQVariant(ret, slot.typeName()), v[0], slot.typeName()); + QVariantToVoidStar(VARIANTToQVariant(ret, slot.typeName(), slot.returnType()), v[0], slot.typeName()); if (ret.vt != VT_DISPATCH) clearVARIANT(&ret); else @@ -3481,7 +3486,7 @@ int QAxBasePrivate::qtStaticMetaCall(QAxBase *_t, QMetaObject::Call _c, int _id, if (_c != QMetaObject::InvokeMetaMethod) return 0; Q_ASSERT(_t != nullptr); - const QMetaObject *mo = _t->axBaseMetaObject(); + const QMetaObject *mo = _t->qObject()->metaObject(); switch (mo->method(_id + mo->methodOffset()).methodType()) { case QMetaMethod::Signal: QMetaObject::activate(_t->qObject(), mo, _id, _a); @@ -3497,7 +3502,7 @@ int QAxBasePrivate::qtStaticMetaCall(QAxBase *_t, QMetaObject::Call _c, int _id, int QAxBasePrivate::qtMetaCall(QMetaObject::Call call, int id, void **v) { - const QMetaObject *mo = q->axBaseMetaObject(); + const QMetaObject *mo = q->qObject()->metaObject(); if (q->isNull() && mo->property(id + mo->propertyOffset()).name() != QByteArray("control")) { qWarning("QAxBase::qt_metacall: Object is not initialized, or initialization failed"); return id; @@ -3522,7 +3527,7 @@ int QAxBasePrivate::qtMetaCall(QMetaObject::Call call, int id, void **v) #ifdef QT_CHECK_STATE static void qax_noSuchFunction(int disptype, const QByteArray &name, const QByteArray &function, const QAxBase *that) { - const QMetaObject *metaObject = that->axBaseMetaObject(); + const QMetaObject *metaObject = that->qObject()->metaObject(); const char *coclass = metaObject->classInfo(metaObject->indexOfClassInfo("CoClass")).value(); if (disptype == DISPATCH_METHOD) { @@ -3570,11 +3575,11 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & return false; } - const QMetaObject *mo = axBaseMetaObject(); + const QMetaObject *mo = qObject()->metaObject(); Q_ASSERT(d->metaobj); const QMetaObjectExtra &moExtra = moextra_cache.value(d->metaobj); - int varc = vars.count(); + qsizetype varc = vars.size(); QByteArray normFunction = QMetaObject::normalizedSignature(name); QByteArray function(normFunction); @@ -3684,7 +3689,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & curArg += cc; } - varc = vars.count(); + varc = vars.size(); } } else { if (d->useMetaObject) @@ -3706,7 +3711,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & varc = qMin(varc, moExtra.numParameter(normFunction)); arg = varc <= QAX_NUM_PARAMS ? staticarg : new VARIANT[varc]; outArgs = QBitArray(varc); - for (int i = 0; i < varc; ++i) { + for (qsizetype i = 0; i < varc; ++i) { const QVariant &var = vars.at(i); VariantInit(arg + (varc - i - 1)); bool out = false; @@ -3718,7 +3723,9 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & else paramType = moExtra.paramType(normFunction, i, &out); - if ((!parse && d->useMetaObject && var.type() == QVariant::String) || var.type() == QVariant::ByteArray) { + const int vType = var.metaType().id(); + if ((!parse && d->useMetaObject && vType == QMetaType::QString) + || vType == QMetaType::QByteArray) { int enumIndex =mo->indexOfEnumerator(paramType); if (enumIndex != -1) { QMetaEnum metaEnum =mo->enumerator(enumIndex); @@ -3765,14 +3772,14 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & hres = Invoke(disp, dispid, IID_NULL, LOCALE_USER_DEFAULT, disptype, ¶ms, nullptr, &excepinfo, &argerr); } - if (disptype == (DISPATCH_METHOD|DISPATCH_PROPERTYGET) && hres == S_OK && varc) { - for (int i = 0; i < varc; ++i) + if ((disptype & (DISPATCH_METHOD|DISPATCH_PROPERTYGET)) && hres == S_OK && varc) { + for (qsizetype i = 0; i < varc; ++i) if ((arg[varc-i-1].vt & VT_BYREF) || outArgs[i]) // update out-parameters vars[i] = VARIANTToQVariant(arg[varc-i-1], vars.at(i).typeName()); } // clean up - for (int i = 0; i < varc; ++i) + for (qsizetype i = 0; i < varc; ++i) clearVARIANT(params.rgvarg+i); if (arg && arg != staticarg) delete[] arg; @@ -3900,8 +3907,11 @@ QVariant QAxBase::dynamicCall(const char *function, QList<QVariant> &vars, unsig return QVariant(); QVariant qvar = VARIANTToQVariant(res, rettype); - if ((res.vt != VT_DISPATCH && res.vt != VT_UNKNOWN) || qvar.type() == QVariant::Pixmap || qvar.type() == QVariant::Font) + const int vType = qvar.metaType().id(); + if ((res.vt != VT_DISPATCH && res.vt != VT_UNKNOWN) + || vType == QMetaType::QPixmap || vType == QMetaType::QFont) { clearVARIANT(&res); + } return qvar; } @@ -3980,7 +3990,7 @@ QAxObject *QAxBase::querySubObject(const char *name, QList<QVariant> &vars) if (res.pdispVal) { if (rettype.isEmpty() || rettype == "IDispatch*" || rettype == "QVariant") { object = new QAxObject(res.pdispVal, qObject()); - } else if (QMetaType::type(rettype)) { + } else if (QMetaType::fromName(rettype).id() != QMetaType::UnknownType) { QVariant qvar = VARIANTToQVariant(res, rettype, 0); object = *static_cast<QAxObject**>(qvar.data()); // qVariantGet(qvar, object, rettype); @@ -3994,7 +4004,7 @@ QAxObject *QAxBase::querySubObject(const char *name, QList<QVariant> &vars) if (res.punkVal) { if (rettype.isEmpty() || rettype == "IUnknown*") { object = new QAxObject(res.punkVal, qObject()); - } else if (QMetaType::type(rettype)) { + } else if (QMetaType::fromName(rettype).id() != QMetaType::UnknownType) { QVariant qvar = VARIANTToQVariant(res, rettype, 0); object = *static_cast<QAxObject**>(qvar.data()); // qVariantGet(qvar, object, rettype); @@ -4007,7 +4017,7 @@ QAxObject *QAxBase::querySubObject(const char *name, QList<QVariant> &vars) case VT_EMPTY: #ifdef QT_CHECK_STATE { - auto mo = axBaseMetaObject(); + auto mo = qObject()->metaObject(); const char *coclass = mo->classInfo(mo->indexOfClassInfo("CoClass")).value(); qWarning("QAxBase::querySubObject: %s: Error calling function or property in %s (%s)" , name, control().toLatin1().data(), coclass ? coclass: "unknown"); @@ -4017,7 +4027,7 @@ QAxObject *QAxBase::querySubObject(const char *name, QList<QVariant> &vars) default: #ifdef QT_CHECK_STATE { - auto mo = axBaseMetaObject(); + auto mo = qObject()->metaObject(); const char *coclass = mo->classInfo(mo->indexOfClassInfo("CoClass")).value(); qWarning("QAxBase::querySubObject: %s: Method or property is not of interface type in %s (%s)" , name, control().toLatin1().data(), coclass ? coclass: "unknown"); @@ -4124,7 +4134,7 @@ QAxBase::PropertyBag QAxBase::propertyBag() const persist->Release(); return result; } - const QMetaObject *mo = axBaseMetaObject(); + const QMetaObject *mo = qObject()->metaObject(); for (int p = mo->propertyOffset(); p < mo->propertyCount(); ++p) { const QMetaProperty property = mo->property(p); QVariant var = qObject()->property(property.name()); @@ -4164,7 +4174,7 @@ void QAxBase::setPropertyBag(const PropertyBag &bag) pbag->Release(); persist->Release(); } else { - const QMetaObject *mo = axBaseMetaObject(); + const QMetaObject *mo = qObject()->metaObject(); for (int p = mo->propertyOffset(); p < mo->propertyCount(); ++p) { const QMetaProperty property = mo->property(p); QVariant var = bag.value(QLatin1String(property.name())); @@ -4237,10 +4247,10 @@ QVariant QAxBase::asVariant() const cn.remove(0, cn.lastIndexOf(':') + 1); cn += '*'; QObject *object = qObject(); - int typeId = QMetaType::type(cn); - if (typeId == QMetaType::UnknownType) - typeId = qRegisterMetaType<QObject *>(cn); - qvar = QVariant(typeId, &object); + QMetaType metaType = QMetaType::fromName(cn); + if (metaType.id() == QMetaType::UnknownType) + metaType = QMetaType(qRegisterMetaType<QObject *>(cn)); + qvar = QVariant(metaType, &object); } return qvar; @@ -4253,7 +4263,7 @@ void *qax_createObjectWrapper(int metaType, IUnknown *iface) if (!iface) return nullptr; - void *object = QMetaType::create(metaType, nullptr); + void *object = QMetaType(metaType).create(nullptr); QAxBasePrivate *d = reinterpret_cast<const QAxObject *>(object)->d; d->ptr = iface; |