summaryrefslogtreecommitdiffstats
path: root/src/activeqt/shared/qaxtypes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/activeqt/shared/qaxtypes.cpp')
-rw-r--r--src/activeqt/shared/qaxtypes.cpp411
1 files changed, 210 insertions, 201 deletions
diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp
index 40f5e0a..d9175ea 100644
--- a/src/activeqt/shared/qaxtypes.cpp
+++ b/src/activeqt/shared/qaxtypes.cpp
@@ -1,54 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 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$
-**
-****************************************************************************/
-
-#define NOMINMAX
+// Copyright (C) 2015 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <ocidl.h>
#include <olectl.h>
@@ -60,6 +11,7 @@
#include <qcursor.h>
#include <qpixmap.h>
#include <qpainter.h>
+#include <private/qpixmap_win_p.h>
#include <qobject.h>
#include <qdebug.h>
#ifdef QAX_SERVER
@@ -139,9 +91,6 @@ static QFont IFontToQFont(IFont *f)
return font;
}
-Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0);
-Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0);
-
static IPictureDisp *QPixmapToIPicture(const QPixmap &pixmap)
{
IPictureDisp *pic = nullptr;
@@ -263,26 +212,42 @@ static QByteArray msgOutParameterNotSupported(const QByteArray &type)
} \
}
+static qsizetype columnCount2D(const QVariantList &list)
+{
+ if (!list.isEmpty()) {
+ const auto &firstElement = list.at(0);
+ const auto type = firstElement.typeId();
+ if (type != QMetaType::QString && type != QMetaType::QByteArray
+ && firstElement.canConvert<QVariantList>()) {
+ return firstElement.toList().size();
+ }
+ }
+ return 0;
+}
+
bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out)
{
QVariant qvar = var;
// "type" is the expected type, so coerce if necessary
- const QVariant::Type proptype = typeName.isEmpty() ? QVariant::Invalid : QVariant::nameToType(typeName);
- if (proptype != QVariant::Invalid
- && proptype != QVariant::UserType
- && proptype != int(QMetaType::QVariant)
- && proptype != qvar.type()) {
- if (qvar.canConvert(proptype))
- qvar.convert(proptype);
+ const int proptype = typeName.isEmpty()
+ ? QMetaType::UnknownType
+ : QMetaType::fromName(typeName).id();
+ if (proptype != QMetaType::UnknownType
+ && proptype != QMetaType::User
+ && proptype != QMetaType::QVariant
+ && proptype != qvar.metaType().id()) {
+ const QMetaType metaType(proptype);
+ if (qvar.canConvert(metaType))
+ qvar.convert(metaType);
else
- qvar = QVariant(proptype);
+ qvar = QVariant(metaType);
}
if (out && arg.vt == (VT_VARIANT|VT_BYREF) && arg.pvarVal) {
return QVariantToVARIANT(var, *arg.pvarVal, typeName, false);
}
- if (out && proptype == QVariant::UserType && typeName == "QVariant") {
+ if (out && proptype == QMetaType::QVariant) {
VARIANT *pVariant = new VARIANT;
QVariantToVARIANT(var, *pVariant, QByteArray(), false);
arg.vt = VT_VARIANT|VT_BYREF;
@@ -290,8 +255,8 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
return true;
}
- switch ((int)qvar.type()) {
- case QVariant::String:
+ switch (qvar.metaType().id()) {
+ case QMetaType::QString:
if (out && arg.vt == (VT_BSTR|VT_BYREF)) {
if (*arg.pbstrVal)
SysFreeString(*arg.pbstrVal);
@@ -323,15 +288,15 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
QVARIANT_TO_VARIANT_POD(ushort, qvariant_cast<ushort>(qvar), out, VT_UI2, uiVal, puiVal)
break;
- case QVariant::Int:
+ case QMetaType::Int:
QVARIANT_TO_VARIANT_POD(long, qvar.toInt(), out, VT_I4, lVal, plVal)
break;
- case QVariant::UInt:
+ case QMetaType::UInt:
QVARIANT_TO_VARIANT_POD(uint, qvar.toUInt(), out, VT_UI4, uintVal, puintVal)
break;
- case QVariant::LongLong:
+ case QMetaType::LongLong:
if (out && arg.vt == (VT_CY|VT_BYREF)) { // VT_CY: Currency
arg.pcyVal->int64 = qvar.toLongLong();
} else {
@@ -339,7 +304,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
}
break;
- case QVariant::ULongLong:
+ case QMetaType::ULongLong:
if (out && arg.vt == (VT_CY|VT_BYREF)) { // VT_CY: Currency
arg.pcyVal->int64 = qvar.toULongLong();
} else {
@@ -347,7 +312,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
}
break;
- case QVariant::Bool:
+ case QMetaType::Bool:
QVARIANT_TO_VARIANT_POD(short, short(qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE),
out, VT_BOOL, boolVal, pboolVal)
break;
@@ -360,19 +325,19 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
QVARIANT_TO_VARIANT_POD(double, qvar.toDouble(), out, VT_R8, dblVal, pdblVal)
break;
- case QVariant::Color:
+ case QMetaType::QColor:
QVARIANT_TO_VARIANT_POD(long, QColorToOLEColor(qvariant_cast<QColor>(qvar)),
out, VT_COLOR, lVal, plVal)
break;
- case QVariant::Date:
- case QVariant::Time:
- case QVariant::DateTime: // DATE = double
+ case QMetaType::QDate:
+ case QMetaType::QTime:
+ case QMetaType::QDateTime: // DATE = double
QVARIANT_TO_VARIANT_POD(DATE, QDateTimeToDATE(qvar.toDateTime()),
out, VT_DATE, date, pdate)
break;
- case QVariant::Font:
+ case QMetaType::QFont:
if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) {
if (*arg.ppdispVal)
(*arg.ppdispVal)->Release();
@@ -387,7 +352,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
}
break;
- case QVariant::Pixmap:
+ case QMetaType::QPixmap:
if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) {
if (*arg.ppdispVal)
(*arg.ppdispVal)->Release();
@@ -402,7 +367,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
}
break;
- case QVariant::Cursor:
+ case QMetaType::QCursor:
{
#ifndef QT_NO_CURSOR
int shape = qvariant_cast<QCursor>(qvar).shape();
@@ -439,37 +404,37 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
}
break;
- case QVariant::List:
+ case QMetaType::QVariantList:
{
const auto list = qvar.toList();
- const int count = list.count();
+ const qsizetype count = list.size();
VARTYPE vt = VT_VARIANT;
- QVariant::Type listType = QVariant::Type(QMetaType::QVariant);
+ int listType = QMetaType::QVariant;
if (!typeName.isEmpty() && typeName.startsWith("QList<")) {
const QByteArray listTypeName = typeName.mid(6, typeName.length() - 7); // QList<int> -> int
- listType = QVariant::nameToType(listTypeName);
+ listType = QMetaType::fromName(listTypeName).id();
}
VARIANT variant;
void *pElement = &variant;
switch(listType) {
- case QVariant::Int:
+ case QMetaType::Int:
vt = VT_I4;
pElement = &variant.lVal;
break;
- case QVariant::Double:
+ case QMetaType::Double:
vt = VT_R8;
pElement = &variant.dblVal;
break;
- case QVariant::DateTime:
+ case QMetaType::QDateTime:
vt = VT_DATE;
pElement = &variant.date;
break;
- case QVariant::Bool:
+ case QMetaType::Bool:
vt = VT_BOOL;
pElement = &variant.boolVal;
break;
- case QVariant::LongLong:
+ case QMetaType::LongLong:
vt = VT_I8;
pElement = &variant.llVal;
break;
@@ -477,41 +442,33 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
break;
}
SAFEARRAY *array = nullptr;
- bool is2D = false;
// If the first element in the array is a list the whole list is
// treated as a 2D array. The column count is taken from the 1st element.
- if (count) {
- QVariantList col = list.at(0).toList();
- int maxColumns = col.count();
- if (maxColumns) {
- is2D = true;
- SAFEARRAYBOUND rgsabound[2] = { {0, 0}, {0, 0} };
- rgsabound[0].cElements = count;
- rgsabound[1].cElements = maxColumns;
- array = SafeArrayCreate(VT_VARIANT, 2, rgsabound);
- LONG rgIndices[2];
- for (LONG i = 0; i < count; ++i) {
- rgIndices[0] = i;
- QVariantList columns = list.at(i).toList();
- int columnCount = qMin(maxColumns, columns.count());
- for (LONG j = 0; j < columnCount; ++j) {
- const QVariant &elem = columns.at(j);
- VariantInit(&variant);
- QVariantToVARIANT(elem, variant, elem.typeName());
- rgIndices[1] = j;
- SafeArrayPutElement(array, rgIndices, pElement);
- clearVARIANT(&variant);
- }
+ if (qsizetype maxColumns = columnCount2D(list)) {
+ SAFEARRAYBOUND rgsabound[2] = { {0, 0}, {0, 0} };
+ rgsabound[0].cElements = count;
+ rgsabound[1].cElements = maxColumns;
+ array = SafeArrayCreate(VT_VARIANT, 2, rgsabound);
+ LONG rgIndices[2];
+ for (LONG i = 0; i < count; ++i) {
+ rgIndices[0] = i;
+ QVariantList columns = list.at(i).toList();
+ qsizetype columnCount = qMin(maxColumns, columns.size());
+ for (LONG j = 0; j < columnCount; ++j) {
+ const QVariant &elem = columns.at(j);
+ VariantInit(&variant);
+ QVariantToVARIANT(elem, variant, elem.typeName());
+ rgIndices[1] = j;
+ SafeArrayPutElement(array, rgIndices, pElement);
+ clearVARIANT(&variant);
}
-
}
- }
- if (!is2D) {
+ } else {
array = SafeArrayCreateVector(vt, 0, count);
for (LONG index = 0; index < count; ++index) {
QVariant elem = list.at(index);
- if (listType != QVariant::Type(QMetaType::QVariant))
- elem.convert(listType);
+ if (listType != QMetaType::QVariant)
+ elem.convert(QMetaType(listType));
VariantInit(&variant);
QVariantToVARIANT(elem, variant, elem.typeName());
SafeArrayPutElement(array, &index, pElement);
@@ -533,10 +490,10 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
}
break;
- case QVariant::StringList:
+ case QMetaType::QStringList:
{
const QStringList list = qvar.toStringList();
- const int count = list.count();
+ const qsizetype count = list.size();
SAFEARRAY *array = SafeArrayCreateVector(VT_BSTR, 0, count);
for (LONG index = 0; index < count; ++index) {
QString elem = list.at(index);
@@ -560,10 +517,10 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
}
break;
- case QVariant::ByteArray:
+ case QMetaType::QByteArray:
{
const QByteArray bytes = qvar.toByteArray();
- const uint count = bytes.count();
+ const uint count = static_cast<uint>(bytes.size());
SAFEARRAY *array = SafeArrayCreateVector(VT_UI1, 0, count);
if (count) {
const char *data = bytes.constData();
@@ -589,9 +546,9 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
break;
#ifdef QAX_SERVER
- case QVariant::Rect:
- case QVariant::Size:
- case QVariant::Point:
+ case QMetaType::QRect:
+ case QMetaType::QSize:
+ case QMetaType::QPoint:
{
typedef HRESULT(WINAPI* PGetRecordInfoFromTypeInfo)(ITypeInfo *, IRecordInfo **);
static PGetRecordInfoFromTypeInfo pGetRecordInfoFromTypeInfo = 0;
@@ -606,9 +563,10 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
ITypeInfo *typeInfo = 0;
IRecordInfo *recordInfo = 0;
- CLSID clsid = qvar.type() == QVariant::Rect ? CLSID_QRect
- :qvar.type() == QVariant::Size ? CLSID_QSize
- :CLSID_QPoint;
+ const int vType = qvar.metaType().id();
+ CLSID clsid = vType == QMetaType::QRect
+ ? CLSID_QRect
+ : vType == QMetaType::QSize ? CLSID_QSize : CLSID_QPoint;
qAxTypeLibrary->GetTypeInfoOfGuid(clsid, &typeInfo);
if (!typeInfo)
break;
@@ -618,20 +576,20 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
break;
void *record = 0;
- switch (qvar.type()) {
- case QVariant::Rect:
+ switch (qvar.metaType().id()) {
+ case QMetaType::QRect:
{
QRect qrect(qvar.toRect());
recordInfo->RecordCreateCopy(&qrect, &record);
}
break;
- case QVariant::Size:
+ case QMetaType::QSize:
{
QSize qsize(qvar.toSize());
recordInfo->RecordCreateCopy(&qsize, &record);
}
break;
- case QVariant::Point:
+ case QMetaType::QPoint:
{
QPoint qpoint(qvar.toPoint());
recordInfo->RecordCreateCopy(&qpoint, &record);
@@ -653,8 +611,22 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
}
break;
#endif // QAX_SERVER
- case QVariant::UserType:
- {
+
+ case QMetaType::UnknownType: // default-parameters not set
+ if (out && arg.vt == (VT_ERROR|VT_BYREF)) {
+ *arg.plVal = DISP_E_PARAMNOTFOUND;
+ } else {
+ arg.vt = VT_ERROR;
+ arg.lVal = DISP_E_PARAMNOTFOUND;
+ if (out) {
+ arg.plVal = new long(arg.lVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ default:
+ if (qvar.metaType().id() >= QMetaType::User) {
QByteArray subType = qvar.typeName();
#ifdef QAX_SERVER
if (subType.endsWith('*'))
@@ -704,7 +676,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
qAxFactory()->createObjectWrapper(static_cast<QObject*>(user), &arg.pdispVal);
}
#else
- } else if (QMetaType::type(subType)) {
+ } else if (QMetaType::fromName(subType).id() != QMetaType::UnknownType) {
if (out) {
qWarning().noquote() << msgOutParameterNotSupported("subtype");
arg.vt = VT_EMPTY;
@@ -719,33 +691,42 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
} else {
return false;
}
+ } else { // >= User
+ return false;
}
break;
- case QVariant::Invalid: // default-parameters not set
- if (out && arg.vt == (VT_ERROR|VT_BYREF)) {
- *arg.plVal = DISP_E_PARAMNOTFOUND;
- } else {
- arg.vt = VT_ERROR;
- arg.lVal = DISP_E_PARAMNOTFOUND;
- if (out) {
- arg.plVal = new long(arg.lVal);
- arg.vt |= VT_BYREF;
- }
- }
- break;
-
- default:
- return false;
}
Q_ASSERT(!out || (arg.vt & VT_BYREF));
return true;
}
+#ifdef QAX_SERVER
+static QVariant axServer(IUnknown *unknown, const QByteArray &typeName)
+{
+ IAxServerBase *iface = nullptr;
+ if (unknown && typeName != "IDispatch*" && typeName != "IUnknown*")
+ unknown->QueryInterface(IID_IAxServerBase, reinterpret_cast<void**>(&iface));
+ if (iface == nullptr)
+ return {};
+
+ auto *qObj = iface->qObject();
+ iface->Release();
+ QByteArray pointerType = qObj ? QByteArray(qObj->metaObject()->className()) + '*' : typeName;
+ QMetaType pointerMetaType = QMetaType::fromName(pointerType);
+ if (pointerMetaType.id() == QMetaType::UnknownType)
+ pointerMetaType = QMetaType(qRegisterMetaType<QObject *>(pointerType));
+ return QVariant(pointerMetaType, &qObj);
+}
+#endif // QAX_SERVER
+
#undef QVARIANT_TO_VARIANT_POD
/*
- Returns \a arg as a QVariant of type \a type.
+ Returns \a arg as a QVariant of type \a typeName or \a type.
+
+ NOTE: If a \a typeName is specified, value type is assumed. to
+ get/create a pointer type, provide the type id in the \a type argument.
Used by
@@ -762,8 +743,16 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type
- QAxBase::dynamicCall(return value)
- IPropertyBag::Write (QtPropertyBag)
*/
-QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint type)
+QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, int type)
{
+ int nameTypeId = QMetaType::UnknownType;
+ if (type == QMetaType::UnknownType && !typeName.isEmpty()) {
+ auto name = typeName.endsWith('*')
+ ? QByteArrayView{typeName.constData(), typeName.size() - 1}
+ : QByteArrayView{typeName};
+ nameTypeId = QMetaType::fromName(name).id();
+ }
+
QVariant var;
switch(arg.vt) {
case VT_BSTR:
@@ -781,38 +770,38 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
case VT_I1:
var = arg.cVal;
if (typeName == "char")
- type = QVariant::Int;
+ type = QMetaType::Int;
break;
case VT_I1|VT_BYREF:
var = *arg.pcVal;
if (typeName == "char")
- type = QVariant::Int;
+ type = QMetaType::Int;
break;
case VT_I2:
var = arg.iVal;
if (typeName == "short")
- type = QVariant::Int;
+ type = QMetaType::Int;
break;
case VT_I2|VT_BYREF:
var = *arg.piVal;
if (typeName == "short")
- type = QVariant::Int;
+ type = QMetaType::Int;
break;
case VT_I4:
- if (type == QVariant::Color || (!type && typeName == "QColor"))
+ if (type == QMetaType::QColor || nameTypeId == QMetaType::QColor)
var = QVariant::fromValue(OLEColorToQColor(arg.lVal));
#ifndef QT_NO_CURSOR
- else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
+ else if (type == QMetaType::QCursor || nameTypeId == QMetaType::QCursor)
var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(arg.lVal)));
#endif
else
var = (int)arg.lVal;
break;
case VT_I4|VT_BYREF:
- if (type == QVariant::Color || (!type && typeName == "QColor"))
+ if (type == QMetaType::QColor || nameTypeId == QMetaType::QColor)
var = QVariant::fromValue(OLEColorToQColor((int)*arg.plVal));
#ifndef QT_NO_CURSOR
- else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
+ else if (type == QMetaType::QCursor || nameTypeId == QMetaType::QCursor)
var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(*arg.plVal)));
#endif
else
@@ -837,20 +826,20 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
var = *arg.puiVal;
break;
case VT_UI4:
- if (type == QVariant::Color || (!type && typeName == "QColor"))
+ if (type == QMetaType::QColor || nameTypeId == QMetaType::QColor)
var = QVariant::fromValue(OLEColorToQColor(arg.ulVal));
#ifndef QT_NO_CURSOR
- else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
+ else if (type == QMetaType::QCursor || nameTypeId == QMetaType::QCursor)
var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(arg.ulVal)));
#endif
else
var = (int)arg.ulVal;
break;
case VT_UI4|VT_BYREF:
- if (type == QVariant::Color || (!type && typeName == "QColor"))
+ if (type == QMetaType::QColor || nameTypeId == QMetaType::QColor)
var = QVariant::fromValue(OLEColorToQColor((uint)*arg.pulVal));
#ifndef QT_NO_CURSOR
- else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
+ else if (type == QMetaType::QCursor || nameTypeId == QMetaType::QCursor)
var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(*arg.pulVal)));
#endif
else
@@ -894,18 +883,18 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
break;
case VT_DATE:
var = DATEToQDateTime(arg.date);
- if (type == QVariant::Date || (!type && (typeName == "QDate" || typeName == "QDate*"))) {
- var.convert(QVariant::Date);
- } else if (type == QVariant::Time || (!type && (typeName == "QTime" || typeName == "QTime*"))) {
- var.convert(QVariant::Time);
+ if (type == QMetaType::QDate || nameTypeId == QMetaType::QDate) {
+ var.convert(QMetaType(QMetaType::QDate));
+ } else if (type == QMetaType::QTime || nameTypeId == QMetaType::QTime) {
+ var.convert(QMetaType(QMetaType::QTime));
}
break;
case VT_DATE|VT_BYREF:
var = DATEToQDateTime(*arg.pdate);
- if (type == QVariant::Date || (!type && (typeName == "QDate" || typeName == "QDate*"))) {
- var.convert(QVariant::Date);
- } else if (type == QVariant::Time || (!type && (typeName == "QTime" || typeName == "QTime*"))) {
- var.convert(QVariant::Time);
+ if (type == QMetaType::QDate || nameTypeId == QMetaType::QDate) {
+ var.convert(QMetaType(QMetaType::QDate));
+ } else if (type == QMetaType::QTime || nameTypeId == QMetaType::QTime) {
+ var.convert(QMetaType(QMetaType::QTime));
}
break;
case VT_VARIANT:
@@ -923,7 +912,7 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
disp = *arg.ppdispVal;
else
disp = arg.pdispVal;
- if (type == QVariant::Font || (!type && (typeName == "QFont" || typeName == "QFont*"))) {
+ if (type == QMetaType::QFont || nameTypeId == QMetaType::QFont) {
IFont *ifont = nullptr;
if (disp)
disp->QueryInterface(IID_IFont, reinterpret_cast<void**>(&ifont));
@@ -933,7 +922,7 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
} else {
var = QVariant::fromValue(QFont());
}
- } else if (type == QVariant::Pixmap || (!type && (typeName == "QPixmap" || typeName == "QPixmap*"))) {
+ } else if (type == QMetaType::QPixmap || nameTypeId == QMetaType::QPixmap) {
IPicture *ipic = nullptr;
if (disp)
disp->QueryInterface(IID_IPicture, reinterpret_cast<void**>(&ipic));
@@ -945,40 +934,55 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
}
} else {
#ifdef QAX_SERVER
- IAxServerBase *iface = 0;
- if (disp && typeName != "IDispatch*")
- disp->QueryInterface(IID_IAxServerBase, reinterpret_cast<void**>(&iface));
- if (iface) {
- QObject *qObj = iface->qObject();
- iface->Release();
- QByteArray pointerType = qObj ? QByteArray(qObj->metaObject()->className()) + '*' : typeName;
- int pointerTypeId = QMetaType::type(pointerType);
- if (!pointerTypeId)
- pointerTypeId = qRegisterMetaType<QObject *>(pointerType);
- var = QVariant(pointerTypeId, &qObj);
+ if (auto axs = axServer(disp, typeName); axs.isValid()) {
+ var = axs;
} else
#endif
{
if (!typeName.isEmpty()) {
if (arg.vt & VT_BYREF) {
- var = QVariant(qRegisterMetaType<IDispatch**>("IDispatch**"), &arg.ppdispVal);
+ // When the dispinterface is a return value, just assign it to a QVariant
+ static const int dispatchId = qRegisterMetaType<IDispatch**>("IDispatch**");
+ var = QVariant(QMetaType(dispatchId), &arg.ppdispVal);
} else {
#ifndef QAX_SERVER
if (typeName == "QVariant") {
+ // If a QVariant is requested, wrap the dispinterface in a QAxObject
QAxObject *object = new QAxObject(disp);
var = QVariant::fromValue<QAxObject*>(object);
- } else if (typeName != "IDispatch*" && QMetaType::type(typeName)) {
- QByteArray typeNameStr = QByteArray(typeName);
+ } else if (typeName != "IDispatch*" && QMetaType::fromName(typeName).id() != QMetaType::UnknownType) {
+ // Conversion from IDispatch* to a wrapper type is requested. Here, the requested
+ // wrapper type is constructed around the dispinterface, and then returned as
+ // a QVariant containing a pointer to the wrapper type.
+
+ // Calculate the value type from a potential pointer type
+ QByteArray valueTypeStr = QByteArray(typeName);
int pIndex = typeName.lastIndexOf('*');
if (pIndex != -1)
- typeNameStr = typeName.left(pIndex);
- int metaType = QMetaType::type(typeNameStr);
- Q_ASSERT(metaType != 0);
- auto object = static_cast<QAxObject*>(qax_createObjectWrapper(metaType, disp));
- var = QVariant(QMetaType::type(typeName), &object);
- } else
+ valueTypeStr = typeName.left(pIndex);
+
+ const QMetaType metaValueType = QMetaType::fromName(valueTypeStr);
+ Q_ASSERT(metaValueType.id() != QMetaType::UnknownType);
+
+ auto object = static_cast<QAxObject*>(qax_createObjectWrapper(metaValueType.id(), disp));
+
+ // Return object as the original type
+ const QMetaType returnType = QMetaType::fromName(typeName);
+ Q_ASSERT(metaValueType.id() != QMetaType::UnknownType);
+
+ var = QVariant(returnType, &object);
+
+ // The result must be a pointer to an instance derived from QObject
+ Q_ASSERT((var.metaType().flags() & QMetaType::PointerToQObject) != 0);
+ } else {
+#endif
+ // An IDispatch pointer is requested, no conversion required, just return as QVariant
+ // containing the pointer.
+ static const int dispatchId = qRegisterMetaType<IDispatch*>(typeName.constData());
+ var = QVariant(QMetaType(dispatchId), &disp);
+#ifndef QAX_SERVER
+ }
#endif
- var = QVariant(qRegisterMetaType<IDispatch*>(typeName), &disp);
}
}
}
@@ -994,6 +998,10 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
else
unkn = arg.punkVal;
var.setValue(unkn);
+#ifdef QAX_SERVER
+ if (auto axs = axServer(unkn, typeName); axs.isValid())
+ var = axs;
+#endif
}
break;
case VT_ARRAY|VT_VARIANT:
@@ -1219,22 +1227,23 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint
break;
}
- QVariant::Type proptype = (QVariant::Type)type;
- if (proptype == QVariant::Invalid && !typeName.isEmpty()) {
- if (typeName != "QVariant")
- proptype = QVariant::nameToType(typeName);
- }
- if (proptype != QVariant::Type(QMetaType::QVariant) && proptype != QVariant::LastType && proptype != QVariant::Invalid && var.type() != proptype) {
- if (var.canConvert(proptype)) {
+ const int proptype = type != QMetaType::UnknownType || typeName.isEmpty() || typeName == "QVariant"
+ ? type : nameTypeId;
+
+ if (proptype != QMetaType::QVariant && proptype != QMetaType::UnknownType
+ && var.metaType().id() != proptype) {
+ QMetaType propertyMetaType(proptype);
+ if (var.canConvert(propertyMetaType)) {
QVariant oldvar = var;
- if (oldvar.convert(proptype))
+ if (oldvar.convert(propertyMetaType))
var = oldvar;
- } else if (proptype == QVariant::StringList && var.type() == QVariant::List) {
+ } else if (proptype == QMetaType::QStringList
+ && var.metaType().id() == QMetaType::QVariantList) {
bool allStrings = true;
QStringList strings;
const QVariantList list(var.toList());
for (const QVariant &variant : list) {
- if (variant.canConvert(QVariant::String))
+ if (variant.canConvert<QString>())
strings << variant.toString();
else
allStrings = false;