summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-05-13 08:05:39 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-05-28 07:48:53 +0200
commit592dcba7276b129220a27af3bef44a736ca347ba (patch)
treeb5d19d615a54ff109f3fce0bea71589f971a3416
parent9bd2e8f1cc1f98a0fb613e20a971e9eee22e19ae (diff)
Remove hard-coded QMetaObject data
Introduce QAxBaseObject and QAxBaseWidget providing the static properties and signals of QAxObject and QAxWidget. Rename the QAxBase methods to be called from the metacall implementations of QAxObject and QAxWidget. Add "classContext" as a real property on this occasion. Change-Id: Ia4f4e45e091e2d575ed9e6b2dd212139a1146300 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r--src/activeqt/container/CMakeLists.txt1
-rw-r--r--src/activeqt/container/container.pro1
-rw-r--r--src/activeqt/container/qaxbase.cpp301
-rw-r--r--src/activeqt/container/qaxbase.h30
-rw-r--r--src/activeqt/container/qaxbase_p.h12
-rw-r--r--src/activeqt/container/qaxdump.cpp4
-rw-r--r--src/activeqt/container/qaxobject.cpp146
-rw-r--r--src/activeqt/container/qaxobject.h33
-rw-r--r--src/activeqt/container/qaxobjectinterface.h75
-rw-r--r--src/activeqt/container/qaxobjectinterface.qdoc112
-rw-r--r--src/activeqt/container/qaxwidget.cpp188
-rw-r--r--src/activeqt/container/qaxwidget.h30
-rw-r--r--tools/dumpcpp/main.cpp2
-rw-r--r--tools/testcon/invokemethod.cpp4
-rw-r--r--tools/testcon/mainwindow.cpp14
15 files changed, 635 insertions, 318 deletions
diff --git a/src/activeqt/container/CMakeLists.txt b/src/activeqt/container/CMakeLists.txt
index f9b72b4..ddb16d8 100644
--- a/src/activeqt/container/CMakeLists.txt
+++ b/src/activeqt/container/CMakeLists.txt
@@ -13,6 +13,7 @@ qt_add_module(AxContainer
qaxbase.cpp qaxbase.h qaxbase_p.h
qaxdump.cpp
qaxobject.cpp qaxobject.h
+ qaxobjectinterface.h
qaxscript.cpp qaxscript.h
qaxscriptwrapper.cpp
qaxselect.cpp qaxselect.h qaxselect.ui
diff --git a/src/activeqt/container/container.pro b/src/activeqt/container/container.pro
index 3606e87..a5cf33a 100644
--- a/src/activeqt/container/container.pro
+++ b/src/activeqt/container/container.pro
@@ -9,6 +9,7 @@ HEADERS = ../control/qaxaggregated.h \
qaxbase_p.h \
qaxwidget.h \
qaxobject.h \
+ qaxobjectinterface.h \
qaxscript.h \
qaxselect.h \
../shared/qaxtypes_p.h
diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp
index cb4893f..dc0a63d 100644
--- a/src/activeqt/container/qaxbase.cpp
+++ b/src/activeqt/container/qaxbase.cpp
@@ -387,21 +387,13 @@ public:
if (qobject->signalsBlocked())
return S_OK;
- const QMetaObject *meta = combase->metaObject();
+ const QMetaObject *meta = combase->axBaseMetaObject();
const QMetaObjectExtra &moExtra = moextra_cache.value(meta);
int index = -1;
// emit the generic signal "as is"
- if (signalHasReceivers(qobject, "signal(QString,int,void*)")) {
- index = meta->indexOfSignal("signal(QString,int,void*)");
- Q_ASSERT(index != -1);
-
- QString nameString = QLatin1String(signame);
- void *argv[] = {nullptr, &nameString, &pDispParams->cArgs, &pDispParams->rgvarg};
- QAxBase::qt_static_metacall(combase, QMetaObject::InvokeMetaMethod,
- index - meta->methodOffset(), argv);
- }
-
+ combase->d->signalBridge->emitSignal(QLatin1String(signame),
+ pDispParams->cArgs, pDispParams->rgvarg);
HRESULT hres = S_OK;
// get the signal information from the metaobject
@@ -472,7 +464,7 @@ public:
if (ok) {
// emit the generated signal if everything went well
- QAxBase::qt_static_metacall(combase, QMetaObject::InvokeMetaMethod, index - meta->methodOffset(), argv);
+ QAxBase::axBase_qt_static_metacall(combase, QMetaObject::InvokeMetaMethod, index - meta->methodOffset(), argv);
// update the VARIANT for references and free memory
for (p = 0; p < pcount; ++p) {
bool out;
@@ -504,7 +496,7 @@ public:
if (dispID == DISPID_UNKNOWN || !combase)
return S_OK;
- const QMetaObject *meta = combase->metaObject();
+ const QMetaObject *meta = combase->axBaseMetaObject();
if (!meta)
return S_OK;
@@ -517,19 +509,13 @@ public:
return S_OK;
// emit the generic signal
- int index = meta->indexOfSignal("propertyChanged(QString)");
- if (index != -1) {
- QString propnameString = QString::fromLatin1(propname);
- void *argv[] = {nullptr, &propnameString};
- QAxBase::qt_static_metacall(combase, QMetaObject::InvokeMetaMethod,
- index - meta->methodOffset(), argv);
- }
+ combase->d->signalBridge->emitPropertyChanged(QString::fromLatin1(propname));
QByteArray signame = propsigs.value(dispID);
if (signame.isEmpty())
return S_OK;
- index = meta->indexOfSignal(signame);
+ const int index = meta->indexOfSignal(signame);
if (index == -1) // bindable but not marked as bindable in typelib
return S_OK;
@@ -546,8 +532,8 @@ public:
argv[1] = &var;
// emit the "changed" signal
- QAxBase::qt_static_metacall(combase, QMetaObject::InvokeMetaMethod,
- index - meta->methodOffset(), argv);
+ QAxBase::axBase_qt_static_metacall(combase, QMetaObject::InvokeMetaMethod,
+ index - meta->methodOffset(), argv);
}
return S_OK;
}
@@ -612,6 +598,7 @@ QAxBasePrivate::~QAxBasePrivate()
}
CoFreeUnusedLibraries();
+ delete signalBridge;
}
QByteArray QAxEventSink::findProperty(DISPID dispID)
@@ -637,7 +624,7 @@ QByteArray QAxEventSink::findProperty(DISPID dispID)
typeinfo->Release();
QByteArray propsignal(propname + "Changed(");
- const QMetaObject *mo = combase->metaObject();
+ const QMetaObject *mo = combase->axBaseMetaObject();
int index = mo->indexOfProperty(propname);
const QMetaProperty prop = mo->property(index);
propsignal += prop.typeName();
@@ -894,60 +881,6 @@ void QAxBase::initializeFrom(QAxBase *that)
}
}
-/*!
- \property QAxBase::control
- \brief the name of the COM object wrapped by this QAxBase object.
-
- Setting this property initializes the COM object. Any COM object
- previously set is shut down.
-
- The most efficient way to set this property is by using the
- registered component's UUID, e.g.
-
- \snippet src_activeqt_container_qaxbase.cpp 7
-
- The second fastest way is to use the registered control's class
- name (with or without version number), e.g.
-
- \snippet src_activeqt_container_qaxbase.cpp 8
-
- The slowest, but easiest way to use is to use the control's full
- name, e.g.
-
- \snippet src_activeqt_container_qaxbase.cpp 9
-
- It is also possible to initialize the object from a file, e.g.
-
- \snippet src_activeqt_container_qaxbase.cpp 10
-
- If the component's UUID is used the following patterns can be used
- to initialize the control on a remote machine, to initialize a
- licensed control or to connect to a running object:
- \list
- \li To initialize the control on a different machine use the following
- pattern:
-
- \snippet src_activeqt_container_qaxbase.cpp 11
-
- \li To initialize a licensed control use the following pattern:
-
- \snippet src_activeqt_container_qaxbase.cpp 12
-
- \li To connect to an already running object use the following pattern:
-
- \snippet src_activeqt_container_qaxbase.cpp 13
-
- \endlist
- The first two patterns can be combined, e.g. to initialize a licensed
- control on a remote machine:
-
- \snippet src_activeqt_container_qaxbase.cpp 14
-
- The control's read function always returns the control's UUID, if provided including the license
- key, and the name of the server, but not including the username, the domain or the password.
-
- \sa setClassContext()
-*/
bool QAxBase::setControl(const QString &c)
{
if (!c.compare(d->ctrl, Qt::CaseInsensitive))
@@ -1029,7 +962,7 @@ void QAxBase::disableEventSink()
\return the context the ActiveX control will run in (default CLSCTX_SERVER).
*/
-unsigned long QAxBase::classContext() const
+ulong QAxBase::classContext() const
{
return d->classContext;
}
@@ -1047,7 +980,7 @@ unsigned long QAxBase::classContext() const
Note that this function must be called before setControl() to have any
effect.
*/
-void QAxBase::setClassContext(unsigned long classContext)
+void QAxBase::setClassContext(ulong classContext)
{
d->classContext = classContext;
}
@@ -1185,7 +1118,7 @@ long QAxBase::indexOfVerb(const QString &verb) const
if remote or licensed initialization fails, CoCreateInstance
is used directly to create the object.
- See the \l control property documentation for details about
+ See the \l QAxBaseWidget::control property documentation for details about
supported patterns.
The interface returned in \a ptr must be referenced exactly once
@@ -1236,6 +1169,14 @@ bool QAxBase::initialize(IUnknown **ptr)
}
/*!
+ \internal
+*/
+void QAxBase::axBaseInit(QAxBasePrivateSignalBridge *b)
+{
+ d->signalBridge = b;
+}
+
+/*!
Creates an instance of a licensed control, and returns the IUnknown interface
to the object in \a ptr. This functions returns true if successful, otherwise
returns false.
@@ -1247,10 +1188,11 @@ bool QAxBase::initialize(IUnknown **ptr)
*/
bool QAxBase::initializeLicensed(IUnknown** ptr)
{
- int at = control().lastIndexOf(QLatin1String("}:"));
+ const QString ctl = control();
+ int at = ctl.lastIndexOf(QLatin1String("}:"));
- QString clsid(control().left(at));
- QString key(control().mid(at+2));
+ QString clsid(ctl.left(at));
+ QString key(ctl.mid(at+2));
IClassFactory *factory = nullptr;
CoGetClassObject(QUuid(clsid), CLSCTX_SERVER, nullptr, IID_IClassFactory,
@@ -1330,8 +1272,9 @@ bool QAxBase::initializeLicensedHelper(void *f, const QString &key, IUnknown **p
*/
bool QAxBase::initializeActive(IUnknown** ptr)
{
- int at = control().lastIndexOf(QLatin1String("}&"));
- QString clsid(control().left(at));
+ const QString ctl = control();
+ int at = ctl.lastIndexOf(QLatin1String("}&"));
+ QString clsid(ctl.left(at));
GetActiveObject(QUuid(clsid), nullptr, ptr);
@@ -1399,10 +1342,11 @@ static inline void setIdentityString(const QString &v, ULONG &length, USHORT *&t
*/
bool QAxBase::initializeRemote(IUnknown** ptr)
{
- int at = control().lastIndexOf(QLatin1String("/{"));
+ const QString ctl = control();
+ int at = ctl.lastIndexOf(QLatin1String("/{"));
- QString server(control().left(at));
- QString clsid(control().mid(at+1));
+ QString server(ctl.left(at));
+ QString clsid(ctl.mid(at+1));
QString user;
QString domain;
@@ -1482,7 +1426,7 @@ bool QAxBase::initializeRemote(IUnknown** ptr)
Returns the result of the QueryInterface implementation of the COM object.
- \sa control
+ \sa control()
*/
long QAxBase::queryInterface(const QUuid &uuid, void **iface) const
{
@@ -2945,20 +2889,6 @@ QMetaObject *MetaObjectGenerator::tryCache()
return nullptr;
}
-static int nameToBuiltinType(const QByteArray &typeName)
-{
- int id = QMetaType::type(typeName);
- return (id < QMetaType::User) ? id : QMetaType::UnknownType;
-}
-
-static uint nameToTypeInfo(const QByteArray &typeName, QMetaStringTable &strings)
-{
- int id = nameToBuiltinType(typeName);
- const int result = id != QMetaType::UnknownType
- ? id : (IsUnresolvedType) | strings.enter(typeName);
- return uint(result);
-}
-
static void addMetaProperty(QMetaObjectBuilder &builder, const QByteArray &name,
const QByteArray &type, uint flags)
{
@@ -3055,19 +2985,9 @@ QMetaObject *MetaObjectGenerator::metaObject(const QMetaObject *parentObject, co
for (auto it = classinfo_list.cbegin(), cend = classinfo_list.cend(); it != cend; ++it)
builder.addClassInfo(it.key(), it.value());
- // add each method. Signals must be added before other methods, to match moc.
- addMetaMethod(builder, &QMetaObjectBuilder::addSignal,
- "exception(int,QString,QString,QString)", "code,source,desc,help");
- addMetaMethod(builder, &QMetaObjectBuilder::addSignal,
- "propertyChanged(QString)", "name");
- addMetaMethod(builder, &QMetaObjectBuilder::addSignal,
- "signal(QString,int,void*)", "name,argc,argv");
buildMethods(signal_list, moExtra, builder, &QMetaObjectBuilder::addSignal);
buildMethods(slot_list, moExtra, builder, &QMetaObjectBuilder::addSlot);
- // each property
- addMetaProperty(builder, "control", "QString",
- Readable | Writable | Designable | Scriptable | Stored | Editable | StdCppSet);
for (auto it = property_list.cbegin(), end = property_list.cend(); it != end; ++it) {
const QByteArray &name = it.key();
const QByteArray &type = it.value().type;
@@ -3108,31 +3028,6 @@ QMetaObject *MetaObjectGenerator::metaObject(const QMetaObject *parentObject, co
return metaobj;
}
-#define QT_MOC_LITERAL(ofs, len) \
- uint(offsetof(qt_meta_stringdata_QAxBase_t, stringdata) + ofs), len
-
-const QAxBase::qt_meta_stringdata_QAxBase_t QAxBase::qt_meta_stringdata_QAxBase = {
- {
-QT_MOC_LITERAL(0, 7),
-QT_MOC_LITERAL(8, 6),
-QT_MOC_LITERAL(15, 0),
-QT_MOC_LITERAL(16, 4),
-QT_MOC_LITERAL(21, 4),
-QT_MOC_LITERAL(26, 4),
-QT_MOC_LITERAL(31, 15),
-QT_MOC_LITERAL(47, 9),
-QT_MOC_LITERAL(57, 4),
-QT_MOC_LITERAL(62, 6),
-QT_MOC_LITERAL(69, 4),
-QT_MOC_LITERAL(74, 4),
-QT_MOC_LITERAL(79, 7)
- },
- "QAxBase\0signal\0\0name\0argc\0argv\0"
- "propertyChanged\0exception\0code\0source\0"
- "desc\0help\0control\0"
-};
-#undef QT_MOC_LITERAL
-
/*!
\fn const QMetaObject *QAxBase::fallbackMetaObject() const
\internal
@@ -3140,46 +3035,12 @@ QT_MOC_LITERAL(79, 7)
/*!
\internal
- \class QAxBase::qt_meta_stringdata_QAxBase_t
-*/
-
-const uint QAxBase::qt_meta_data_QAxBase[] = {
-
- // content:
- 7, // revision
- 0, // classname
- 0, 0, // classinfo
- 3, 14, // methods
- 1, 48, // properties
- 0, 0, // enums/sets
- 0, 0, // constructors
- 0, // flags
- 3, // signalCount
-
- // signals: name, argc, parameters, tag, flags
- 1, 3, 29, 2, 0x05,
- 6, 1, 36, 2, 0x05,
- 7, 4, 39, 2, 0x05,
-
- // signals: parameters
- QMetaType::Void, QMetaType::QString, QMetaType::Int, QMetaType::VoidStar, 3, 4, 5,
- QMetaType::Void, QMetaType::QString, 3,
- QMetaType::Void, QMetaType::Int, QMetaType::QString, QMetaType::QString, QMetaType::QString, 8, 9, 10, 11,
-
- // properties: name, type, flags
- 12, QMetaType::QString, 0x00095000,
-
- 0 // eod
-};
-
-/*!
- \internal
The metaobject is generated on the fly from the information
provided by the IDispatch and ITypeInfo interface implementations
in the COM object.
*/
-const QMetaObject *QAxBase::metaObject() const
+const QMetaObject *QAxBase::axBaseMetaObject() const
{
if (d->metaobj)
return d->metaobj;
@@ -3324,8 +3185,6 @@ void QAxBase::connectNotify()
void QAxBasePrivate::handleException(tagEXCEPINFO *exc, const QString &name)
{
- const QMetaObject *mo = metaObject();
- const int exceptionSignal = mo->indexOfSignal("exception(int,QString,QString,QString)");
if (exc->pfnDeferredFillIn)
exc->pfnDeferredFillIn(exc);
int code = exc->wCode ? exc->wCode : exc->scode;
@@ -3336,11 +3195,8 @@ void QAxBasePrivate::handleException(tagEXCEPINFO *exc, const QString &name)
if (helpContext && !help.isEmpty())
help += QString::fromLatin1(" [%1]").arg(helpContext);
- if (QAxEventSink::signalHasReceivers(q->qObject(), "exception(int,QString,QString,QString)")) {
- void *argv[] = {nullptr, &code, &source, &desc, &help};
- QAxBase::qt_static_metacall(q, QMetaObject::InvokeMetaMethod,
- exceptionSignal - mo->methodOffset(), argv);
- } else {
+ signalBridge->emitException(code, source, desc, help);
+ if (!QAxEventSink::signalHasReceivers(q->qObject(), "exception(int,QString,QString,QString)")) {
qWarning(R"(QAxBase: Error calling IDispatch member %s: Exception thrown by server
Code : %d
Source : %s
@@ -3412,28 +3268,10 @@ bool QAxBasePrivate::checkHRESULT(HRESULT hres, EXCEPINFO *exc, const QString &n
*/
int QAxBase::internalProperty(QMetaObject::Call call, int index, void **v)
{
- const QMetaObject *mo = metaObject();
+ const QMetaObject *mo = axBaseMetaObject();
const QMetaProperty prop = mo->property(index + mo->propertyOffset());
QByteArray propname = prop.name();
- // hardcoded control property
- if (propname == "control") {
- switch(call) {
- case QMetaObject::ReadProperty:
- *static_cast<QString*>(*v) = control();
- break;
- case QMetaObject::WriteProperty:
- setControl(*static_cast<const QString*>(*v));
- break;
- case QMetaObject::ResetProperty:
- clear();
- break;
- default:
- break;
- }
- return index - mo->propertyCount();
- }
-
// get the IDispatch
if (!d->ptr || !prop.isValid())
return index;
@@ -3534,7 +3372,7 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v)
if (!disp)
return index;
- const QMetaObject *mo = metaObject();
+ const QMetaObject *mo = axBaseMetaObject();
// get the slot information
const QMetaMethod slot = mo->method(index + mo->methodOffset());
Q_ASSERT(slot.methodType() == QMetaMethod::Slot);
@@ -3650,12 +3488,12 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v)
/*!
\internal
*/
-int QAxBase::qt_static_metacall(QAxBase *_t, QMetaObject::Call _c, int _id, void **_a)
+int QAxBase::axBase_qt_static_metacall(QAxBase *_t, QMetaObject::Call _c, int _id, void **_a)
{
if (_c != QMetaObject::InvokeMetaMethod)
return 0;
Q_ASSERT(_t != nullptr);
- const QMetaObject *mo = _t->metaObject();
+ const QMetaObject *mo = _t->axBaseMetaObject();
switch (mo->method(_id + mo->methodOffset()).methodType()) {
case QMetaMethod::Signal:
QMetaObject::activate(_t->qObject(), mo, _id, _a);
@@ -3672,9 +3510,9 @@ int QAxBase::qt_static_metacall(QAxBase *_t, QMetaObject::Call _c, int _id, void
/*!
\internal
*/
-int QAxBase::qt_metacall(QMetaObject::Call call, int id, void **v)
+int QAxBase::axBase_qt_metacall(QMetaObject::Call call, int id, void **v)
{
- const QMetaObject *mo = metaObject();
+ const QMetaObject *mo = axBaseMetaObject();
if (isNull() && mo->property(id + mo->propertyOffset()).name() != QByteArray("control")) {
qWarning("QAxBase::qt_metacall: Object is not initialized, or initialization failed");
return id;
@@ -3682,7 +3520,7 @@ int QAxBase::qt_metacall(QMetaObject::Call call, int id, void **v)
switch(call) {
case QMetaObject::InvokeMetaMethod:
- id = qt_static_metacall(this, call, id, v);
+ id = axBase_qt_static_metacall(this, call, id, v);
break;
case QMetaObject::ReadProperty:
case QMetaObject::WriteProperty:
@@ -3706,7 +3544,7 @@ int QAxBase::qt_metacall(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->metaObject();
+ const QMetaObject *metaObject = that->axBaseMetaObject();
const char *coclass = metaObject->classInfo(metaObject->indexOfClassInfo("CoClass")).value();
if (disptype == DISPATCH_METHOD) {
@@ -3754,8 +3592,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> &
return false;
}
- const QMetaObject *mo = metaObject();
- d->metaObject();
+ const QMetaObject *mo = axBaseMetaObject();
Q_ASSERT(d->metaobj);
const QMetaObjectExtra &moExtra = moextra_cache.value(d->metaobj);
@@ -4192,7 +4029,7 @@ QAxObject *QAxBase::querySubObject(const char *name, QList<QVariant> &vars)
case VT_EMPTY:
#ifdef QT_CHECK_STATE
{
- auto mo = metaObject();
+ auto mo = axBaseMetaObject();
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");
@@ -4202,7 +4039,7 @@ QAxObject *QAxBase::querySubObject(const char *name, QList<QVariant> &vars)
default:
#ifdef QT_CHECK_STATE
{
- auto mo = metaObject();
+ auto mo = axBaseMetaObject();
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");
@@ -4309,7 +4146,7 @@ QAxBase::PropertyBag QAxBase::propertyBag() const
persist->Release();
return result;
}
- const QMetaObject *mo = metaObject();
+ const QMetaObject *mo = axBaseMetaObject();
for (int p = mo->propertyOffset(); p < mo->propertyCount(); ++p) {
const QMetaProperty property = mo->property(p);
QVariant var = qObject()->property(property.name());
@@ -4349,7 +4186,7 @@ void QAxBase::setPropertyBag(const PropertyBag &bag)
pbag->Release();
persist->Release();
} else {
- const QMetaObject *mo = metaObject();
+ const QMetaObject *mo = axBaseMetaObject();
for (int p = mo->propertyOffset(); p < mo->propertyCount(); ++p) {
const QMetaProperty property = mo->property(p);
QVariant var = bag.value(QLatin1String(property.name()));
@@ -4366,7 +4203,7 @@ void QAxBase::setPropertyBag(const PropertyBag &bag)
Depending on the control implementation this setting might be
ignored for some properties.
- \sa setPropertyWritable(), propertyChanged()
+ \sa setPropertyWritable(), QAxBaseWidget::propertyChanged(), QAxBaseObject::propertyChanged()
*/
bool QAxBase::propertyWritable(const char *prop) const
{
@@ -4382,7 +4219,7 @@ bool QAxBase::propertyWritable(const char *prop) const
Depending on the control implementation this setting might be
ignored for some properties.
- \sa propertyWritable(), propertyChanged()
+ \sa propertyWritable(), QAxBaseWidget::propertyChanged(), QAxBaseObject::propertyChanged()
*/
void QAxBase::setPropertyWritable(const char *prop, bool ok)
{
@@ -4393,7 +4230,7 @@ void QAxBase::setPropertyWritable(const char *prop, bool ok)
Returns true if there is no COM object loaded by this wrapper;
otherwise return false.
- \sa control
+ \sa control()
*/
bool QAxBase::isNull() const
{
@@ -4450,38 +4287,6 @@ void *qax_createObjectWrapper(int metaType, IUnknown *iface)
}
/*!
- \fn void QAxBase::signal(const QString &name, int argc, void *argv)
-
- This generic signal gets emitted when the COM object issues the
- event \a name. \a argc is the number of parameters provided by the
- event (DISPPARAMS.cArgs), and \a argv is the pointer to the
- parameter values (DISPPARAMS.rgvarg). Note that the order of parameter
- values is turned around, ie. the last element of the array is the first
- parameter in the function.
-
- \snippet src_activeqt_container_qaxbase.cpp 20
-
- Use this signal if the event has parameters of unsupported data
- types. Otherwise, connect directly to the signal \a name.
-*/
-
-/*!
- \fn void QAxBase::propertyChanged(const QString &name)
-
- If the COM object supports property notification, this signal gets
- emitted when the property called \a name is changed.
-*/
-
-/*!
- \fn void QAxBase::exception(int code, const QString &source, const QString &desc, const QString &help)
-
- This signal is emitted when the COM object throws an exception while called using the OLE automation
- interface IDispatch. \a code, \a source, \a desc and \a help provide information about the exception as
- provided by the COM server and can be used to provide useful feedback to the end user. \a help includes
- the help file, and the help context ID in brackets, e.g. "filename [id]".
-*/
-
-/*!
\fn QObject *QAxBase::qObject() const
\internal
*/
diff --git a/src/activeqt/container/qaxbase.h b/src/activeqt/container/qaxbase.h
index 049ee57..498e9ee 100644
--- a/src/activeqt/container/qaxbase.h
+++ b/src/activeqt/container/qaxbase.h
@@ -65,11 +65,10 @@ class QUuid;
class QAxEventSink;
class QAxObject;
class QAxBasePrivate;
+class QAxBasePrivateSignalBridge;
class QAxBase
{
- QDOC_PROPERTY(QString control READ control WRITE setControl)
-
public:
using PropertyBag = QMap<QString, QVariant>;
@@ -99,9 +98,9 @@ public:
const QVariant &v8 = QVariant());
QAxObject* querySubObject(const char *name, QList<QVariant> &vars);
- virtual const QMetaObject *metaObject() const;
- virtual int qt_metacall(QMetaObject::Call, int, void **);
- static int qt_static_metacall(QAxBase *, QMetaObject::Call, int, void **);
+ const QMetaObject *axBaseMetaObject() const;
+ int axBase_qt_metacall(QMetaObject::Call, int, void **);
+ static int axBase_qt_static_metacall(QAxBase *, QMetaObject::Call, int, void **);
virtual QObject *qObject() const = 0;
virtual const char *className() const = 0;
@@ -120,23 +119,16 @@ public:
QVariant asVariant() const;
-#ifdef Q_QDOC
-Q_SIGNALS:
- void signal(const QString&,int,void*);
- void propertyChanged(const QString&);
- void exception(int,const QString&,const QString&,const QString&);
-#endif
-
public:
- virtual void clear();
+ void clear();
bool setControl(const QString&);
void disableMetaObject();
void disableClassInfo();
void disableEventSink();
- unsigned long classContext() const;
- void setClassContext(unsigned long classContext);
+ ulong classContext() const;
+ void setClassContext(ulong classContext);
protected:
virtual bool initialize(IUnknown** ptr);
@@ -156,13 +148,7 @@ protected:
const QVariant &var7, const QVariant &var8);
virtual const QMetaObject *fallbackMetaObject() const = 0;
-
- struct qt_meta_stringdata_QAxBase_t {
- const uint offsetsAndSize[26];
- char stringdata[88];
- };
- static const qt_meta_stringdata_QAxBase_t qt_meta_stringdata_QAxBase;
- static const uint qt_meta_data_QAxBase[];
+ void axBaseInit(QAxBasePrivateSignalBridge *b);
private:
enum DynamicCallHelperFlags {
diff --git a/src/activeqt/container/qaxbase_p.h b/src/activeqt/container/qaxbase_p.h
index fc347b7..d9c49cb 100644
--- a/src/activeqt/container/qaxbase_p.h
+++ b/src/activeqt/container/qaxbase_p.h
@@ -76,6 +76,17 @@ QT_BEGIN_NAMESPACE
class QAxBase;
class QAxEventSink;
+class QAxBasePrivateSignalBridge
+{
+public:
+ virtual ~QAxBasePrivateSignalBridge() = default;
+
+ virtual void emitException(int code, const QString &source, const QString &desc,
+ const QString &help) = 0;
+ virtual void emitPropertyChanged(const QString &name) = 0;
+ virtual void emitSignal(const QString &name, int argc, void *argv) = 0;
+};
+
class QAxBasePrivate
{
Q_DISABLE_COPY_MOVE(QAxBasePrivate)
@@ -124,6 +135,7 @@ public:
mutable QMap<QString, LONG> verbs;
QMetaObject *metaobj = nullptr;
+ QAxBasePrivateSignalBridge *signalBridge = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/activeqt/container/qaxdump.cpp b/src/activeqt/container/qaxdump.cpp
index 5adbb6a..98be9b6 100644
--- a/src/activeqt/container/qaxdump.cpp
+++ b/src/activeqt/container/qaxdump.cpp
@@ -139,7 +139,7 @@ static QByteArray toType(const QByteArray &t)
QString qax_generateDocumentation(QAxBase *that)
{
- that->metaObject();
+ that->axBaseMetaObject();
if (that->isNull())
return QString();
@@ -153,7 +153,7 @@ QString qax_generateDocumentation(QAxBase *that)
QString docu;
QTextStream stream(&docu, QIODevice::WriteOnly);
- const QMetaObject *mo = that->metaObject();
+ const QMetaObject *mo = that->axBaseMetaObject();
QString coClass = QLatin1String(mo->classInfo(mo->indexOfClassInfo("CoClass")).value());
stream << "<h1 align=center>" << coClass << " Reference</h1>" << Qt::endl;
diff --git a/src/activeqt/container/qaxobject.cpp b/src/activeqt/container/qaxobject.cpp
index 8f309b3..317f83b 100644
--- a/src/activeqt/container/qaxobject.cpp
+++ b/src/activeqt/container/qaxobject.cpp
@@ -49,6 +49,7 @@
****************************************************************************/
#include "qaxobject.h"
+#include "qaxbase_p.h"
#include <quuid.h>
#include <qmetaobject.h>
@@ -58,6 +59,97 @@
QT_BEGIN_NAMESPACE
+class QAxObjectSignalBridge : public QAxBasePrivateSignalBridge
+{
+public:
+ explicit QAxObjectSignalBridge(QAxBaseObject *o) : m_o(o) {}
+
+ void emitException(int code, const QString &source, const QString &desc,
+ const QString &help) override
+ {
+ emit m_o->exception(code, source, desc, help);
+ }
+
+ void emitPropertyChanged(const QString &name) override
+ {
+ emit m_o->propertyChanged(name);
+ }
+
+ void emitSignal(const QString &name, int argc, void *argv) override
+ {
+ emit m_o->signal(name, argc, argv);
+ }
+
+private:
+ QAxBaseObject *m_o;
+};
+
+/*!
+ \class QAxBaseObject
+ \brief QAxBaseObject provides static properties and signals for QAxObject.
+ \inmodule QAxContainer
+ \since 6.0
+*/
+
+/*!
+ \property QAxBaseObject::classContext
+ \brief the context the ActiveX control will run in (default CLSCTX_SERVER).
+
+ The property affects the "dwClsContext" argument when calling
+ CoCreateInstance. This can be used to control in-proc vs. out-of-proc
+ startup for controls supporting both alternatives. Also, it can be used to
+ modify/reduce control permissions when used with CLSCTX_ENABLE_CLOAKING
+ and an impersonation token.
+
+ Note that it must be set before setControl() to have any effect.
+ \sa QAxBaseWidget::control
+*/
+
+/*!
+ \property QAxBaseObject::control
+ \brief the name of the COM object wrapped by this QAxBaseObject object.
+
+ Setting this property initializes the COM object. Any COM object
+ previously set is shut down.
+
+ The most efficient way to set this property is by using the
+ registered component's UUID, e.g.
+ \sa QAxBaseWidget::control, QAxBaseWidget::classContext
+*/
+
+/*!
+ \fn void QAxBaseObject::signal(const QString &name, int argc, void *argv)
+
+ This generic signal gets emitted when the COM object issues the
+ event \a name. \a argc is the number of parameters provided by the
+ event (DISPPARAMS.cArgs), and \a argv is the pointer to the
+ parameter values (DISPPARAMS.rgvarg). Note that the order of parameter
+ values is turned around, ie. the last element of the array is the first
+ parameter in the function.
+
+ \sa QAxBaseWidget::signal()
+*/
+
+/*!
+ \fn void QAxBaseObject::propertyChanged(const QString &name)
+
+ If the COM object supports property notification, this signal gets
+ emitted when the property called \a name is changed.
+
+ \sa QAxBaseWidget::propertyChanged()
+*/
+
+/*!
+ \fn void QAxBaseObject::exception(int code, const QString &source, const QString &desc, const QString &help)
+
+ This signal is emitted when the COM object throws an exception while called using the OLE automation
+ interface IDispatch. \a code, \a source, \a desc and \a help provide information about the exception as
+ provided by the COM server and can be used to provide useful feedback to the end user. \a help includes
+ the help file, and the help context ID in brackets, e.g. "filename [id]".
+
+ \sa QAxBaseWidget::exception()
+*/
+
/*!
\class QAxObject
\brief The QAxObject class provides a QObject that wraps a COM object.
@@ -90,19 +182,14 @@ QT_BEGIN_NAMESPACE
\sa QAxBase, QAxWidget, QAxScript, {ActiveQt Framework}
*/
-const QMetaObject QAxObject::staticMetaObject = {
- { &QObject::staticMetaObject, qt_meta_stringdata_QAxBase.offsetsAndSize,
- qt_meta_data_QAxBase, qt_static_metacall, nullptr, nullptr }
-};
-
/*!
Creates an empty COM object and propagates \a parent to the
- QObject constructor. To initialize the object, call \link
- QAxBase::setControl() setControl \endlink.
+ QObject constructor. To initialize the object, call setControl().
*/
QAxObject::QAxObject(QObject *parent)
-: QObject(parent)
+: QAxBaseObject(parent)
{
+ axBaseInit(new QAxObjectSignalBridge(this));
}
/*!
@@ -112,8 +199,9 @@ QAxObject::QAxObject(QObject *parent)
\sa setControl()
*/
QAxObject::QAxObject(const QString &c, QObject *parent)
-: QObject(parent)
+: QAxBaseObject(parent)
{
+ axBaseInit(new QAxObjectSignalBridge(this));
setControl(c);
}
@@ -122,8 +210,9 @@ QAxObject::QAxObject(const QString &c, QObject *parent)
iface. \a parent is propagated to the QObject constructor.
*/
QAxObject::QAxObject(IUnknown *iface, QObject *parent)
-: QObject(parent), QAxBase(iface)
+: QAxBaseObject(parent), QAxBase(iface)
{
+ axBaseInit(new QAxObjectSignalBridge(this));
}
/*!
@@ -135,12 +224,37 @@ QAxObject::~QAxObject()
clear();
}
+unsigned long QAxObject::classContext() const
+{
+ return QAxBase::classContext();
+}
+
+void QAxObject::setClassContext(ulong classContext)
+{
+ QAxBase::setClassContext(classContext);
+}
+
+QString QAxObject::control() const
+{
+ return QAxBase::control();
+}
+
+bool QAxObject::setControl(const QString &c)
+{
+ return QAxBase::setControl(c);
+}
+
+void QAxObject::clear()
+{
+ QAxBase::clear();
+}
+
/*!
\internal
*/
void QAxObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
- QAxBase::qt_static_metacall(qobject_cast<QAxObject*>(_o), _c, _id, _a);
+ QAxBase::axBase_qt_static_metacall(static_cast<QAxObject *>(_o), _c, _id, _a);
}
/*!
@@ -156,7 +270,7 @@ const QMetaObject *QAxObject::fallbackMetaObject() const
*/
const QMetaObject *QAxObject::metaObject() const
{
- return QAxBase::metaObject();
+ return QAxBase::axBaseMetaObject();
}
/*!
@@ -164,7 +278,7 @@ const QMetaObject *QAxObject::metaObject() const
*/
const QMetaObject *QAxObject::parentMetaObject() const
{
- return &QObject::staticMetaObject;
+ return &QAxBaseObject::staticMetaObject;
}
/*!
@@ -174,7 +288,7 @@ void *QAxObject::qt_metacast(const char *cname)
{
if (!qstrcmp(cname, "QAxObject")) return static_cast<void *>(this);
if (!qstrcmp(cname, "QAxBase")) return static_cast<QAxBase *>(this);
- return QObject::qt_metacast(cname);
+ return QAxBaseObject::qt_metacast(cname);
}
/*!
@@ -190,10 +304,10 @@ const char *QAxObject::className() const
*/
int QAxObject::qt_metacall(QMetaObject::Call call, int id, void **v)
{
- id = QObject::qt_metacall(call, id, v);
+ id = QAxBaseObject::qt_metacall(call, id, v);
if (id < 0)
return id;
- return QAxBase::qt_metacall(call, id, v);
+ return QAxBase::axBase_qt_metacall(call, id, v);
}
/*!
diff --git a/src/activeqt/container/qaxobject.h b/src/activeqt/container/qaxobject.h
index 049747c..56275c0 100644
--- a/src/activeqt/container/qaxobject.h
+++ b/src/activeqt/container/qaxobject.h
@@ -52,13 +52,30 @@
#define QAXOBJECT_H
#include <QtAxContainer/qaxbase.h>
+#include <QtAxContainer/qaxobjectinterface.h>
QT_BEGIN_NAMESPACE
-class QAxObject : public QObject, public QAxBase
+class QAxBaseObject : public QObject, public QAxObjectInterface
+{
+ Q_OBJECT
+ Q_PROPERTY(ulong classContext READ classContext WRITE setClassContext)
+ Q_PROPERTY(QString control READ control WRITE setControl RESET clear)
+
+protected:
+ using QObject::QObject;
+
+public:
+
+Q_SIGNALS:
+ void exception(int code, const QString &source, const QString &desc, const QString &help);
+ void propertyChanged(const QString &name);
+ void signal(const QString &name, int argc, void *argv);
+};
+
+class QAxObject : public QAxBaseObject, public QAxBase
{
friend class QAxEventSink;
- Q_OBJECT_FAKE
public:
QObject* qObject() const override { return static_cast<QObject *>(const_cast<QAxObject *>(this)); }
const char *className() const override;
@@ -68,8 +85,20 @@ public:
explicit QAxObject(IUnknown *iface, QObject *parent = nullptr);
~QAxObject() override;
+ ulong classContext() const override;
+ void setClassContext(ulong classContext) override;
+
+ QString control() const override;
+ bool setControl(const QString &c) override;
+ void clear() override;
+
bool doVerb(const QString &verb);
+ const QMetaObject *metaObject() const override;
+ int qt_metacall(QMetaObject::Call call, int id, void **v) override;
+ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a);
+ void *qt_metacast(const char *) override;
+
protected:
void connectNotify(const QMetaMethod &signal) override;
const QMetaObject *fallbackMetaObject() const override;
diff --git a/src/activeqt/container/qaxobjectinterface.h b/src/activeqt/container/qaxobjectinterface.h
new file mode 100644
index 0000000..d6e7239
--- /dev/null
+++ b/src/activeqt/container/qaxobjectinterface.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QAXOBJECTINTERFACE_H
+#define QAXOBJECTINTERFACE_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+
+class QAxObjectInterface
+{
+public:
+ virtual ~QAxObjectInterface() = default;
+
+ virtual ulong classContext() const = 0;
+ virtual void setClassContext(ulong classContext) = 0;
+
+ virtual QString control() const = 0;
+ virtual void clear() = 0;
+ virtual bool setControl(const QString &c) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QAXOBJECTINTERFACE_H
diff --git a/src/activeqt/container/qaxobjectinterface.qdoc b/src/activeqt/container/qaxobjectinterface.qdoc
new file mode 100644
index 0000000..f9b2004
--- /dev/null
+++ b/src/activeqt/container/qaxobjectinterface.qdoc
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+/*!
+ \class QAxObjectInterface
+ \brief QAxObjectInterface is an interface providing common properties of QAxObject and QAxWidget.
+ \inmodule QAxContainer
+ \since 6.0
+*/
+
+/*!
+ \fn QAxObjectInterface::~QAxObjectInterface()
+
+ Destroys the QAxObjectInterface.
+*/
+
+/*!
+ \fn virtual ulong QAxObjectInterface::classContext() const
+
+ \return the context the ActiveX control will run in (default CLSCTX_SERVER).
+
+ \sa QAxBaseWidget::classContext, QAxBaseObject::classContext
+*/
+
+/*!
+ \fn virtual void QAxObjectInterface::setClassContext(ulong classContext)
+
+ Sets the context the ActiveX control will run in to \a classContext
+
+ Affects the "dwClsContext" argument when calling CoCreateInstance.
+ This can be used to control in-proc vs. out-of-proc startup for controls
+ supporting both alternatives. Also, it can be used to modify/reduce control
+ permissions when used with CLSCTX_ENABLE_CLOAKING and an impersonation token.
+
+ Note that this function must be called before setControl() to have any
+ effect.
+
+ \sa QAxBaseWidget::classContext, QAxBaseObject::classContext
+*/
+
+/*!
+ \fn virtual QString QAxObjectInterface::control() const
+
+ \return the name of the COM object wrapped by this QAxBase object.
+
+ \sa QAxBaseWidget::control, QAxBaseObject::control
+*/
+
+/*!
+ \fn virtual bool QAxObjectInterface::setControl(const QString &c)
+
+ \return whether setting the COM object succeeded.
+
+ Sets the name of the COM object wrapped by this QAxBase object to \a c.
+
+ \sa QAxBaseWidget::control, QAxBaseObject::control
+*/
+
+/*!
+ \fn virtual void QAxObjectInterface::clear()
+
+ Disconnects and destroys the COM object.
+
+ \sa QAxBaseWidget::control, QAxBaseObject::control
+*/
diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp
index abc9948..4e2ca46 100644
--- a/src/activeqt/container/qaxwidget.cpp
+++ b/src/activeqt/container/qaxwidget.cpp
@@ -49,6 +49,7 @@
****************************************************************************/
#include "qaxwidget.h"
+#include "qaxbase_p.h"
#include <QtAxBase/private/qaxutils_p.h>
#include <QtAxBase/private/qaxtypefunctions_p.h>
@@ -109,6 +110,31 @@
QT_BEGIN_NAMESPACE
+class QAxWidgetSignalBridge : public QAxBasePrivateSignalBridge
+{
+public:
+ explicit QAxWidgetSignalBridge(QAxBaseWidget *w) : m_w(w) {}
+
+ void emitException(int code, const QString &source, const QString &desc,
+ const QString &help) override
+ {
+ emit m_w->exception(code, source, desc, help);
+ }
+
+ void emitPropertyChanged(const QString &name) override
+ {
+ emit m_w->propertyChanged(name);
+ }
+
+ void emitSignal(const QString &name, int argc, void *argv) override
+ {
+ emit m_w->signal(name, argc, argv);
+ }
+
+private:
+ QAxBaseWidget *m_w;
+};
+
/* \class QAxHostWidget
\brief The QAxHostWidget class is the actual container widget.
@@ -1873,6 +1899,120 @@ void QAxHostWidget::paintEvent(QPaintEvent*)
}
/*!
+ \class QAxBaseWidget
+ \brief QAxBaseWidget provides static properties and signals for QAxWidget.
+ \inmodule QAxContainer
+ \since 6.0
+*/
+
+/*!
+ \property QAxBaseWidget::classContext
+ \brief the context the ActiveX control will run in (default CLSCTX_SERVER).
+
+ The property affects the "dwClsContext" argument when calling
+ CoCreateInstance. This can be used to control in-proc vs. out-of-proc
+ startup for controls supporting both alternatives. Also, it can be used to
+ modify/reduce control permissions when used with CLSCTX_ENABLE_CLOAKING
+ and an impersonation token.
+
+ Note that it must be set before setControl() to have any effect.
+ \sa control
+*/
+
+/*!
+ \property QAxBaseWidget::control
+ \brief the name of the COM object wrapped by this QAxBaseWidget object.
+
+ Setting this property initializes the COM object. Any COM object
+ previously set is shut down.
+
+ The most efficient way to set this property is by using the
+ registered component's UUID, e.g.
+
+ \snippet src_activeqt_container_qaxbase.cpp 7
+
+ The second fastest way is to use the registered control's class
+ name (with or without version number), e.g.
+
+ \snippet src_activeqt_container_qaxbase.cpp 8
+
+ The slowest, but easiest way to use is to use the control's full
+ name, e.g.
+
+ \snippet src_activeqt_container_qaxbase.cpp 9
+
+ It is also possible to initialize the object from a file, e.g.
+
+ \snippet src_activeqt_container_qaxbase.cpp 10
+
+ If the component's UUID is used the following patterns can be used
+ to initialize the control on a remote machine, to initialize a
+ licensed control or to connect to a running object:
+ \list
+ \li To initialize the control on a different machine use the following
+ pattern:
+
+ \snippet src_activeqt_container_qaxbase.cpp 11
+
+ \li To initialize a licensed control use the following pattern:
+
+ \snippet src_activeqt_container_qaxbase.cpp 12
+
+ \li To connect to an already running object use the following pattern:
+
+ \snippet src_activeqt_container_qaxbase.cpp 13
+
+ \endlist
+ The first two patterns can be combined, e.g. to initialize a licensed
+ control on a remote machine:
+
+ \snippet src_activeqt_container_qaxbase.cpp 14
+
+ The control's read function always returns the control's UUID, if provided including the license
+ key, and the name of the server, but not including the username, the domain or the password.
+
+ \sa classContext
+*/
+
+/*!
+ \fn void QAxBaseWidget::signal(const QString &name, int argc, void *argv)
+
+ This generic signal gets emitted when the COM object issues the
+ event \a name. \a argc is the number of parameters provided by the
+ event (DISPPARAMS.cArgs), and \a argv is the pointer to the
+ parameter values (DISPPARAMS.rgvarg). Note that the order of parameter
+ values is turned around, ie. the last element of the array is the first
+ parameter in the function.
+
+ \snippet src_activeqt_container_qaxbase.cpp 20
+
+ Use this signal if the event has parameters of unsupported data
+ types. Otherwise, connect directly to the signal \a name.
+
+ \sa QAxBaseObject::signal()
+*/
+
+/*!
+ \fn void QAxBaseWidget::propertyChanged(const QString &name)
+
+ If the COM object supports property notification, this signal gets
+ emitted when the property called \a name is changed.
+
+ \sa QAxBaseObject::propertyChanged()
+*/
+
+/*!
+ \fn void QAxBaseWidget::exception(int code, const QString &source, const QString &desc, const QString &help)
+
+ This signal is emitted when the COM object throws an exception while called using the OLE automation
+ interface IDispatch. \a code, \a source, \a desc and \a help provide information about the exception as
+ provided by the COM server and can be used to provide useful feedback to the end user. \a help includes
+ the help file, and the help context ID in brackets, e.g. "filename [id]".
+
+ \sa QAxBaseObject::exception()
+*/
+
+/*!
\class QAxWidget
\brief The QAxWidget class is a QWidget that wraps an ActiveX control.
@@ -1914,19 +2054,15 @@ void QAxHostWidget::paintEvent(QPaintEvent*)
\sa QAxBase, QAxObject, QAxScript, {ActiveQt Framework}
*/
-const QMetaObject QAxWidget::staticMetaObject = {
- { &QWidget::staticMetaObject, qt_meta_stringdata_QAxBase.offsetsAndSize,
- qt_meta_data_QAxBase, qt_static_metacall, nullptr, nullptr }
-};
-
/*!
Creates an empty QAxWidget widget and propagates \a parent
and \a f to the QWidget constructor. To initialize a control,
call setControl().
*/
QAxWidget::QAxWidget(QWidget *parent, Qt::WindowFlags f)
-: QWidget(parent, f)
+: QAxBaseWidget(parent, f)
{
+ axBaseInit(new QAxWidgetSignalBridge(this));
}
/*!
@@ -1936,8 +2072,9 @@ QAxWidget::QAxWidget(QWidget *parent, Qt::WindowFlags f)
\sa setControl()
*/
QAxWidget::QAxWidget(const QString &c, QWidget *parent, Qt::WindowFlags f)
-: QWidget(parent, f)
+: QAxBaseWidget(parent, f)
{
+ axBaseInit(new QAxWidgetSignalBridge(this));
setControl(c);
}
@@ -1946,8 +2083,9 @@ QAxWidget::QAxWidget(const QString &c, QWidget *parent, Qt::WindowFlags f)
\a parent and \a f are propagated to the QWidget contructor.
*/
QAxWidget::QAxWidget(IUnknown *iface, QWidget *parent, Qt::WindowFlags f)
-: QWidget(parent, f), QAxBase(iface)
+: QAxBaseWidget(parent, f), QAxBase(iface)
{
+ axBaseInit(new QAxWidgetSignalBridge(this));
}
/*!
@@ -2043,6 +2181,26 @@ QAxAggregated *QAxWidget::createAggregate()
return nullptr;
}
+ulong QAxWidget::classContext() const
+{
+ return QAxBase::classContext();
+}
+
+void QAxWidget::setClassContext(ulong classContext)
+{
+ QAxBase::setClassContext(classContext);
+}
+
+QString QAxWidget::control() const
+{
+ return QAxBase::control();
+}
+
+bool QAxWidget::setControl(const QString &c)
+{
+ return QAxBase::setControl(c);
+}
+
/*!
\reimp
@@ -2052,7 +2210,7 @@ void QAxWidget::clear()
{
if (isNull())
return;
- if (!control().isEmpty()) {
+ if (!QAxBase::control().isEmpty()) {
ATOM filter_ref = FindAtom(qaxatom);
if (filter_ref)
DeleteAtom(filter_ref);
@@ -2102,7 +2260,7 @@ bool QAxWidget::doVerb(const QString &verb)
*/
void QAxWidget::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
- QAxBase::qt_static_metacall(qobject_cast<QAxWidget*>(_o), _c, _id, _a);
+ QAxBase::axBase_qt_static_metacall(static_cast<QAxWidget *>(_o), _c, _id, _a);
}
/*!
@@ -2118,7 +2276,7 @@ const QMetaObject *QAxWidget::fallbackMetaObject() const
*/
const QMetaObject *QAxWidget::metaObject() const
{
- return QAxBase::metaObject();
+ return QAxBase::axBaseMetaObject();
}
/*!
@@ -2126,7 +2284,7 @@ const QMetaObject *QAxWidget::metaObject() const
*/
const QMetaObject *QAxWidget::parentMetaObject() const
{
- return &QWidget::staticMetaObject;
+ return &QAxBaseWidget::staticMetaObject;
}
/*!
@@ -2136,7 +2294,7 @@ void *QAxWidget::qt_metacast(const char *cname)
{
if (!qstrcmp(cname, "QAxWidget")) return static_cast<void *>(this);
if (!qstrcmp(cname, "QAxBase")) return static_cast<QAxBase *>(this);
- return QWidget::qt_metacast(cname);
+ return QAxBaseWidget::qt_metacast(cname);
}
/*!
@@ -2152,10 +2310,10 @@ const char *QAxWidget::className() const
*/
int QAxWidget::qt_metacall(QMetaObject::Call call, int id, void **v)
{
- id = QWidget::qt_metacall(call, id, v);
+ id = QAxBaseWidget::qt_metacall(call, id, v);
if (id < 0)
return id;
- return QAxBase::qt_metacall(call, id, v);
+ return QAxBase::axBase_qt_metacall(call, id, v);
}
/*!
diff --git a/src/activeqt/container/qaxwidget.h b/src/activeqt/container/qaxwidget.h
index 2bcf3c7..a161246 100644
--- a/src/activeqt/container/qaxwidget.h
+++ b/src/activeqt/container/qaxwidget.h
@@ -52,6 +52,7 @@
#define QAXWIDGET_H
#include <QtAxContainer/qaxbase.h>
+#include <QtAxContainer/qaxobjectinterface.h>
#include <QtWidgets/qwidget.h>
QT_BEGIN_NAMESPACE
@@ -62,9 +63,24 @@ class QAxAggregated;
class QAxClientSite;
class QAxWidgetPrivate;
-class QAxWidget : public QWidget, public QAxBase
+class QAxBaseWidget : public QWidget, public QAxObjectInterface
+{
+ Q_OBJECT
+ Q_PROPERTY(ulong classContext READ classContext WRITE setClassContext)
+ Q_PROPERTY(QString control READ control WRITE setControl RESET clear)
+protected:
+ using QWidget::QWidget;
+
+public:
+
+Q_SIGNALS:
+ void exception(int code, const QString &source, const QString &desc, const QString &help);
+ void propertyChanged(const QString &name);
+ void signal(const QString &name, int argc, void *argv);
+};
+
+class QAxWidget : public QAxBaseWidget, public QAxBase
{
- Q_OBJECT_FAKE
public:
QObject* qObject() const override { return const_cast<QAxWidget *>(this); }
const char *className() const override;
@@ -74,6 +90,11 @@ public:
explicit QAxWidget(IUnknown *iface, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
~QAxWidget() override;
+ ulong classContext() const override;
+ void setClassContext(ulong classContext) override;
+
+ QString control() const override;
+ bool setControl(const QString &) override;
void clear() override;
bool doVerb(const QString &verb);
@@ -82,6 +103,11 @@ public:
virtual QAxAggregated *createAggregate();
+ const QMetaObject *metaObject() const override;
+ int qt_metacall(QMetaObject::Call call, int id, void **v) override;
+ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a);
+ void *qt_metacast(const char *) override;
+
protected:
bool initialize(IUnknown **) override;
virtual bool createHostWindow(bool);
diff --git a/tools/dumpcpp/main.cpp b/tools/dumpcpp/main.cpp
index d50c65d..baabdb4 100644
--- a/tools/dumpcpp/main.cpp
+++ b/tools/dumpcpp/main.cpp
@@ -272,7 +272,7 @@ void generateClassDecl(QTextStream &out, const QMetaObject *mo,
continue;
QByteArray propertyName(property.name());
- if (propertyName == "control" || propertyName == className)
+ if (propertyName == className)
continue;
if (!(category & OnlyInlines)) {
diff --git a/tools/testcon/invokemethod.cpp b/tools/testcon/invokemethod.cpp
index 32021ea..1651537 100644
--- a/tools/testcon/invokemethod.cpp
+++ b/tools/testcon/invokemethod.cpp
@@ -68,7 +68,7 @@ void InvokeMethod::setControl(QAxBase *ax)
return;
}
- const QMetaObject *mo = activex->metaObject();
+ const QMetaObject *mo = activex->axBaseMetaObject();
if (mo->methodCount()) {
for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
const QMetaMethod method = mo->method(i);
@@ -113,7 +113,7 @@ void InvokeMethod::on_comboMethods_textActivated(const QString &method)
return;
listParameters->clear();
- const QMetaObject *mo = activex->metaObject();
+ const QMetaObject *mo = activex->axBaseMetaObject();
const QMetaMethod slot = mo->method(mo->indexOfSlot(method.toLatin1()));
QString signature = QString::fromLatin1(slot.methodSignature());
signature.remove(0, signature.indexOf(QLatin1Char('(')) + 1);
diff --git a/tools/testcon/mainwindow.cpp b/tools/testcon/mainwindow.cpp
index 7bcc483..00a33a4 100644
--- a/tools/testcon/mainwindow.cpp
+++ b/tools/testcon/mainwindow.cpp
@@ -549,17 +549,15 @@ void MainWindow::updateGUI()
const auto axw = axWidgets();
for (QAxWidget *container : axw) {
- container->disconnect(SIGNAL(signal(QString,int,void*)));
+ disconnect(container, &QAxWidget::signal, this, nullptr);
if (actionLogSignals->isChecked())
- connect(container, SIGNAL(signal(QString,int,void*)), this, SLOT(logSignal(QString,int,void*)));
+ connect(container, &QAxWidget::signal, this, &MainWindow::logSignal);
+ disconnect(container, &QAxWidget::exception, this, nullptr);
+ connect(container, &QAxWidget::exception, this, &MainWindow::logException);
- container->disconnect(SIGNAL(exception(int,QString,QString,QString)));
- connect(container, SIGNAL(exception(int,QString,QString,QString)),
- this, SLOT(logException(int,QString,QString,QString)));
-
- container->disconnect(SIGNAL(propertyChanged(QString)));
+ disconnect(container, &QAxWidget::propertyChanged, this, nullptr);
if (actionLogProperties->isChecked())
- connect(container, SIGNAL(propertyChanged(QString)), this, SLOT(logPropertyChanged(QString)));
+ connect(container, &QAxWidget::propertyChanged, this, &MainWindow::logPropertyChanged);
container->blockSignals(actionFreezeEvents->isChecked());
}
}