diff options
author | Oliver Wolff <oliver.wolff@qt.io> | 2022-07-13 15:57:22 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2022-07-14 07:52:01 +0000 |
commit | 7b3c2f06de2ef65a8d72c4d1e0b942052d2b3c12 (patch) | |
tree | 2217b25f86f8e3aa046e5fe5c4c4520bb4d48184 | |
parent | 777fd50ba3117a166896ae4831711e988e23ff23 (diff) |
Use QObject::metaObject instead of QAxBase::axBaseMetaObject in qaxbase.cpp
Using QAxBase::axBaseMetaObject results in usage of the dynamically
queried COM object whenever it is used. This behavior is not always what
we want though. If a type library was queried for its interface with
dumpcpp we should use the information from the resulting h and cpp files
and do not operate on the information given by the COM object. The files
generated by dumpcpp will override the virtual metaObject function.
By using QObject::metaObject instead of QAxBase::axBaseMetaObject we
make sure that:
a) Dynamically queried information is used if no overload has been added
by dumpcpp. This is the case because QAxWidget::metaObject and
QAxObject::metaObject return QAxBase::axBaseMetaObject. So the
functionality there does not change.
b) If dumpcpp was run on a type library the types in the code generated
by dumpcpp will overload QObject::metaObject. In this cases we will only
use the information from dumpcpp runs.
With the previous approach it was possible that we run into issues if
there are inconsistencies between a user's type library and the actual
COM interface. If a function was available in the COM interface but not
inside the type library definitions that might have thrown off ActiveQt
which resulted in calls of wrong versions. This regression (it worked as
expected in Qt5) is fixed by this patch.
Pick-to: 6.4 6.3 6.2
Change-Id: I1af5ecb81f0c4ce0dc1e899cc3f019ebee575f4b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r-- | src/activeqt/container/qaxbase.cpp | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index e1cb0c8..d85ca1f 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -341,7 +341,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; @@ -450,7 +450,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; @@ -458,10 +462,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)); @@ -577,7 +577,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(); @@ -3261,7 +3261,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(); @@ -3366,7 +3366,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); @@ -3484,7 +3484,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); @@ -3500,7 +3500,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; @@ -3525,7 +3525,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) { @@ -3573,7 +3573,7 @@ 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); @@ -4015,7 +4015,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"); @@ -4025,7 +4025,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"); @@ -4132,7 +4132,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()); @@ -4172,7 +4172,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())); |