summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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());
}
}