summaryrefslogtreecommitdiffstats
path: root/src/activeqt/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/activeqt/shared')
-rw-r--r--src/activeqt/shared/qaxtypes.cpp1486
-rw-r--r--src/activeqt/shared/qaxtypes.h97
2 files changed, 1583 insertions, 0 deletions
diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp
new file mode 100644
index 0000000..ace81e7
--- /dev/null
+++ b/src/activeqt/shared/qaxtypes.cpp
@@ -0,0 +1,1486 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the ActiveQt framework of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 Nokia Corporation and its Subsidiary(-ies) 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 UNICODE
+#define UNICODE
+#endif
+
+
+#include <ocidl.h>
+#include <olectl.h>
+
+#include "qaxtypes.h"
+
+#ifndef QT_NO_WIN_ACTIVEQT
+
+#include <qcolormap.h>
+#include <qcursor.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qobject.h>
+#ifdef QAX_SERVER
+# include <qaxfactory.h>
+# include <qlibrary.h>
+#else
+# include <quuid.h>
+# include <qaxobject.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QAX_SERVER
+extern ITypeLib *qAxTypeLibrary;
+
+CLSID CLSID_QRect = { 0x34030f30, 0xe359, 0x4fe6, {0xab, 0x82, 0x39, 0x76, 0x6f, 0x5d, 0x91, 0xee } };
+CLSID CLSID_QSize = { 0xcb5f84b3, 0x29e5, 0x491d, {0xba, 0x18, 0x54, 0x72, 0x48, 0x8e, 0xef, 0xba } };
+CLSID CLSID_QPoint = { 0x3be838a3, 0x3fac, 0xbfc4, {0x4c, 0x6c, 0x37, 0xc4, 0x4d, 0x03, 0x02, 0x52 } };
+
+GUID IID_IAxServerBase = { 0xbd2ec165, 0xdfc9, 0x4319, { 0x8b, 0x9b, 0x60, 0xa5, 0x74, 0x78, 0xe9, 0xe3} };
+#else
+extern void *qax_createObjectWrapper(int metaType, IUnknown *iface);
+#endif
+
+static IFontDisp *QFontToIFont(const QFont &font)
+{
+#if defined(Q_OS_WINCE)
+ Q_UNUSED(font);
+ return 0;
+#else
+ FONTDESC fdesc;
+ memset(&fdesc, 0, sizeof(fdesc));
+ fdesc.cbSizeofstruct = sizeof(FONTDESC);
+ fdesc.cySize.Lo = font.pointSize() * 10000;
+ fdesc.fItalic = font.italic();
+ fdesc.fStrikethrough = font.strikeOut();
+ fdesc.fUnderline = font.underline();
+ fdesc.lpstrName = QStringToBSTR(font.family());
+ fdesc.sWeight = font.weight() * 10;
+
+ IFontDisp *f;
+ HRESULT res = OleCreateFontIndirect(&fdesc, IID_IFontDisp, (void**)&f);
+ if (res != S_OK) {
+ if (f) f->Release();
+ f = 0;
+#if defined(QT_CHECK_STATE)
+ qWarning("QFontToIFont: Failed to create IFont");
+#endif
+ }
+ return f;
+#endif
+}
+
+static QFont IFontToQFont(IFont *f)
+{
+ BSTR name;
+ BOOL bold;
+ SHORT charset;
+ BOOL italic;
+ CY size;
+ BOOL strike;
+ BOOL underline;
+ SHORT weight;
+ f->get_Name(&name);
+ f->get_Bold(&bold);
+ f->get_Charset(&charset);
+ f->get_Italic(&italic);
+ f->get_Size(&size);
+ f->get_Strikethrough(&strike);
+ f->get_Underline(&underline);
+ f->get_Weight(&weight);
+ QFont font(QString::fromUtf16((const ushort *)name), size.Lo/9750, weight / 97, italic);
+ font.setBold(bold);
+ font.setStrikeOut(strike);
+ font.setUnderline(underline);
+ SysFreeString(name);
+
+ return font;
+}
+
+static IPictureDisp *QPixmapToIPicture(const QPixmap &pixmap)
+{
+#if defined(Q_OS_WINCE)
+ Q_UNUSED(pixmap);
+ return 0;
+#else
+ IPictureDisp *pic = 0;
+
+ PICTDESC desc;
+ desc.cbSizeofstruct = sizeof(PICTDESC);
+ desc.picType = PICTYPE_BITMAP;
+
+ desc.bmp.hbitmap = 0;
+ desc.bmp.hpal = QColormap::hPal();
+
+ if (!pixmap.isNull()) {
+ desc.bmp.hbitmap = pixmap.toWinHBITMAP();
+ Q_ASSERT(desc.bmp.hbitmap);
+ }
+
+ HRESULT res = OleCreatePictureIndirect(&desc, IID_IPictureDisp, true, (void**)&pic);
+ if (res != S_OK) {
+ if (pic) pic->Release();
+ pic = 0;
+#if defined(QT_CHECK_STATE)
+ qWarning("QPixmapToIPicture: Failed to create IPicture");
+#endif
+ }
+ return pic;
+#endif
+}
+
+static QPixmap IPictureToQPixmap(IPicture *ipic)
+{
+ SHORT type;
+ ipic->get_Type(&type);
+ if (type != PICTYPE_BITMAP)
+ return QPixmap();
+
+ HBITMAP hbm = 0;
+ ipic->get_Handle((OLE_HANDLE*)&hbm);
+ if (!hbm)
+ return QPixmap();
+
+ return QPixmap::fromWinHBITMAP(hbm);
+}
+
+static QDateTime DATEToQDateTime(DATE ole)
+{
+ SYSTEMTIME stime;
+ if (ole >= 949998 || VariantTimeToSystemTime(ole, &stime) == false)
+ return QDateTime();
+
+ QDate date(stime.wYear, stime.wMonth, stime.wDay);
+ QTime time(stime.wHour, stime.wMinute, stime.wSecond, stime.wMilliseconds);
+ return QDateTime(date, time);
+}
+
+static DATE QDateTimeToDATE(const QDateTime &dt)
+{
+ if (!dt.isValid() || dt.isNull())
+ return 949998;
+
+ SYSTEMTIME stime;
+ memset(&stime, 0, sizeof(stime));
+ QDate date = dt.date();
+ QTime time = dt.time();
+ if (date.isValid() && !date.isNull()) {
+ stime.wDay = date.day();
+ stime.wMonth = date.month();
+ stime.wYear = date.year();
+ }
+ if (time.isValid() && !time.isNull()) {
+ stime.wMilliseconds = time.msec();
+ stime.wSecond = time.second();
+ stime.wMinute = time.minute();
+ stime.wHour = time.hour();
+ }
+
+ double vtime;
+ SystemTimeToVariantTime(&stime, &vtime);
+
+ return vtime;
+}
+
+QColor OLEColorToQColor(uint col)
+{
+#if defined(Q_OS_WINCE)
+ return QColor(GetBValue(col),GetGValue(col),GetRValue(col));
+#else
+ COLORREF cref;
+ OleTranslateColor(col, QColormap::hPal(), &cref);
+ return QColor(GetRValue(cref),GetGValue(cref),GetBValue(cref));
+#endif
+}
+
+/*
+ Converts \a var to \a arg, and tries to coerce \a arg to \a type.
+
+ Used by
+
+ QAxServerBase:
+ - QAxServerBase::qt_metacall
+ - IDispatch::Invoke(PROPERTYGET, METHOD)
+ - IPersistPropertyBag::Save
+
+ QAxBase:
+ - IDispatch::Invoke (QAxEventSink)
+ - QAxBase::internalProperty(WriteProperty)
+ - QAxBase::internalInvoke()
+ - QAxBase::dynamicCallHelper()
+ - IPropertyBag::Read (QtPropertyBag)
+
+ Also called recoursively for lists.
+*/
+bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out)
+{
+ QVariant qvar = var;
+ // "type" is the expected type, so coerce if necessary
+ QVariant::Type proptype = typeName.isEmpty() ? QVariant::Invalid : QVariant::nameToType(typeName);
+ if (proptype == QVariant::UserType && !typeName.isEmpty()) {
+ if (typeName == "short" || typeName == "char")
+ proptype = QVariant::Int;
+ else if (typeName == "float")
+ proptype = QVariant::Double;
+ }
+ if (proptype != QVariant::Invalid && proptype != QVariant::UserType && proptype != qvar.type()) {
+ if (qvar.canConvert(proptype))
+ qvar.convert(proptype);
+ else
+ qvar = QVariant(proptype);
+ }
+
+ if (out && arg.vt == (VT_VARIANT|VT_BYREF) && arg.pvarVal) {
+ return QVariantToVARIANT(var, *arg.pvarVal, typeName, false);
+ }
+
+ if (out && proptype == QVariant::Invalid && typeName == "QVariant") {
+ VARIANT *pVariant = new VARIANT;
+ QVariantToVARIANT(var, *pVariant, QByteArray(), false);
+ arg.vt = VT_VARIANT|VT_BYREF;
+ arg.pvarVal = pVariant;
+ return true;
+ }
+
+ switch ((int)qvar.type()) {
+ case QVariant::String:
+ if (out && arg.vt == (VT_BSTR|VT_BYREF)) {
+ if (*arg.pbstrVal)
+ SysFreeString(*arg.pbstrVal);
+ *arg.pbstrVal = QStringToBSTR(qvar.toString());
+ arg.vt = VT_BSTR|VT_BYREF;
+ } else {
+ arg.vt = VT_BSTR;
+ arg.bstrVal = QStringToBSTR(qvar.toString());
+ if (out) {
+ arg.pbstrVal = new BSTR(arg.bstrVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ case QVariant::Int:
+ if (out && arg.vt == (VT_I4|VT_BYREF)) {
+ *arg.plVal = qvar.toInt();
+ } else {
+ arg.vt = VT_I4;
+ arg.lVal = qvar.toInt();
+ if (out) {
+ if (typeName == "short") {
+ arg.vt = VT_I2;
+ arg.piVal = new short(arg.lVal);
+ } else if (typeName == "char") {
+ arg.vt = VT_I1;
+ arg.pcVal= new char(arg.lVal);
+ } else {
+ arg.plVal = new long(arg.lVal);
+ }
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ case QVariant::UInt:
+ if (out && (arg.vt == (VT_UINT|VT_BYREF) || arg.vt == (VT_I4|VT_BYREF))) {
+ *arg.puintVal = qvar.toUInt();
+ } else {
+ arg.vt = VT_UINT;
+ arg.uintVal = qvar.toUInt();
+ if (out) {
+ arg.puintVal = new uint(arg.uintVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ case QVariant::LongLong:
+ if (out && arg.vt == (VT_CY|VT_BYREF)) {
+ arg.pcyVal->int64 = qvar.toLongLong();
+#if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
+ } else if (out && arg.vt == (VT_I8|VT_BYREF)) {
+ *arg.pllVal = qvar.toLongLong();
+ } else {
+ arg.vt = VT_I8;
+ arg.llVal = qvar.toLongLong();
+ if (out) {
+ arg.pllVal = new LONGLONG(arg.llVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+#else
+ } else {
+ arg.vt = VT_CY;
+ arg.cyVal.int64 = qvar.toLongLong();
+ if (out) {
+ arg.pcyVal = new CY(arg.cyVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+#endif
+ break;
+
+ case QVariant::ULongLong:
+ if (out && arg.vt == (VT_CY|VT_BYREF)) {
+ arg.pcyVal->int64 = qvar.toULongLong();
+#if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
+ } else if (out && arg.vt == (VT_UI8|VT_BYREF)) {
+ *arg.pullVal = qvar.toULongLong();
+ } else {
+ arg.vt = VT_UI8;
+ arg.ullVal = qvar.toULongLong();
+ if (out) {
+ arg.pullVal = new ULONGLONG(arg.ullVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+#else
+ } else {
+ arg.vt = VT_CY;
+ arg.cyVal.int64 = qvar.toULongLong();
+ if (out) {
+ arg.pcyVal = new CY(arg.cyVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+
+#endif
+
+ break;
+
+ case QVariant::Bool:
+ if (out && arg.vt == (VT_BOOL|VT_BYREF)) {
+ *arg.pboolVal = qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE;
+ } else {
+ arg.vt = VT_BOOL;
+ arg.boolVal = qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE;
+ if (out) {
+ arg.pboolVal = new short(arg.boolVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+ case QVariant::Double:
+ if (out && arg.vt == (VT_R8|VT_BYREF)) {
+ *arg.pdblVal = qvar.toDouble();
+ } else {
+ arg.vt = VT_R8;
+ arg.dblVal = qvar.toDouble();
+ if (out) {
+ if (typeName == "float") {
+ arg.vt = VT_R4;
+ arg.pfltVal = new float(arg.dblVal);
+ } else {
+ arg.pdblVal = new double(arg.dblVal);
+ }
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+ case QVariant::Color:
+ if (out && arg.vt == (VT_COLOR|VT_BYREF)) {
+
+ *arg.plVal = QColorToOLEColor(qvariant_cast<QColor>(qvar));
+ } else {
+ arg.vt = VT_COLOR;
+ arg.lVal = QColorToOLEColor(qvariant_cast<QColor>(qvar));
+ if (out) {
+ arg.plVal = new long(arg.lVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ case QVariant::Date:
+ case QVariant::Time:
+ case QVariant::DateTime:
+ if (out && arg.vt == (VT_DATE|VT_BYREF)) {
+ *arg.pdate = QDateTimeToDATE(qvar.toDateTime());
+ } else {
+ arg.vt = VT_DATE;
+ arg.date = QDateTimeToDATE(qvar.toDateTime());
+ if (out) {
+ arg.pdate = new DATE(arg.date);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+ case QVariant::Font:
+ if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) {
+ if (*arg.ppdispVal)
+ (*arg.ppdispVal)->Release();
+ *arg.ppdispVal = QFontToIFont(qvariant_cast<QFont>(qvar));
+ } else {
+ arg.vt = VT_DISPATCH;
+ arg.pdispVal = QFontToIFont(qvariant_cast<QFont>(qvar));
+ if (out) {
+ arg.ppdispVal = new IDispatch*(arg.pdispVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ case QVariant::Pixmap:
+ if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) {
+ if (*arg.ppdispVal)
+ (*arg.ppdispVal)->Release();
+ *arg.ppdispVal = QPixmapToIPicture(qvariant_cast<QPixmap>(qvar));
+ } else {
+ arg.vt = VT_DISPATCH;
+ arg.pdispVal = QPixmapToIPicture(qvariant_cast<QPixmap>(qvar));
+ if (out) {
+ arg.ppdispVal = new IDispatch*(arg.pdispVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ case QVariant::Cursor:
+ {
+#ifndef QT_NO_CURSOR
+ int shape = qvariant_cast<QCursor>(qvar).shape();
+ if (out && (arg.vt & VT_BYREF)) {
+ switch(arg.vt & ~VT_BYREF) {
+ case VT_I4:
+ *arg.plVal = shape;
+ break;
+ case VT_I2:
+ *arg.piVal = shape;
+ break;
+ case VT_UI4:
+ *arg.pulVal = shape;
+ break;
+ case VT_UI2:
+ *arg.puiVal = shape;
+ break;
+ case VT_INT:
+ *arg.pintVal = shape;
+ break;
+ case VT_UINT:
+ *arg.puintVal = shape;
+ break;
+ }
+ } else {
+ arg.vt = VT_I4;
+ arg.lVal = shape;
+ if (out) {
+ arg.plVal = new long(arg.lVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+#endif
+ }
+ break;
+
+ case QVariant::List:
+ {
+ const QList<QVariant> list = qvar.toList();
+ const int count = list.count();
+ VARTYPE vt = VT_VARIANT;
+ QVariant::Type listType = QVariant::LastType; // == QVariant
+ if (!typeName.isEmpty() && typeName.startsWith("QList<")) {
+ const QByteArray listTypeName = typeName.mid(6, typeName.length() - 7); // QList<int> -> int
+ listType = QVariant::nameToType(listTypeName);
+ }
+
+ VARIANT variant;
+ void *pElement = &variant;
+ switch(listType) {
+ case QVariant::Int:
+ vt = VT_I4;
+ pElement = &variant.lVal;
+ break;
+ case QVariant::Double:
+ vt = VT_R8;
+ pElement = &variant.dblVal;
+ break;
+ case QVariant::DateTime:
+ vt = VT_DATE;
+ pElement = &variant.date;
+ break;
+ case QVariant::Bool:
+ vt = VT_BOOL;
+ pElement = &variant.boolVal;
+ break;
+ case QVariant::LongLong:
+#if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
+ vt = VT_I8;
+ pElement = &variant.llVal;
+#else
+ vt = VT_CY;
+ pElement = &variant.cyVal;
+#endif
+ break;
+ default:
+ break;
+ }
+ SAFEARRAY *array = 0;
+ bool is2D = false;
+ // If the first element in the array is a list the whole list is
+ // treated as a 2D array. The colum 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};
+ 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) {
+ QVariant elem = columns.at(j);
+ VariantInit(&variant);
+ QVariantToVARIANT(elem, variant, elem.typeName());
+ rgIndices[1] = j;
+ SafeArrayPutElement(array, rgIndices, pElement);
+ clearVARIANT(&variant);
+ }
+ }
+
+ }
+ }
+ if (!is2D) {
+ array = SafeArrayCreateVector(vt, 0, count);
+ for (LONG index = 0; index < count; ++index) {
+ QVariant elem = list.at(index);
+ if (listType != QVariant::LastType)
+ elem.convert(listType);
+ VariantInit(&variant);
+ QVariantToVARIANT(elem, variant, elem.typeName());
+ SafeArrayPutElement(array, &index, pElement);
+ clearVARIANT(&variant);
+ }
+ }
+ if (out && arg.vt == (VT_ARRAY|vt|VT_BYREF)) {
+ if (*arg.pparray)
+ SafeArrayDestroy(*arg.pparray);
+ *arg.pparray = array;
+ } else {
+ arg.vt = VT_ARRAY|vt;
+ arg.parray = array;
+ if (out) {
+ arg.pparray = new SAFEARRAY*(arg.parray);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ }
+ break;
+
+ case QVariant::StringList:
+ {
+ const QStringList list = qvar.toStringList();
+ const int count = list.count();
+ SAFEARRAY *array = SafeArrayCreateVector(VT_BSTR, 0, count);
+ for (LONG index = 0; index < count; ++index) {
+ QString elem = list.at(index);
+ BSTR bstr = QStringToBSTR(elem);
+ SafeArrayPutElement(array, &index, bstr);
+ SysFreeString(bstr);
+ }
+
+ if (out && arg.vt == (VT_ARRAY|VT_BSTR|VT_BYREF)) {
+ if (*arg.pparray)
+ SafeArrayDestroy(*arg.pparray);
+ *arg.pparray = array;
+ } else {
+ arg.vt = VT_ARRAY|VT_BSTR;
+ arg.parray = array;
+ if (out) {
+ arg.pparray = new SAFEARRAY*(arg.parray);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ }
+ break;
+
+ case QVariant::ByteArray:
+ {
+ const QByteArray bytes = qvar.toByteArray();
+ const uint count = bytes.count();
+ SAFEARRAY *array = SafeArrayCreateVector(VT_UI1, 0, count);
+ if (count) {
+ const char *data = bytes.constData();
+ char *dest;
+ SafeArrayAccessData(array, (void **)&dest);
+ memcpy(dest, data, count);
+ SafeArrayUnaccessData(array);
+ }
+
+ if (out && arg.vt == (VT_ARRAY|VT_UI1|VT_BYREF)) {
+ if (*arg.pparray)
+ SafeArrayDestroy(*arg.pparray);
+ *arg.pparray = array;
+ } else {
+ arg.vt = VT_ARRAY|VT_UI1;
+ arg.parray = array;
+ if (out) {
+ arg.pparray = new SAFEARRAY*(arg.parray);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ }
+ break;
+
+#ifdef QAX_SERVER
+ case QVariant::Rect:
+ case QVariant::Size:
+ case QVariant::Point:
+ {
+ typedef HRESULT(WINAPI* PGetRecordInfoFromTypeInfo)(ITypeInfo *, IRecordInfo **);
+ static PGetRecordInfoFromTypeInfo pGetRecordInfoFromTypeInfo = 0;
+ static bool resolved = false;
+ if (!resolved) {
+ resolved = true;
+ pGetRecordInfoFromTypeInfo = (PGetRecordInfoFromTypeInfo)QLibrary::resolve(QLatin1String("oleaut32"),
+ "GetRecordInfoFromTypeInfo");
+ }
+ if (!pGetRecordInfoFromTypeInfo)
+ break;
+
+ ITypeInfo *typeInfo = 0;
+ IRecordInfo *recordInfo = 0;
+ CLSID clsid = qvar.type() == QVariant::Rect ? CLSID_QRect
+ :qvar.type() == QVariant::Size ? CLSID_QSize
+ :CLSID_QPoint;
+ qAxTypeLibrary->GetTypeInfoOfGuid(clsid, &typeInfo);
+ if (!typeInfo)
+ break;
+ pGetRecordInfoFromTypeInfo(typeInfo, &recordInfo);
+ typeInfo->Release();
+ if (!recordInfo)
+ break;
+
+ void *record = 0;
+ switch (qvar.type()) {
+ case QVariant::Rect:
+ {
+ QRect qrect(qvar.toRect());
+ recordInfo->RecordCreateCopy(&qrect, &record);
+ }
+ break;
+ case QVariant::Size:
+ {
+ QSize qsize(qvar.toSize());
+ recordInfo->RecordCreateCopy(&qsize, &record);
+ }
+ break;
+ case QVariant::Point:
+ {
+ QPoint qpoint(qvar.toPoint());
+ recordInfo->RecordCreateCopy(&qpoint, &record);
+ }
+ break;
+ }
+
+ arg.vt = VT_RECORD;
+ arg.pRecInfo = recordInfo,
+ arg.pvRecord = record;
+ if (out) {
+ qWarning("QVariantToVARIANT: out-parameter not supported for records");
+ return false;
+ }
+ }
+ break;
+#endif // QAX_SERVER
+ case QVariant::UserType:
+ {
+ QByteArray subType = qvar.typeName();
+#ifdef QAX_SERVER
+ if (subType.endsWith('*'))
+ subType.truncate(subType.length() - 1);
+#endif
+ if (!qstrcmp(qvar.typeName(), "IDispatch*")) {
+ arg.vt = VT_DISPATCH;
+ arg.pdispVal = *(IDispatch**)qvar.data();
+ if (arg.pdispVal)
+ arg.pdispVal->AddRef();
+ if (out) {
+ qWarning("QVariantToVARIANT: out-parameter not supported for IDispatch");
+ return false;
+ }
+ } else if (!qstrcmp(qvar.typeName(), "IDispatch**")) {
+ arg.vt = VT_DISPATCH;
+ arg.ppdispVal = *(IDispatch***)qvar.data();
+ if (out)
+ arg.vt |= VT_BYREF;
+ } else if (!qstrcmp(qvar.typeName(), "IUnknown*")) {
+ arg.vt = VT_UNKNOWN;
+ arg.punkVal = *(IUnknown**)qvar.data();
+ if (arg.punkVal)
+ arg.punkVal->AddRef();
+ if (out) {
+ qWarning("QVariantToVARIANT: out-parameter not supported for IUnknown");
+ return false;
+ }
+#ifdef QAX_SERVER
+ } else if (qAxFactory()->metaObject(QString::fromLatin1(subType.constData()))) {
+ arg.vt = VT_DISPATCH;
+ void *user = *(void**)qvar.constData();
+// qVariantGet(qvar, user, qvar.typeName());
+ if (!user) {
+ arg.pdispVal = 0;
+ } else {
+ qAxFactory()->createObjectWrapper(static_cast<QObject*>(user), &arg.pdispVal);
+ }
+ if (out) {
+ qWarning("QVariantToVARIANT: out-parameter not supported for subtype");
+ return false;
+ }
+#else
+ } else if (QMetaType::type(subType)) {
+ QAxObject *object = *(QAxObject**)qvar.constData();
+// qVariantGet(qvar, object, subType);
+ arg.vt = VT_DISPATCH;
+ object->queryInterface(IID_IDispatch, (void**)&arg.pdispVal);
+ if (out) {
+ qWarning("QVariantToVARIANT: out-parameter not supported for subtype");
+ return false;
+ }
+#endif
+ } else {
+ 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;
+}
+
+/*!
+ Copies the data in \a var into \a data.
+
+ Used by
+
+ QAxServerBase:
+ - QAxServerBase::qt_metacall (update out parameters/return value)
+
+ QAxBase:
+ - internalProperty(ReadProperty)
+ - internalInvoke(update out parameters/return value)
+
+*/
+bool QVariantToVoidStar(const QVariant &var, void *data, const QByteArray &typeName, uint type)
+{
+ if (!data)
+ return true;
+
+ if (type == QVariant::LastType || (type == 0 && typeName == "QVariant")) {
+ *(QVariant*)data = var;
+ return true;
+ }
+
+ switch (var.type()) {
+ case QVariant::Invalid:
+ break;
+ case QVariant::String:
+ *(QString*)data = var.toString();
+ break;
+ case QVariant::Int:
+ *(int*)data = var.toInt();
+ break;
+ case QVariant::UInt:
+ *(uint*)data = var.toUInt();
+ break;
+ case QVariant::Bool:
+ *(bool*)data = var.toBool();
+ break;
+ case QVariant::Double:
+ *(double*)data = var.toDouble();
+ break;
+ case QVariant::Color:
+ *(QColor*)data = qvariant_cast<QColor>(var);
+ break;
+ case QVariant::Date:
+ *(QDate*)data = var.toDate();
+ break;
+ case QVariant::Time:
+ *(QTime*)data = var.toTime();
+ break;
+ case QVariant::DateTime:
+ *(QDateTime*)data = var.toDateTime();
+ break;
+ case QVariant::Font:
+ *(QFont*)data = qvariant_cast<QFont>(var);
+ break;
+ case QVariant::Pixmap:
+ *(QPixmap*)data = qvariant_cast<QPixmap>(var);
+ break;
+#ifndef QT_NO_CURSOR
+ case QVariant::Cursor:
+ *(QCursor*)data = qvariant_cast<QCursor>(var);
+ break;
+#endif
+ case QVariant::List:
+ *(QList<QVariant>*)data = var.toList();
+ break;
+ case QVariant::StringList:
+ *(QStringList*)data = var.toStringList();
+ break;
+ case QVariant::ByteArray:
+ *(QByteArray*)data = var.toByteArray();
+ break;
+ case QVariant::LongLong:
+ *(qint64*)data = var.toLongLong();
+ break;
+ case QVariant::ULongLong:
+ *(quint64*)data = var.toULongLong();
+ break;
+ case QVariant::Rect:
+ *(QRect*)data = var.toRect();
+ break;
+ case QVariant::Size:
+ *(QSize*)data = var.toSize();
+ break;
+ case QVariant::Point:
+ *(QPoint*)data = var.toPoint();
+ break;
+ case QVariant::UserType:
+ *(void**)data = *(void**)var.constData();
+// qVariantGet(var, *(void**)data, typeName);
+ break;
+ default:
+ qWarning("QVariantToVoidStar: Unhandled QVariant type");
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Returns \a arg as a QVariant of type \a type.
+
+ Used by
+
+ QAxServerBase:
+ - QAxServerBase::qt_metacall(update out parameters/return value)
+ - IDispatch::Invoke(METHOD, PROPERTYPUT)
+ - IPersistPropertyBag::Load
+
+ QAxBase:
+ - IDispatch::Invoke (QAxEventSink)
+ - QAxBase::internalProperty(ReadProperty)
+ - QAxBase::internalInvoke(update out parameters/return value)
+ - QAxBase::dynamicCallHelper(update out parameters)
+ - QAxBase::dynamicCall(return value)
+ - IPropertyBag::Write (QtPropertyBag)
+*/
+QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint type)
+{
+ QVariant var;
+ switch(arg.vt) {
+ case VT_BSTR:
+ var = QString::fromUtf16((const ushort *)arg.bstrVal);
+ break;
+ case VT_BSTR|VT_BYREF:
+ var = QString::fromUtf16((const ushort *)*arg.pbstrVal);
+ break;
+ case VT_BOOL:
+ var = QVariant((bool)arg.boolVal);
+ break;
+ case VT_BOOL|VT_BYREF:
+ var = QVariant((bool)*arg.pboolVal);
+ break;
+ case VT_I1:
+ var = arg.cVal;
+ if (typeName == "char")
+ type = QVariant::Int;
+ break;
+ case VT_I1|VT_BYREF:
+ var = *arg.pcVal;
+ if (typeName == "char")
+ type = QVariant::Int;
+ break;
+ case VT_I2:
+ var = arg.iVal;
+ if (typeName == "short")
+ type = QVariant::Int;
+ break;
+ case VT_I2|VT_BYREF:
+ var = *arg.piVal;
+ if (typeName == "short")
+ type = QVariant::Int;
+ break;
+ case VT_I4:
+ if (type == QVariant::Color || (!type && typeName == "QColor"))
+ var = qVariantFromValue(OLEColorToQColor(arg.lVal));
+#ifndef QT_NO_CURSOR
+ else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
+ var = qVariantFromValue(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"))
+ var = qVariantFromValue(OLEColorToQColor((int)*arg.plVal));
+#ifndef QT_NO_CURSOR
+ else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
+ var = qVariantFromValue(QCursor(static_cast<Qt::CursorShape>(*arg.plVal)));
+#endif
+ else
+ var = (int)*arg.plVal;
+ break;
+ case VT_INT:
+ var = arg.intVal;
+ break;
+ case VT_INT|VT_BYREF:
+ var = *arg.pintVal;
+ break;
+ case VT_UI1:
+ var = arg.bVal;
+ break;
+ case VT_UI1|VT_BYREF:
+ var = *arg.pbVal;
+ break;
+ case VT_UI2:
+ var = arg.uiVal;
+ break;
+ case VT_UI2|VT_BYREF:
+ var = *arg.puiVal;
+ break;
+ case VT_UI4:
+ if (type == QVariant::Color || (!type && typeName == "QColor"))
+ var = qVariantFromValue(OLEColorToQColor(arg.ulVal));
+#ifndef QT_NO_CURSOR
+ else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
+ var = qVariantFromValue(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"))
+ var = qVariantFromValue(OLEColorToQColor((uint)*arg.pulVal));
+#ifndef QT_NO_CURSOR
+ else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
+ var = qVariantFromValue(QCursor(static_cast<Qt::CursorShape>(*arg.pulVal)));
+#endif
+ else
+ var = (int)*arg.pulVal;
+ break;
+ case VT_UINT:
+ var = arg.uintVal;
+ break;
+ case VT_UINT|VT_BYREF:
+ var = *arg.puintVal;
+ break;
+ case VT_CY:
+ var = arg.cyVal.int64;
+ break;
+ case VT_CY|VT_BYREF:
+ var = arg.pcyVal->int64;
+ break;
+#if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
+ case VT_I8:
+ var = arg.llVal;
+ break;
+ case VT_I8|VT_BYREF:
+ var = *arg.pllVal;
+ break;
+ case VT_UI8:
+ var = arg.ullVal;
+ break;
+ case VT_UI8|VT_BYREF:
+ var = *arg.pullVal;
+ break;
+#endif
+ case VT_R4:
+ var = arg.fltVal;
+ break;
+ case VT_R4|VT_BYREF:
+ var = *arg.pfltVal;
+ break;
+ case VT_R8:
+ var = arg.dblVal;
+ break;
+ case VT_R8|VT_BYREF:
+ var = *arg.pdblVal;
+ 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);
+ }
+ 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);
+ }
+ break;
+ case VT_VARIANT:
+ case VT_VARIANT|VT_BYREF:
+ if (arg.pvarVal)
+ var = VARIANTToQVariant(*arg.pvarVal, typeName);
+ break;
+
+ case VT_DISPATCH:
+ case VT_DISPATCH|VT_BYREF:
+ {
+ // pdispVal and ppdispVal are a union
+ IDispatch *disp = 0;
+ if (arg.vt & VT_BYREF)
+ disp = *arg.ppdispVal;
+ else
+ disp = arg.pdispVal;
+ if (type == QVariant::Font || (!type && (typeName == "QFont" || typeName == "QFont*"))) {
+ IFont *ifont = 0;
+ if (disp)
+ disp->QueryInterface(IID_IFont, (void**)&ifont);
+ if (ifont) {
+ var = qVariantFromValue(IFontToQFont(ifont));
+ ifont->Release();
+ } else {
+ var = qVariantFromValue(QFont());
+ }
+ } else if (type == QVariant::Pixmap || (!type && (typeName == "QPixmap" || typeName == "QPixmap*"))) {
+ IPicture *ipic = 0;
+ if (disp)
+ disp->QueryInterface(IID_IPicture, (void**)&ipic);
+ if (ipic) {
+ var = qVariantFromValue(IPictureToQPixmap(ipic));
+ ipic->Release();
+ } else {
+ var = qVariantFromValue(QPixmap());
+ }
+ } else {
+#ifdef QAX_SERVER
+ IAxServerBase *iface = 0;
+ if (disp && typeName != "IDispatch*")
+ disp->QueryInterface(IID_IAxServerBase, (void**)&iface);
+ if (iface) {
+ QObject *qObj = iface->qObject();
+ iface->Release();
+ var = QVariant(qRegisterMetaType<QObject*>(qObj ? QByteArray(qObj->metaObject()->className()) + "*" : typeName), &qObj);
+ } else
+#endif
+ {
+ if (!typeName.isEmpty()) {
+ if (arg.vt & VT_BYREF) {
+ var = QVariant(qRegisterMetaType<IDispatch**>("IDispatch**"), &arg.ppdispVal);
+ } else {
+#ifndef QAX_SERVER
+ if (typeName == "QVariant") {
+ QAxObject *object = new QAxObject(disp);
+ var = qVariantFromValue<QAxObject*>(object);
+ } else if (typeName != "IDispatch*" && QMetaType::type(typeName)) {
+ QByteArray typeNameStr = QByteArray(typeName);
+ int pIndex = typeName.lastIndexOf('*');
+ if (pIndex != -1)
+ typeNameStr = typeName.left(pIndex);
+ int metaType = QMetaType::type(typeNameStr);
+ Q_ASSERT(metaType != 0);
+ QAxObject *object = (QAxObject*)qax_createObjectWrapper(metaType, disp);
+ var = QVariant(QMetaType::type(typeName), &object);
+ } else
+#endif
+ var = QVariant(qRegisterMetaType<IDispatch*>(typeName), &disp);
+ }
+ }
+ }
+ }
+ }
+ break;
+ case VT_UNKNOWN:
+ case VT_UNKNOWN|VT_BYREF:
+ {
+ IUnknown *unkn = 0;
+ if (arg.vt & VT_BYREF)
+ unkn = *arg.ppunkVal;
+ else
+ unkn = arg.punkVal;
+ qVariantSetValue(var, unkn);
+ }
+ break;
+ case VT_ARRAY|VT_VARIANT:
+ case VT_ARRAY|VT_VARIANT|VT_BYREF:
+ {
+ SAFEARRAY *array = 0;
+ if ( arg.vt & VT_BYREF )
+ array = *arg.pparray;
+ else
+ array = arg.parray;
+
+ UINT cDims = array ? SafeArrayGetDim(array) : 0;
+ switch(cDims) {
+ case 1:
+ {
+ QVariantList list;
+
+ long lBound, uBound;
+ SafeArrayGetLBound( array, 1, &lBound );
+ SafeArrayGetUBound( array, 1, &uBound );
+
+ for ( long i = lBound; i <= uBound; ++i ) {
+ VARIANT var;
+ VariantInit( &var );
+ SafeArrayGetElement( array, &i, &var );
+
+ QVariant qvar = VARIANTToQVariant( var, 0 );
+ clearVARIANT( &var );
+ list << qvar;
+ }
+
+ var = list;
+ }
+ break;
+
+ case 2:
+ {
+ QVariantList listList; // a list of lists
+ long dimIndices[2];
+
+ long xlBound, xuBound, ylBound, yuBound;
+ SafeArrayGetLBound(array, 1, &xlBound);
+ SafeArrayGetUBound(array, 1, &xuBound);
+ SafeArrayGetLBound(array, 2, &ylBound);
+ SafeArrayGetUBound(array, 2, &yuBound);
+
+ for (long x = xlBound; x <= xuBound; ++x) {
+ QVariantList list;
+
+ dimIndices[0] = x;
+ for (long y = ylBound; y <= yuBound; ++y) {
+ VARIANT var;
+ VariantInit(&var);
+ dimIndices[1] = y;
+ SafeArrayGetElement(array, dimIndices, &var);
+
+ QVariant qvar = VARIANTToQVariant(var, 0);
+ clearVARIANT(&var);
+ list << qvar;
+ }
+
+ listList << QVariant(list);
+ }
+ var = listList;
+ }
+ break;
+ default:
+ var = QVariantList();
+ break;
+ }
+ }
+ break;
+
+ case VT_ARRAY|VT_BSTR:
+ case VT_ARRAY|VT_BSTR|VT_BYREF:
+ {
+ SAFEARRAY *array = 0;
+ if (arg.vt & VT_BYREF)
+ array = *arg.pparray;
+ else
+ array = arg.parray;
+
+ QStringList strings;
+ if (!array || array->cDims != 1) {
+ var = strings;
+ break;
+ }
+
+ long lBound, uBound;
+ SafeArrayGetLBound(array, 1, &lBound);
+ SafeArrayGetUBound(array, 1, &uBound);
+
+ for (long i = lBound; i <= uBound; ++i) {
+ BSTR bstr;
+ SafeArrayGetElement(array, &i, &bstr);
+ strings << QString::fromUtf16((const ushort *)bstr);
+ SysFreeString(bstr);
+ }
+
+ var = strings;
+ }
+ break;
+
+ case VT_ARRAY|VT_UI1:
+ case VT_ARRAY|VT_UI1|VT_BYREF:
+ {
+ SAFEARRAY *array = 0;
+ if (arg.vt & VT_BYREF)
+ array = *arg.pparray;
+ else
+ array = arg.parray;
+
+ QByteArray bytes;
+ if (!array || array->cDims != 1) {
+ var = bytes;
+ break;
+ }
+
+ long lBound, uBound;
+ SafeArrayGetLBound(array, 1, &lBound);
+ SafeArrayGetUBound(array, 1, &uBound);
+
+ if (uBound != -1) { // non-empty array
+ bytes.resize(uBound - lBound + 1);
+ char *data = bytes.data();
+ char *src;
+ SafeArrayAccessData(array, (void**)&src);
+ memcpy(data, src, bytes.size());
+ SafeArrayUnaccessData(array);
+ }
+
+ var = bytes;
+ }
+ break;
+
+#if defined(QAX_SERVER)
+ case VT_RECORD:
+ case VT_RECORD|VT_BYREF:
+ if (arg.pvRecord && arg.pRecInfo) {
+ IRecordInfo *recordInfo = arg.pRecInfo;
+ void *record = arg.pvRecord;
+ GUID guid;
+ recordInfo->GetGuid(&guid);
+
+ if (guid == CLSID_QRect) {
+ QRect qrect;
+ recordInfo->RecordCopy(record, &qrect);
+ var = qrect;
+ } else if (guid == CLSID_QSize) {
+ QSize qsize;
+ recordInfo->RecordCopy(record, &qsize);
+ var = qsize;
+ } else if (guid == CLSID_QPoint) {
+ QPoint qpoint;
+ recordInfo->RecordCopy(record, &qpoint);
+ var = qpoint;
+ }
+ }
+ break;
+#endif // QAX_SERVER
+ default:
+#if !defined(Q_OS_WINCE)
+ // support for any SAFEARRAY(Type) where Type can be converted to a QVariant
+ // -> QVariantList
+ if (arg.vt & VT_ARRAY) {
+ SAFEARRAY *array = 0;
+ if (arg.vt & VT_BYREF)
+ array = *arg.pparray;
+ else
+ array = arg.parray;
+
+ QVariantList list;
+ if (!array || array->cDims != 1) {
+ var = list;
+ break;
+ }
+
+ // find out where to store the element
+ VARTYPE vt;
+ VARIANT variant;
+ SafeArrayGetVartype(array, &vt);
+
+ void *pElement = 0;
+ switch(vt) {
+ case VT_BSTR: Q_ASSERT(false); break; // already covered
+ case VT_BOOL: pElement = &variant.boolVal; break;
+ case VT_I1: pElement = &variant.cVal; break;
+ case VT_I2: pElement = &variant.iVal; break;
+ case VT_I4: pElement = &variant.lVal; break;
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ case VT_I8: pElement = &variant.llVal; break;
+ case VT_UI8: pElement = &variant.ullVal; break;
+#endif
+ case VT_INT: pElement = &variant.intVal; break;
+ case VT_UI1: Q_ASSERT(false); break; // already covered
+ case VT_UI2: pElement = &variant.uiVal; break;
+ case VT_UI4: pElement = &variant.ulVal; break;
+ case VT_UINT: pElement = &variant.uintVal; break;
+ case VT_CY: pElement = &variant.cyVal; break;
+ case VT_R4: pElement = &variant.fltVal; break;
+ case VT_R8: pElement = &variant.dblVal; break;
+ case VT_DATE: pElement = &variant.date; break;
+ case VT_VARIANT: Q_ASSERT(false); break; // already covered
+ default:
+ break;
+ }
+ if (!pElement) {
+ var = list;
+ break;
+ }
+
+ long lBound, uBound;
+ SafeArrayGetLBound( array, 1, &lBound );
+ SafeArrayGetUBound( array, 1, &uBound );
+
+ for ( long i = lBound; i <= uBound; ++i ) {
+ variant.vt = vt;
+ SafeArrayGetElement(array, &i, pElement);
+ QVariant qvar = VARIANTToQVariant(variant, 0);
+ clearVARIANT(&variant);
+ list << qvar;
+ }
+
+ var = list;
+ }
+#endif
+ break;
+ }
+
+ QVariant::Type proptype = (QVariant::Type)type;
+ if (proptype == QVariant::Invalid && !typeName.isEmpty())
+ proptype = QVariant::nameToType(typeName);
+ if (proptype != QVariant::LastType && proptype != QVariant::Invalid && var.type() != proptype) {
+ if (var.canConvert(proptype)) {
+ QVariant oldvar = var;
+ if (oldvar.convert(proptype))
+ var = oldvar;
+ } else if (proptype == QVariant::StringList && var.type() == QVariant::List) {
+ bool allStrings = true;
+ QStringList strings;
+ const QList<QVariant> list(var.toList());
+ for (QList<QVariant>::ConstIterator it(list.begin()); it != list.end(); ++it) {
+ QVariant variant = *it;
+ if (variant.canConvert(QVariant::String))
+ strings << variant.toString();
+ else
+ allStrings = false;
+ }
+ if (allStrings)
+ var = strings;
+ } else {
+ var = QVariant();
+ }
+ }
+ return var;
+}
+
+void clearVARIANT(VARIANT *var)
+{
+ if (var->vt & VT_BYREF) {
+ switch(var->vt) {
+ case VT_BSTR|VT_BYREF:
+ SysFreeString(*var->pbstrVal);
+ delete var->pbstrVal;
+ break;
+ case VT_BOOL|VT_BYREF:
+ delete var->pboolVal;
+ break;
+ case VT_I1|VT_BYREF:
+ delete var->pcVal;
+ break;
+ case VT_I2|VT_BYREF:
+ delete var->piVal;
+ break;
+ case VT_I4|VT_BYREF:
+ delete var->plVal;
+ break;
+ case VT_INT|VT_BYREF:
+ delete var->pintVal;
+ break;
+ case VT_UI1|VT_BYREF:
+ delete var->pbVal;
+ break;
+ case VT_UI2|VT_BYREF:
+ delete var->puiVal;
+ break;
+ case VT_UI4|VT_BYREF:
+ delete var->pulVal;
+ break;
+ case VT_UINT|VT_BYREF:
+ delete var->puintVal;
+ break;
+#if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
+ case VT_I8|VT_BYREF:
+ delete var->pllVal;
+ break;
+ case VT_UI8|VT_BYREF:
+ delete var->pullVal;
+ break;
+#endif
+ case VT_CY|VT_BYREF:
+ delete var->pcyVal;
+ break;
+ case VT_R4|VT_BYREF:
+ delete var->pfltVal;
+ break;
+ case VT_R8|VT_BYREF:
+ delete var->pdblVal;
+ break;
+ case VT_DATE|VT_BYREF:
+ delete var->pdate;
+ break;
+ case VT_DISPATCH|VT_BYREF:
+ (*var->ppdispVal)->Release();
+ delete var->ppdispVal;
+ break;
+ case VT_ARRAY|VT_VARIANT|VT_BYREF:
+ case VT_ARRAY|VT_UI1|VT_BYREF:
+ case VT_ARRAY|VT_BSTR|VT_BYREF:
+ SafeArrayDestroy(*var->pparray);
+ delete var->pparray;
+ break;
+ case VT_VARIANT|VT_BYREF:
+ delete var->pvarVal;
+ break;
+ }
+ VariantInit(var);
+ } else {
+ VariantClear(var);
+ }
+}
+
+QT_END_NAMESPACE
+#endif // QT_NO_WIN_ACTIVEQT
diff --git a/src/activeqt/shared/qaxtypes.h b/src/activeqt/shared/qaxtypes.h
new file mode 100644
index 0000000..a29030f
--- /dev/null
+++ b/src/activeqt/shared/qaxtypes.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the ActiveQt framework of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 Nokia Corporation and its Subsidiary(-ies) 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 QAXTYPES_H
+#define QAXTYPES_H
+
+#if !defined(_WINDOWS_) && !defined(_WINDOWS_H) && !defined(__WINDOWS__)
+#error Must include windows.h first!
+#endif
+
+#include <QtGui/qcolor.h>
+#include <QtGui/qfont.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(ActiveQt)
+
+#ifndef QT_NO_WIN_ACTIVEQT
+
+extern GUID IID_IAxServerBase;
+struct IAxServerBase : public IUnknown
+{
+ virtual IUnknown *clientSite() const = 0;
+ virtual void emitPropertyChanged(const char*) = 0;
+ virtual bool emitRequestPropertyChange(const char*) = 0;
+ virtual QObject *qObject() const = 0;
+ virtual void reportError(int code, const QString &src, const QString &desc, const QString &context) = 0;
+};
+
+#define HIMETRIC_PER_INCH 2540
+#define MAP_PIX_TO_LOGHIM(x,ppli) ((HIMETRIC_PER_INCH*(x) + ((ppli)>>1)) / (ppli))
+#define MAP_LOGHIM_TO_PIX(x,ppli) (((ppli)*(x) + HIMETRIC_PER_INCH/2) / HIMETRIC_PER_INCH)
+#define QAX_NUM_PARAMS 8
+
+static inline BSTR QStringToBSTR(const QString &str)
+{
+ return SysAllocStringLen((OLECHAR*)str.unicode(), str.length());
+}
+
+static inline uint QColorToOLEColor(const QColor &col)
+{
+ return qRgba(col.blue(), col.green(), col.red(), 0x00);
+}
+
+extern QColor OLEColorToQColor(uint col);
+
+extern bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName = 0, bool out = false);
+extern QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint type = 0);
+extern bool QVariantToVoidStar(const QVariant &var, void *data, const QByteArray &typeName, uint type = 0);
+extern void clearVARIANT(VARIANT *var);
+
+QT_END_NAMESPACE
+#endif // QT_NO_WIN_ACTIVEQT
+
+QT_END_HEADER
+
+#endif // QAXTYPES_H