Qt 4.8
qaxtypes.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the ActiveQt framework of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 ** * Redistributions of source code must retain the above copyright
15 ** notice, this list of conditions and the following disclaimer.
16 ** * Redistributions in binary form must reproduce the above copyright
17 ** notice, this list of conditions and the following disclaimer in
18 ** the documentation and/or other materials provided with the
19 ** distribution.
20 ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 ** of its contributors may be used to endorse or promote products derived
22 ** from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #include <ocidl.h>
42 #include <olectl.h>
43 
44 #include "qaxtypes.h"
45 
46 #ifndef QT_NO_WIN_ACTIVEQT
47 
48 #include <qcolormap.h>
49 #include <qcursor.h>
50 #include <qpixmap.h>
51 #include <qpainter.h>
52 #include <qobject.h>
53 #ifdef QAX_SERVER
54 # include <qaxfactory.h>
55 # include <private/qsystemlibrary_p.h>
56 #else
57 # include <quuid.h>
58 # include <qaxobject.h>
59 #endif
60 
62 
63 #ifdef QAX_SERVER
64 extern ITypeLib *qAxTypeLibrary;
65 
66 CLSID CLSID_QRect = { 0x34030f30, 0xe359, 0x4fe6, {0xab, 0x82, 0x39, 0x76, 0x6f, 0x5d, 0x91, 0xee } };
67 CLSID CLSID_QSize = { 0xcb5f84b3, 0x29e5, 0x491d, {0xba, 0x18, 0x54, 0x72, 0x48, 0x8e, 0xef, 0xba } };
68 CLSID CLSID_QPoint = { 0x3be838a3, 0x3fac, 0xbfc4, {0x4c, 0x6c, 0x37, 0xc4, 0x4d, 0x03, 0x02, 0x52 } };
69 
70 GUID IID_IAxServerBase = { 0xbd2ec165, 0xdfc9, 0x4319, { 0x8b, 0x9b, 0x60, 0xa5, 0x74, 0x78, 0xe9, 0xe3} };
71 #else
72 extern void *qax_createObjectWrapper(int metaType, IUnknown *iface);
73 #endif
74 
75 static IFontDisp *QFontToIFont(const QFont &font)
76 {
77 #if defined(Q_OS_WINCE)
78  Q_UNUSED(font);
79  return 0;
80 #else
81  FONTDESC fdesc;
82  memset(&fdesc, 0, sizeof(fdesc));
83  fdesc.cbSizeofstruct = sizeof(FONTDESC);
84  fdesc.cySize.Lo = font.pointSize() * 10000;
85  fdesc.fItalic = font.italic();
86  fdesc.fStrikethrough = font.strikeOut();
87  fdesc.fUnderline = font.underline();
88  fdesc.lpstrName = QStringToBSTR(font.family());
89  fdesc.sWeight = font.weight() * 10;
90 
91  IFontDisp *f;
92  HRESULT res = OleCreateFontIndirect(&fdesc, IID_IFontDisp, (void**)&f);
93  if (res != S_OK) {
94  if (f) f->Release();
95  f = 0;
96 #if defined(QT_CHECK_STATE)
97  qWarning("QFontToIFont: Failed to create IFont");
98 #endif
99  }
100  return f;
101 #endif
102 }
103 
104 static QFont IFontToQFont(IFont *f)
105 {
106  BSTR name;
107  BOOL bold;
108  SHORT charset;
109  BOOL italic;
110  CY size;
111  BOOL strike;
112  BOOL underline;
113  SHORT weight;
114  f->get_Name(&name);
115  f->get_Bold(&bold);
116  f->get_Charset(&charset);
117  f->get_Italic(&italic);
118  f->get_Size(&size);
119  f->get_Strikethrough(&strike);
120  f->get_Underline(&underline);
121  f->get_Weight(&weight);
122  QFont font(QString::fromWCharArray(name), size.Lo/9750, weight / 97, italic);
123  font.setBold(bold);
124  font.setStrikeOut(strike);
125  font.setUnderline(underline);
126  SysFreeString(name);
127 
128  return font;
129 }
130 
131 static IPictureDisp *QPixmapToIPicture(const QPixmap &pixmap)
132 {
133 #if defined(Q_OS_WINCE)
134  Q_UNUSED(pixmap);
135  return 0;
136 #else
137  IPictureDisp *pic = 0;
138 
139  PICTDESC desc;
140  desc.cbSizeofstruct = sizeof(PICTDESC);
141  desc.picType = PICTYPE_BITMAP;
142 
143  desc.bmp.hbitmap = 0;
144  desc.bmp.hpal = QColormap::hPal();
145 
146  if (!pixmap.isNull()) {
147  desc.bmp.hbitmap = pixmap.toWinHBITMAP();
148  Q_ASSERT(desc.bmp.hbitmap);
149  }
150 
151  HRESULT res = OleCreatePictureIndirect(&desc, IID_IPictureDisp, true, (void**)&pic);
152  if (res != S_OK) {
153  if (pic) pic->Release();
154  pic = 0;
155 #if defined(QT_CHECK_STATE)
156  qWarning("QPixmapToIPicture: Failed to create IPicture");
157 #endif
158  }
159  return pic;
160 #endif
161 }
162 
163 static QPixmap IPictureToQPixmap(IPicture *ipic)
164 {
165  SHORT type;
166  ipic->get_Type(&type);
167  if (type != PICTYPE_BITMAP)
168  return QPixmap();
169 
170  HBITMAP hbm = 0;
171  ipic->get_Handle((OLE_HANDLE*)&hbm);
172  if (!hbm)
173  return QPixmap();
174 
175  return QPixmap::fromWinHBITMAP(hbm);
176 }
177 
178 static QDateTime DATEToQDateTime(DATE ole)
179 {
180  SYSTEMTIME stime;
181  if (ole >= 949998 || VariantTimeToSystemTime(ole, &stime) == false)
182  return QDateTime();
183 
184  QDate date(stime.wYear, stime.wMonth, stime.wDay);
185  QTime time(stime.wHour, stime.wMinute, stime.wSecond, stime.wMilliseconds);
186  return QDateTime(date, time);
187 }
188 
189 static DATE QDateTimeToDATE(const QDateTime &dt)
190 {
191  if (!dt.isValid() || dt.isNull())
192  return 949998;
193 
194  SYSTEMTIME stime;
195  memset(&stime, 0, sizeof(stime));
196  QDate date = dt.date();
197  QTime time = dt.time();
198  if (date.isValid() && !date.isNull()) {
199  stime.wDay = date.day();
200  stime.wMonth = date.month();
201  stime.wYear = date.year();
202  }
203  if (time.isValid() && !time.isNull()) {
204  stime.wMilliseconds = time.msec();
205  stime.wSecond = time.second();
206  stime.wMinute = time.minute();
207  stime.wHour = time.hour();
208  }
209 
210  double vtime;
211  SystemTimeToVariantTime(&stime, &vtime);
212 
213  return vtime;
214 }
215 
217 {
218 #if defined(Q_OS_WINCE)
219  return QColor(GetBValue(col),GetGValue(col),GetRValue(col));
220 #else
221  COLORREF cref;
222  OleTranslateColor(col, QColormap::hPal(), &cref);
223  return QColor(GetRValue(cref),GetGValue(cref),GetBValue(cref));
224 #endif
225 }
226 
227 /*
228  Converts \a var to \a arg, and tries to coerce \a arg to \a type.
229 
230  Used by
231 
232  QAxServerBase:
233  - QAxServerBase::qt_metacall
234  - IDispatch::Invoke(PROPERTYGET, METHOD)
235  - IPersistPropertyBag::Save
236 
237  QAxBase:
238  - IDispatch::Invoke (QAxEventSink)
239  - QAxBase::internalProperty(WriteProperty)
240  - QAxBase::internalInvoke()
241  - QAxBase::dynamicCallHelper()
242  - IPropertyBag::Read (QtPropertyBag)
243 
244  Also called recoursively for lists.
245 */
246 bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out)
247 {
248  QVariant qvar = var;
249  // "type" is the expected type, so coerce if necessary
250  QVariant::Type proptype = typeName.isEmpty() ? QVariant::Invalid : QVariant::nameToType(typeName);
251  if (proptype == QVariant::UserType && !typeName.isEmpty()) {
252  if (typeName == "short" || typeName == "char")
253  proptype = QVariant::Int;
254  else if (typeName == "float")
255  proptype = QVariant::Double;
256  }
257  if (proptype != QVariant::Invalid && proptype != QVariant::UserType && proptype != qvar.type()) {
258  if (qvar.canConvert(proptype))
259  qvar.convert(proptype);
260  else
261  qvar = QVariant(proptype);
262  }
263 
264  if (out && arg.vt == (VT_VARIANT|VT_BYREF) && arg.pvarVal) {
265  return QVariantToVARIANT(var, *arg.pvarVal, typeName, false);
266  }
267 
268  if (out && proptype == QVariant::UserType && typeName == "QVariant") {
269  VARIANT *pVariant = new VARIANT;
270  QVariantToVARIANT(var, *pVariant, QByteArray(), false);
271  arg.vt = VT_VARIANT|VT_BYREF;
272  arg.pvarVal = pVariant;
273  return true;
274  }
275 
276  switch ((int)qvar.type()) {
277  case QVariant::String:
278  if (out && arg.vt == (VT_BSTR|VT_BYREF)) {
279  if (*arg.pbstrVal)
280  SysFreeString(*arg.pbstrVal);
281  *arg.pbstrVal = QStringToBSTR(qvar.toString());
282  arg.vt = VT_BSTR|VT_BYREF;
283  } else {
284  arg.vt = VT_BSTR;
285  arg.bstrVal = QStringToBSTR(qvar.toString());
286  if (out) {
287  arg.pbstrVal = new BSTR(arg.bstrVal);
288  arg.vt |= VT_BYREF;
289  }
290  }
291  break;
292 
293  case QVariant::Int:
294  if (out && arg.vt == (VT_I4|VT_BYREF)) {
295  *arg.plVal = qvar.toInt();
296  } else {
297  arg.vt = VT_I4;
298  arg.lVal = qvar.toInt();
299  if (out) {
300  if (typeName == "short") {
301  arg.vt = VT_I2;
302  arg.piVal = new short(arg.lVal);
303  } else if (typeName == "char") {
304  arg.vt = VT_I1;
305  arg.pcVal= new char(arg.lVal);
306  } else {
307  arg.plVal = new long(arg.lVal);
308  }
309  arg.vt |= VT_BYREF;
310  }
311  }
312  break;
313 
314  case QVariant::UInt:
315  if (out && (arg.vt == (VT_UINT|VT_BYREF) || arg.vt == (VT_I4|VT_BYREF))) {
316  *arg.puintVal = qvar.toUInt();
317  } else {
318  arg.vt = VT_UINT;
319  arg.uintVal = qvar.toUInt();
320  if (out) {
321  arg.puintVal = new uint(arg.uintVal);
322  arg.vt |= VT_BYREF;
323  }
324  }
325  break;
326 
327  case QVariant::LongLong:
328  if (out && arg.vt == (VT_CY|VT_BYREF)) {
329  arg.pcyVal->int64 = qvar.toLongLong();
330 #if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
331  } else if (out && arg.vt == (VT_I8|VT_BYREF)) {
332  *arg.pllVal = qvar.toLongLong();
333  } else {
334  arg.vt = VT_I8;
335  arg.llVal = qvar.toLongLong();
336  if (out) {
337  arg.pllVal = new LONGLONG(arg.llVal);
338  arg.vt |= VT_BYREF;
339  }
340  }
341 #else
342  } else {
343  arg.vt = VT_CY;
344  arg.cyVal.int64 = qvar.toLongLong();
345  if (out) {
346  arg.pcyVal = new CY(arg.cyVal);
347  arg.vt |= VT_BYREF;
348  }
349  }
350 #endif
351  break;
352 
353  case QVariant::ULongLong:
354  if (out && arg.vt == (VT_CY|VT_BYREF)) {
355  arg.pcyVal->int64 = qvar.toULongLong();
356 #if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
357  } else if (out && arg.vt == (VT_UI8|VT_BYREF)) {
358  *arg.pullVal = qvar.toULongLong();
359  } else {
360  arg.vt = VT_UI8;
361  arg.ullVal = qvar.toULongLong();
362  if (out) {
363  arg.pullVal = new ULONGLONG(arg.ullVal);
364  arg.vt |= VT_BYREF;
365  }
366  }
367 #else
368  } else {
369  arg.vt = VT_CY;
370  arg.cyVal.int64 = qvar.toULongLong();
371  if (out) {
372  arg.pcyVal = new CY(arg.cyVal);
373  arg.vt |= VT_BYREF;
374  }
375  }
376 
377 #endif
378 
379  break;
380 
381  case QVariant::Bool:
382  if (out && arg.vt == (VT_BOOL|VT_BYREF)) {
383  *arg.pboolVal = qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE;
384  } else {
385  arg.vt = VT_BOOL;
386  arg.boolVal = qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE;
387  if (out) {
388  arg.pboolVal = new short(arg.boolVal);
389  arg.vt |= VT_BYREF;
390  }
391  }
392  break;
393  case QVariant::Double:
394  if (out && arg.vt == (VT_R8|VT_BYREF)) {
395  *arg.pdblVal = qvar.toDouble();
396  } else {
397  arg.vt = VT_R8;
398  arg.dblVal = qvar.toDouble();
399  if (out) {
400  if (typeName == "float") {
401  arg.vt = VT_R4;
402  arg.pfltVal = new float(arg.dblVal);
403  } else {
404  arg.pdblVal = new double(arg.dblVal);
405  }
406  arg.vt |= VT_BYREF;
407  }
408  }
409  break;
410  case QVariant::Color:
411  if (out && arg.vt == (VT_COLOR|VT_BYREF)) {
412 
413  *arg.plVal = QColorToOLEColor(qvariant_cast<QColor>(qvar));
414  } else {
415  arg.vt = VT_COLOR;
416  arg.lVal = QColorToOLEColor(qvariant_cast<QColor>(qvar));
417  if (out) {
418  arg.plVal = new long(arg.lVal);
419  arg.vt |= VT_BYREF;
420  }
421  }
422  break;
423 
424  case QVariant::Date:
425  case QVariant::Time:
426  case QVariant::DateTime:
427  if (out && arg.vt == (VT_DATE|VT_BYREF)) {
428  *arg.pdate = QDateTimeToDATE(qvar.toDateTime());
429  } else {
430  arg.vt = VT_DATE;
431  arg.date = QDateTimeToDATE(qvar.toDateTime());
432  if (out) {
433  arg.pdate = new DATE(arg.date);
434  arg.vt |= VT_BYREF;
435  }
436  }
437  break;
438  case QVariant::Font:
439  if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) {
440  if (*arg.ppdispVal)
441  (*arg.ppdispVal)->Release();
442  *arg.ppdispVal = QFontToIFont(qvariant_cast<QFont>(qvar));
443  } else {
444  arg.vt = VT_DISPATCH;
445  arg.pdispVal = QFontToIFont(qvariant_cast<QFont>(qvar));
446  if (out) {
447  arg.ppdispVal = new IDispatch*(arg.pdispVal);
448  arg.vt |= VT_BYREF;
449  }
450  }
451  break;
452 
453  case QVariant::Pixmap:
454  if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) {
455  if (*arg.ppdispVal)
456  (*arg.ppdispVal)->Release();
457  *arg.ppdispVal = QPixmapToIPicture(qvariant_cast<QPixmap>(qvar));
458  } else {
459  arg.vt = VT_DISPATCH;
460  arg.pdispVal = QPixmapToIPicture(qvariant_cast<QPixmap>(qvar));
461  if (out) {
462  arg.ppdispVal = new IDispatch*(arg.pdispVal);
463  arg.vt |= VT_BYREF;
464  }
465  }
466  break;
467 
468  case QVariant::Cursor:
469  {
470 #ifndef QT_NO_CURSOR
471  int shape = qvariant_cast<QCursor>(qvar).shape();
472  if (out && (arg.vt & VT_BYREF)) {
473  switch(arg.vt & ~VT_BYREF) {
474  case VT_I4:
475  *arg.plVal = shape;
476  break;
477  case VT_I2:
478  *arg.piVal = shape;
479  break;
480  case VT_UI4:
481  *arg.pulVal = shape;
482  break;
483  case VT_UI2:
484  *arg.puiVal = shape;
485  break;
486  case VT_INT:
487  *arg.pintVal = shape;
488  break;
489  case VT_UINT:
490  *arg.puintVal = shape;
491  break;
492  }
493  } else {
494  arg.vt = VT_I4;
495  arg.lVal = shape;
496  if (out) {
497  arg.plVal = new long(arg.lVal);
498  arg.vt |= VT_BYREF;
499  }
500  }
501 #endif
502  }
503  break;
504 
505  case QVariant::List:
506  {
507  const QList<QVariant> list = qvar.toList();
508  const int count = list.count();
509  VARTYPE vt = VT_VARIANT;
510  QVariant::Type listType = QVariant::LastType; // == QVariant
511  if (!typeName.isEmpty() && typeName.startsWith("QList<")) {
512  const QByteArray listTypeName = typeName.mid(6, typeName.length() - 7); // QList<int> -> int
513  listType = QVariant::nameToType(listTypeName);
514  }
515 
516  VARIANT variant;
517  void *pElement = &variant;
518  switch(listType) {
519  case QVariant::Int:
520  vt = VT_I4;
521  pElement = &variant.lVal;
522  break;
523  case QVariant::Double:
524  vt = VT_R8;
525  pElement = &variant.dblVal;
526  break;
527  case QVariant::DateTime:
528  vt = VT_DATE;
529  pElement = &variant.date;
530  break;
531  case QVariant::Bool:
532  vt = VT_BOOL;
533  pElement = &variant.boolVal;
534  break;
535  case QVariant::LongLong:
536 #if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
537  vt = VT_I8;
538  pElement = &variant.llVal;
539 #else
540  vt = VT_CY;
541  pElement = &variant.cyVal;
542 #endif
543  break;
544  default:
545  break;
546  }
547  SAFEARRAY *array = 0;
548  bool is2D = false;
549  // If the first element in the array is a list the whole list is
550  // treated as a 2D array. The column count is taken from the 1st element.
551  if (count) {
552  QVariantList col = list.at(0).toList();
553  int maxColumns = col.count();
554  if (maxColumns) {
555  is2D = true;
556  SAFEARRAYBOUND rgsabound[2] = { {0} };
557  rgsabound[0].cElements = count;
558  rgsabound[1].cElements = maxColumns;
559  array = SafeArrayCreate(VT_VARIANT, 2, rgsabound);
560  LONG rgIndices[2];
561  for (LONG i = 0; i < count; ++i) {
562  rgIndices[0] = i;
563  QVariantList columns = list.at(i).toList();
564  int columnCount = qMin(maxColumns, columns.count());
565  for (LONG j = 0; j < columnCount; ++j) {
566  QVariant elem = columns.at(j);
567  VariantInit(&variant);
568  QVariantToVARIANT(elem, variant, elem.typeName());
569  rgIndices[1] = j;
570  SafeArrayPutElement(array, rgIndices, pElement);
571  clearVARIANT(&variant);
572  }
573  }
574 
575  }
576  }
577  if (!is2D) {
578  array = SafeArrayCreateVector(vt, 0, count);
579  for (LONG index = 0; index < count; ++index) {
580  QVariant elem = list.at(index);
581  if (listType != QVariant::LastType)
582  elem.convert(listType);
583  VariantInit(&variant);
584  QVariantToVARIANT(elem, variant, elem.typeName());
585  SafeArrayPutElement(array, &index, pElement);
586  clearVARIANT(&variant);
587  }
588  }
589  if (out && arg.vt == (VT_ARRAY|vt|VT_BYREF)) {
590  if (*arg.pparray)
591  SafeArrayDestroy(*arg.pparray);
592  *arg.pparray = array;
593  } else {
594  arg.vt = VT_ARRAY|vt;
595  arg.parray = array;
596  if (out) {
597  arg.pparray = new SAFEARRAY*(arg.parray);
598  arg.vt |= VT_BYREF;
599  }
600  }
601  }
602  break;
603 
605  {
606  const QStringList list = qvar.toStringList();
607  const int count = list.count();
608  SAFEARRAY *array = SafeArrayCreateVector(VT_BSTR, 0, count);
609  for (LONG index = 0; index < count; ++index) {
610  QString elem = list.at(index);
611  BSTR bstr = QStringToBSTR(elem);
612  SafeArrayPutElement(array, &index, bstr);
613  SysFreeString(bstr);
614  }
615 
616  if (out && arg.vt == (VT_ARRAY|VT_BSTR|VT_BYREF)) {
617  if (*arg.pparray)
618  SafeArrayDestroy(*arg.pparray);
619  *arg.pparray = array;
620  } else {
621  arg.vt = VT_ARRAY|VT_BSTR;
622  arg.parray = array;
623  if (out) {
624  arg.pparray = new SAFEARRAY*(arg.parray);
625  arg.vt |= VT_BYREF;
626  }
627  }
628  }
629  break;
630 
631  case QVariant::ByteArray:
632  {
633  const QByteArray bytes = qvar.toByteArray();
634  const uint count = bytes.count();
635  SAFEARRAY *array = SafeArrayCreateVector(VT_UI1, 0, count);
636  if (count) {
637  const char *data = bytes.constData();
638  char *dest;
639  SafeArrayAccessData(array, (void **)&dest);
640  memcpy(dest, data, count);
641  SafeArrayUnaccessData(array);
642  }
643 
644  if (out && arg.vt == (VT_ARRAY|VT_UI1|VT_BYREF)) {
645  if (*arg.pparray)
646  SafeArrayDestroy(*arg.pparray);
647  *arg.pparray = array;
648  } else {
649  arg.vt = VT_ARRAY|VT_UI1;
650  arg.parray = array;
651  if (out) {
652  arg.pparray = new SAFEARRAY*(arg.parray);
653  arg.vt |= VT_BYREF;
654  }
655  }
656  }
657  break;
658 
659 #ifdef QAX_SERVER
660  case QVariant::Rect:
661  case QVariant::Size:
662  case QVariant::Point:
663  {
664  typedef HRESULT(WINAPI* PGetRecordInfoFromTypeInfo)(ITypeInfo *, IRecordInfo **);
665  static PGetRecordInfoFromTypeInfo pGetRecordInfoFromTypeInfo = 0;
666  static bool resolved = false;
667  if (!resolved) {
668  QSystemLibrary oleaut32(QLatin1String("oleaut32"));
669  pGetRecordInfoFromTypeInfo = (PGetRecordInfoFromTypeInfo)oleaut32.resolve("GetRecordInfoFromTypeInfo");
670  resolved = true;
671  }
672  if (!pGetRecordInfoFromTypeInfo)
673  break;
674 
675  ITypeInfo *typeInfo = 0;
676  IRecordInfo *recordInfo = 0;
677  CLSID clsid = qvar.type() == QVariant::Rect ? CLSID_QRect
678  :qvar.type() == QVariant::Size ? CLSID_QSize
679  :CLSID_QPoint;
680  qAxTypeLibrary->GetTypeInfoOfGuid(clsid, &typeInfo);
681  if (!typeInfo)
682  break;
683  pGetRecordInfoFromTypeInfo(typeInfo, &recordInfo);
684  typeInfo->Release();
685  if (!recordInfo)
686  break;
687 
688  void *record = 0;
689  switch (qvar.type()) {
690  case QVariant::Rect:
691  {
692  QRect qrect(qvar.toRect());
693  recordInfo->RecordCreateCopy(&qrect, &record);
694  }
695  break;
696  case QVariant::Size:
697  {
698  QSize qsize(qvar.toSize());
699  recordInfo->RecordCreateCopy(&qsize, &record);
700  }
701  break;
702  case QVariant::Point:
703  {
704  QPoint qpoint(qvar.toPoint());
705  recordInfo->RecordCreateCopy(&qpoint, &record);
706  }
707  break;
708  }
709 
710  arg.vt = VT_RECORD;
711  arg.pRecInfo = recordInfo,
712  arg.pvRecord = record;
713  if (out) {
714  qWarning("QVariantToVARIANT: out-parameter not supported for records");
715  return false;
716  }
717  }
718  break;
719 #endif // QAX_SERVER
720  case QVariant::UserType:
721  {
722  QByteArray subType = qvar.typeName();
723 #ifdef QAX_SERVER
724  if (subType.endsWith('*'))
725  subType.truncate(subType.length() - 1);
726 #endif
727  if (!qstrcmp(qvar.typeName(), "IDispatch*")) {
728  arg.vt = VT_DISPATCH;
729  arg.pdispVal = *(IDispatch**)qvar.data();
730  if (arg.pdispVal)
731  arg.pdispVal->AddRef();
732  if (out) {
733  qWarning("QVariantToVARIANT: out-parameter not supported for IDispatch");
734  return false;
735  }
736  } else if (!qstrcmp(qvar.typeName(), "IDispatch**")) {
737  arg.vt = VT_DISPATCH;
738  arg.ppdispVal = *(IDispatch***)qvar.data();
739  if (out)
740  arg.vt |= VT_BYREF;
741  } else if (!qstrcmp(qvar.typeName(), "IUnknown*")) {
742  arg.vt = VT_UNKNOWN;
743  arg.punkVal = *(IUnknown**)qvar.data();
744  if (arg.punkVal)
745  arg.punkVal->AddRef();
746  if (out) {
747  qWarning("QVariantToVARIANT: out-parameter not supported for IUnknown");
748  return false;
749  }
750 #ifdef QAX_SERVER
751  } else if (qAxFactory()->metaObject(QString::fromLatin1(subType.constData()))) {
752  arg.vt = VT_DISPATCH;
753  void *user = *(void**)qvar.constData();
754 // qVariantGet(qvar, user, qvar.typeName());
755  if (!user) {
756  arg.pdispVal = 0;
757  } else {
758  qAxFactory()->createObjectWrapper(static_cast<QObject*>(user), &arg.pdispVal);
759  }
760  if (out) {
761  qWarning("QVariantToVARIANT: out-parameter not supported for subtype");
762  return false;
763  }
764 #else
765  } else if (QMetaType::type(subType)) {
766  QAxObject *object = *(QAxObject**)qvar.constData();
767 // qVariantGet(qvar, object, subType);
768  arg.vt = VT_DISPATCH;
769  object->queryInterface(IID_IDispatch, (void**)&arg.pdispVal);
770  if (out) {
771  qWarning("QVariantToVARIANT: out-parameter not supported for subtype");
772  return false;
773  }
774 #endif
775  } else {
776  return false;
777  }
778  }
779  break;
780  case QVariant::Invalid: // default-parameters not set
781  if (out && arg.vt == (VT_ERROR|VT_BYREF)) {
782  *arg.plVal = DISP_E_PARAMNOTFOUND;
783  } else {
784  arg.vt = VT_ERROR;
785  arg.lVal = DISP_E_PARAMNOTFOUND;
786  if (out) {
787  arg.plVal = new long(arg.lVal);
788  arg.vt |= VT_BYREF;
789  }
790  }
791  break;
792 
793  default:
794  return false;
795  }
796 
797  Q_ASSERT(!out || (arg.vt & VT_BYREF));
798  return true;
799 }
800 
814 bool QVariantToVoidStar(const QVariant &var, void *data, const QByteArray &typeName, uint type)
815 {
816  if (!data)
817  return true;
818 
819  if (type == QVariant::LastType || (type == 0 && typeName == "QVariant")) {
820  *(QVariant*)data = var;
821  return true;
822  }
823 
824  switch (var.type()) {
825  case QVariant::Invalid:
826  break;
827  case QVariant::String:
828  *(QString*)data = var.toString();
829  break;
830  case QVariant::Int:
831  *(int*)data = var.toInt();
832  break;
833  case QVariant::UInt:
834  *(uint*)data = var.toUInt();
835  break;
836  case QVariant::Bool:
837  *(bool*)data = var.toBool();
838  break;
839  case QVariant::Double:
840  *(double*)data = var.toDouble();
841  break;
842  case QVariant::Color:
843  *(QColor*)data = qvariant_cast<QColor>(var);
844  break;
845  case QVariant::Date:
846  *(QDate*)data = var.toDate();
847  break;
848  case QVariant::Time:
849  *(QTime*)data = var.toTime();
850  break;
851  case QVariant::DateTime:
852  *(QDateTime*)data = var.toDateTime();
853  break;
854  case QVariant::Font:
855  *(QFont*)data = qvariant_cast<QFont>(var);
856  break;
857  case QVariant::Pixmap:
858  *(QPixmap*)data = qvariant_cast<QPixmap>(var);
859  break;
860 #ifndef QT_NO_CURSOR
861  case QVariant::Cursor:
862  *(QCursor*)data = qvariant_cast<QCursor>(var);
863  break;
864 #endif
865  case QVariant::List:
866  *(QList<QVariant>*)data = var.toList();
867  break;
869  *(QStringList*)data = var.toStringList();
870  break;
871  case QVariant::ByteArray:
872  *(QByteArray*)data = var.toByteArray();
873  break;
874  case QVariant::LongLong:
875  *(qint64*)data = var.toLongLong();
876  break;
877  case QVariant::ULongLong:
878  *(quint64*)data = var.toULongLong();
879  break;
880  case QVariant::Rect:
881  *(QRect*)data = var.toRect();
882  break;
883  case QVariant::Size:
884  *(QSize*)data = var.toSize();
885  break;
886  case QVariant::Point:
887  *(QPoint*)data = var.toPoint();
888  break;
889  case QVariant::UserType:
890  *(void**)data = *(void**)var.constData();
891 // qVariantGet(var, *(void**)data, typeName);
892  break;
893  default:
894  qWarning("QVariantToVoidStar: Unhandled QVariant type");
895  return false;
896  }
897 
898  return true;
899 }
900 
920 {
921  QVariant var;
922  switch(arg.vt) {
923  case VT_BSTR:
924  var = QString::fromWCharArray(arg.bstrVal);
925  break;
926  case VT_BSTR|VT_BYREF:
927  var = QString::fromWCharArray(*arg.pbstrVal);
928  break;
929  case VT_BOOL:
930  var = QVariant((bool)arg.boolVal);
931  break;
932  case VT_BOOL|VT_BYREF:
933  var = QVariant((bool)*arg.pboolVal);
934  break;
935  case VT_I1:
936  var = arg.cVal;
937  if (typeName == "char")
938  type = QVariant::Int;
939  break;
940  case VT_I1|VT_BYREF:
941  var = *arg.pcVal;
942  if (typeName == "char")
943  type = QVariant::Int;
944  break;
945  case VT_I2:
946  var = arg.iVal;
947  if (typeName == "short")
948  type = QVariant::Int;
949  break;
950  case VT_I2|VT_BYREF:
951  var = *arg.piVal;
952  if (typeName == "short")
953  type = QVariant::Int;
954  break;
955  case VT_I4:
956  if (type == QVariant::Color || (!type && typeName == "QColor"))
957  var = QVariant::fromValue(OLEColorToQColor(arg.lVal));
958 #ifndef QT_NO_CURSOR
959  else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
960  var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(arg.lVal)));
961 #endif
962  else
963  var = (int)arg.lVal;
964  break;
965  case VT_I4|VT_BYREF:
966  if (type == QVariant::Color || (!type && typeName == "QColor"))
967  var = QVariant::fromValue(OLEColorToQColor((int)*arg.plVal));
968 #ifndef QT_NO_CURSOR
969  else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
970  var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(*arg.plVal)));
971 #endif
972  else
973  var = (int)*arg.plVal;
974  break;
975  case VT_INT:
976  var = arg.intVal;
977  break;
978  case VT_INT|VT_BYREF:
979  var = *arg.pintVal;
980  break;
981  case VT_UI1:
982  var = arg.bVal;
983  break;
984  case VT_UI1|VT_BYREF:
985  var = *arg.pbVal;
986  break;
987  case VT_UI2:
988  var = arg.uiVal;
989  break;
990  case VT_UI2|VT_BYREF:
991  var = *arg.puiVal;
992  break;
993  case VT_UI4:
994  if (type == QVariant::Color || (!type && typeName == "QColor"))
995  var = QVariant::fromValue(OLEColorToQColor(arg.ulVal));
996 #ifndef QT_NO_CURSOR
997  else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
998  var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(arg.ulVal)));
999 #endif
1000  else
1001  var = (int)arg.ulVal;
1002  break;
1003  case VT_UI4|VT_BYREF:
1004  if (type == QVariant::Color || (!type && typeName == "QColor"))
1005  var = QVariant::fromValue(OLEColorToQColor((uint)*arg.pulVal));
1006 #ifndef QT_NO_CURSOR
1007  else if (type == QVariant::Cursor || (!type && (typeName == "QCursor" || typeName == "QCursor*")))
1008  var = QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(*arg.pulVal)));
1009 #endif
1010  else
1011  var = (int)*arg.pulVal;
1012  break;
1013  case VT_UINT:
1014  var = arg.uintVal;
1015  break;
1016  case VT_UINT|VT_BYREF:
1017  var = *arg.puintVal;
1018  break;
1019  case VT_CY:
1020  var = arg.cyVal.int64;
1021  break;
1022  case VT_CY|VT_BYREF:
1023  var = arg.pcyVal->int64;
1024  break;
1025 #if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
1026  case VT_I8:
1027  var = arg.llVal;
1028  break;
1029  case VT_I8|VT_BYREF:
1030  var = *arg.pllVal;
1031  break;
1032  case VT_UI8:
1033  var = arg.ullVal;
1034  break;
1035  case VT_UI8|VT_BYREF:
1036  var = *arg.pullVal;
1037  break;
1038 #endif
1039  case VT_R4:
1040  var = arg.fltVal;
1041  break;
1042  case VT_R4|VT_BYREF:
1043  var = *arg.pfltVal;
1044  break;
1045  case VT_R8:
1046  var = arg.dblVal;
1047  break;
1048  case VT_R8|VT_BYREF:
1049  var = *arg.pdblVal;
1050  break;
1051  case VT_DATE:
1052  var = DATEToQDateTime(arg.date);
1053  if (type == QVariant::Date || (!type && (typeName == "QDate" || typeName == "QDate*"))) {
1054  var.convert(QVariant::Date);
1055  } else if (type == QVariant::Time || (!type && (typeName == "QTime" || typeName == "QTime*"))) {
1056  var.convert(QVariant::Time);
1057  }
1058  break;
1059  case VT_DATE|VT_BYREF:
1060  var = DATEToQDateTime(*arg.pdate);
1061  if (type == QVariant::Date || (!type && (typeName == "QDate" || typeName == "QDate*"))) {
1062  var.convert(QVariant::Date);
1063  } else if (type == QVariant::Time || (!type && (typeName == "QTime" || typeName == "QTime*"))) {
1064  var.convert(QVariant::Time);
1065  }
1066  break;
1067  case VT_VARIANT:
1068  case VT_VARIANT|VT_BYREF:
1069  if (arg.pvarVal)
1070  var = VARIANTToQVariant(*arg.pvarVal, typeName);
1071  break;
1072 
1073  case VT_DISPATCH:
1074  case VT_DISPATCH|VT_BYREF:
1075  {
1076  // pdispVal and ppdispVal are a union
1077  IDispatch *disp = 0;
1078  if (arg.vt & VT_BYREF)
1079  disp = *arg.ppdispVal;
1080  else
1081  disp = arg.pdispVal;
1082  if (type == QVariant::Font || (!type && (typeName == "QFont" || typeName == "QFont*"))) {
1083  IFont *ifont = 0;
1084  if (disp)
1085  disp->QueryInterface(IID_IFont, (void**)&ifont);
1086  if (ifont) {
1087  var = QVariant::fromValue(IFontToQFont(ifont));
1088  ifont->Release();
1089  } else {
1090  var = QVariant::fromValue(QFont());
1091  }
1092  } else if (type == QVariant::Pixmap || (!type && (typeName == "QPixmap" || typeName == "QPixmap*"))) {
1093  IPicture *ipic = 0;
1094  if (disp)
1095  disp->QueryInterface(IID_IPicture, (void**)&ipic);
1096  if (ipic) {
1098  ipic->Release();
1099  } else {
1100  var = QVariant::fromValue(QPixmap());
1101  }
1102  } else {
1103 #ifdef QAX_SERVER
1104  IAxServerBase *iface = 0;
1105  if (disp && typeName != "IDispatch*")
1106  disp->QueryInterface(IID_IAxServerBase, (void**)&iface);
1107  if (iface) {
1108  QObject *qObj = iface->qObject();
1109  iface->Release();
1110  var = QVariant(qRegisterMetaType<QObject*>(qObj ? QByteArray(qObj->metaObject()->className()) + '*' : typeName), &qObj);
1111  } else
1112 #endif
1113  {
1114  if (!typeName.isEmpty()) {
1115  if (arg.vt & VT_BYREF) {
1116  var = QVariant(qRegisterMetaType<IDispatch**>("IDispatch**"), &arg.ppdispVal);
1117  } else {
1118 #ifndef QAX_SERVER
1119  if (typeName == "QVariant") {
1120  QAxObject *object = new QAxObject(disp);
1121  var = QVariant::fromValue<QAxObject*>(object);
1122  } else if (typeName != "IDispatch*" && QMetaType::type(typeName)) {
1123  QByteArray typeNameStr = QByteArray(typeName);
1124  int pIndex = typeName.lastIndexOf('*');
1125  if (pIndex != -1)
1126  typeNameStr = typeName.left(pIndex);
1127  int metaType = QMetaType::type(typeNameStr);
1128  Q_ASSERT(metaType != 0);
1129  QAxObject *object = (QAxObject*)qax_createObjectWrapper(metaType, disp);
1130  var = QVariant(QMetaType::type(typeName), &object);
1131  } else
1132 #endif
1133  var = QVariant(qRegisterMetaType<IDispatch*>(typeName), &disp);
1134  }
1135  }
1136  }
1137  }
1138  }
1139  break;
1140  case VT_UNKNOWN:
1141  case VT_UNKNOWN|VT_BYREF:
1142  {
1143  IUnknown *unkn = 0;
1144  if (arg.vt & VT_BYREF)
1145  unkn = *arg.ppunkVal;
1146  else
1147  unkn = arg.punkVal;
1148  var.setValue(unkn);
1149  }
1150  break;
1151  case VT_ARRAY|VT_VARIANT:
1152  case VT_ARRAY|VT_VARIANT|VT_BYREF:
1153  {
1154  SAFEARRAY *array = 0;
1155  if ( arg.vt & VT_BYREF )
1156  array = *arg.pparray;
1157  else
1158  array = arg.parray;
1159 
1160  UINT cDims = array ? SafeArrayGetDim(array) : 0;
1161  switch(cDims) {
1162  case 1:
1163  {
1164  QVariantList list;
1165 
1166  long lBound, uBound;
1167  SafeArrayGetLBound( array, 1, &lBound );
1168  SafeArrayGetUBound( array, 1, &uBound );
1169 
1170  for ( long i = lBound; i <= uBound; ++i ) {
1171  VARIANT var;
1172  VariantInit( &var );
1173  SafeArrayGetElement( array, &i, &var );
1174 
1175  QVariant qvar = VARIANTToQVariant( var, 0 );
1176  clearVARIANT( &var );
1177  list << qvar;
1178  }
1179 
1180  var = list;
1181  }
1182  break;
1183 
1184  case 2:
1185  {
1186  QVariantList listList; // a list of lists
1187  long dimIndices[2];
1188 
1189  long xlBound, xuBound, ylBound, yuBound;
1190  SafeArrayGetLBound(array, 1, &xlBound);
1191  SafeArrayGetUBound(array, 1, &xuBound);
1192  SafeArrayGetLBound(array, 2, &ylBound);
1193  SafeArrayGetUBound(array, 2, &yuBound);
1194 
1195  for (long x = xlBound; x <= xuBound; ++x) {
1196  QVariantList list;
1197 
1198  dimIndices[0] = x;
1199  for (long y = ylBound; y <= yuBound; ++y) {
1200  VARIANT var;
1201  VariantInit(&var);
1202  dimIndices[1] = y;
1203  SafeArrayGetElement(array, dimIndices, &var);
1204 
1205  QVariant qvar = VARIANTToQVariant(var, 0);
1206  clearVARIANT(&var);
1207  list << qvar;
1208  }
1209 
1210  listList << QVariant(list);
1211  }
1212  var = listList;
1213  }
1214  break;
1215  default:
1216  var = QVariantList();
1217  break;
1218  }
1219  }
1220  break;
1221 
1222  case VT_ARRAY|VT_BSTR:
1223  case VT_ARRAY|VT_BSTR|VT_BYREF:
1224  {
1225  SAFEARRAY *array = 0;
1226  if (arg.vt & VT_BYREF)
1227  array = *arg.pparray;
1228  else
1229  array = arg.parray;
1230 
1231  QStringList strings;
1232  if (!array || array->cDims != 1) {
1233  var = strings;
1234  break;
1235  }
1236 
1237  long lBound, uBound;
1238  SafeArrayGetLBound(array, 1, &lBound);
1239  SafeArrayGetUBound(array, 1, &uBound);
1240 
1241  for (long i = lBound; i <= uBound; ++i) {
1242  BSTR bstr;
1243  SafeArrayGetElement(array, &i, &bstr);
1244  strings << QString::fromWCharArray(bstr);
1245  SysFreeString(bstr);
1246  }
1247 
1248  var = strings;
1249  }
1250  break;
1251 
1252  case VT_ARRAY|VT_UI1:
1253  case VT_ARRAY|VT_UI1|VT_BYREF:
1254  {
1255  SAFEARRAY *array = 0;
1256  if (arg.vt & VT_BYREF)
1257  array = *arg.pparray;
1258  else
1259  array = arg.parray;
1260 
1261  QByteArray bytes;
1262  if (!array || array->cDims != 1) {
1263  var = bytes;
1264  break;
1265  }
1266 
1267  long lBound, uBound;
1268  SafeArrayGetLBound(array, 1, &lBound);
1269  SafeArrayGetUBound(array, 1, &uBound);
1270 
1271  if (uBound != -1) { // non-empty array
1272  bytes.resize(uBound - lBound + 1);
1273  char *data = bytes.data();
1274  char *src;
1275  SafeArrayAccessData(array, (void**)&src);
1276  memcpy(data, src, bytes.size());
1277  SafeArrayUnaccessData(array);
1278  }
1279 
1280  var = bytes;
1281  }
1282  break;
1283 
1284 #if defined(QAX_SERVER)
1285  case VT_RECORD:
1286  case VT_RECORD|VT_BYREF:
1287  if (arg.pvRecord && arg.pRecInfo) {
1288  IRecordInfo *recordInfo = arg.pRecInfo;
1289  void *record = arg.pvRecord;
1290  GUID guid;
1291  recordInfo->GetGuid(&guid);
1292 
1293  if (guid == CLSID_QRect) {
1294  QRect qrect;
1295  recordInfo->RecordCopy(record, &qrect);
1296  var = qrect;
1297  } else if (guid == CLSID_QSize) {
1298  QSize qsize;
1299  recordInfo->RecordCopy(record, &qsize);
1300  var = qsize;
1301  } else if (guid == CLSID_QPoint) {
1302  QPoint qpoint;
1303  recordInfo->RecordCopy(record, &qpoint);
1304  var = qpoint;
1305  }
1306  }
1307  break;
1308 #endif // QAX_SERVER
1309  default:
1310 #if !defined(Q_OS_WINCE)
1311  // support for any SAFEARRAY(Type) where Type can be converted to a QVariant
1312  // -> QVariantList
1313  if (arg.vt & VT_ARRAY) {
1314  SAFEARRAY *array = 0;
1315  if (arg.vt & VT_BYREF)
1316  array = *arg.pparray;
1317  else
1318  array = arg.parray;
1319 
1320  QVariantList list;
1321  if (!array || array->cDims != 1) {
1322  var = list;
1323  break;
1324  }
1325 
1326  // find out where to store the element
1327  VARTYPE vt;
1328  VARIANT variant;
1329  SafeArrayGetVartype(array, &vt);
1330 
1331  void *pElement = 0;
1332  switch(vt) {
1333  case VT_BSTR: Q_ASSERT(false); break; // already covered
1334  case VT_BOOL: pElement = &variant.boolVal; break;
1335  case VT_I1: pElement = &variant.cVal; break;
1336  case VT_I2: pElement = &variant.iVal; break;
1337  case VT_I4: pElement = &variant.lVal; break;
1338 #if defined(_MSC_VER) && _MSC_VER >= 1400
1339  case VT_I8: pElement = &variant.llVal; break;
1340  case VT_UI8: pElement = &variant.ullVal; break;
1341 #endif
1342  case VT_INT: pElement = &variant.intVal; break;
1343  case VT_UI1: Q_ASSERT(false); break; // already covered
1344  case VT_UI2: pElement = &variant.uiVal; break;
1345  case VT_UI4: pElement = &variant.ulVal; break;
1346  case VT_UINT: pElement = &variant.uintVal; break;
1347  case VT_CY: pElement = &variant.cyVal; break;
1348  case VT_R4: pElement = &variant.fltVal; break;
1349  case VT_R8: pElement = &variant.dblVal; break;
1350  case VT_DATE: pElement = &variant.date; break;
1351  case VT_VARIANT: Q_ASSERT(false); break; // already covered
1352  default:
1353  break;
1354  }
1355  if (!pElement) {
1356  var = list;
1357  break;
1358  }
1359 
1360  long lBound, uBound;
1361  SafeArrayGetLBound( array, 1, &lBound );
1362  SafeArrayGetUBound( array, 1, &uBound );
1363 
1364  for ( long i = lBound; i <= uBound; ++i ) {
1365  variant.vt = vt;
1366  SafeArrayGetElement(array, &i, pElement);
1367  QVariant qvar = VARIANTToQVariant(variant, 0);
1368  clearVARIANT(&variant);
1369  list << qvar;
1370  }
1371 
1372  var = list;
1373  }
1374 #endif
1375  break;
1376  }
1377 
1378  QVariant::Type proptype = (QVariant::Type)type;
1379  if (proptype == QVariant::Invalid && !typeName.isEmpty()) {
1380  if (typeName != "QVariant")
1381  proptype = QVariant::nameToType(typeName);
1382  }
1383  if (proptype != QVariant::LastType && proptype != QVariant::Invalid && var.type() != proptype) {
1384  if (var.canConvert(proptype)) {
1385  QVariant oldvar = var;
1386  if (oldvar.convert(proptype))
1387  var = oldvar;
1388  } else if (proptype == QVariant::StringList && var.type() == QVariant::List) {
1389  bool allStrings = true;
1390  QStringList strings;
1391  const QList<QVariant> list(var.toList());
1392  for (QList<QVariant>::ConstIterator it(list.begin()); it != list.end(); ++it) {
1393  QVariant variant = *it;
1394  if (variant.canConvert(QVariant::String))
1395  strings << variant.toString();
1396  else
1397  allStrings = false;
1398  }
1399  if (allStrings)
1400  var = strings;
1401  } else {
1402  var = QVariant();
1403  }
1404  }
1405  return var;
1406 }
1407 
1408 void clearVARIANT(VARIANT *var)
1409 {
1410  if (var->vt & VT_BYREF) {
1411  switch(var->vt) {
1412  case VT_BSTR|VT_BYREF:
1413  SysFreeString(*var->pbstrVal);
1414  delete var->pbstrVal;
1415  break;
1416  case VT_BOOL|VT_BYREF:
1417  delete var->pboolVal;
1418  break;
1419  case VT_I1|VT_BYREF:
1420  delete var->pcVal;
1421  break;
1422  case VT_I2|VT_BYREF:
1423  delete var->piVal;
1424  break;
1425  case VT_I4|VT_BYREF:
1426  delete var->plVal;
1427  break;
1428  case VT_INT|VT_BYREF:
1429  delete var->pintVal;
1430  break;
1431  case VT_UI1|VT_BYREF:
1432  delete var->pbVal;
1433  break;
1434  case VT_UI2|VT_BYREF:
1435  delete var->puiVal;
1436  break;
1437  case VT_UI4|VT_BYREF:
1438  delete var->pulVal;
1439  break;
1440  case VT_UINT|VT_BYREF:
1441  delete var->puintVal;
1442  break;
1443 #if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
1444  case VT_I8|VT_BYREF:
1445  delete var->pllVal;
1446  break;
1447  case VT_UI8|VT_BYREF:
1448  delete var->pullVal;
1449  break;
1450 #endif
1451  case VT_CY|VT_BYREF:
1452  delete var->pcyVal;
1453  break;
1454  case VT_R4|VT_BYREF:
1455  delete var->pfltVal;
1456  break;
1457  case VT_R8|VT_BYREF:
1458  delete var->pdblVal;
1459  break;
1460  case VT_DATE|VT_BYREF:
1461  delete var->pdate;
1462  break;
1463  case VT_DISPATCH|VT_BYREF:
1464  (*var->ppdispVal)->Release();
1465  delete var->ppdispVal;
1466  break;
1467  case VT_ARRAY|VT_VARIANT|VT_BYREF:
1468  case VT_ARRAY|VT_UI1|VT_BYREF:
1469  case VT_ARRAY|VT_BSTR|VT_BYREF:
1470  SafeArrayDestroy(*var->pparray);
1471  delete var->pparray;
1472  break;
1473  case VT_VARIANT|VT_BYREF:
1474  delete var->pvarVal;
1475  break;
1476  }
1477  VariantInit(var);
1478  } else {
1479  VariantClear(var);
1480  }
1481 }
1482 
1484 #endif // QT_NO_WIN_ACTIVEQT
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static QString fromWCharArray(const wchar_t *, int size=-1)
Returns a copy of the string, where the encoding of string depends on the size of wchar...
Definition: qstring.cpp:1019
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
void clearVARIANT(VARIANT *var)
Definition: qaxtypes.cpp:1408
int type
Definition: qmetatype.cpp:239
bool isNull() const
Returns true if both the date and the time are null; otherwise returns false.
Definition: qdatetime.cpp:2334
void truncate(int pos)
Truncates the byte array at index position pos.
The QCursor class provides a mouse cursor with an arbitrary shape.
Definition: qcursor.h:89
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
bool isNull() const
Returns true if the date is null; otherwise returns false.
Definition: qdatetime.h:66
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
Definition: quuid.h:52
bool isValid() const
Returns true if this date is valid; otherwise returns false.
Definition: qdatetime.cpp:340
QAxFactory * qAxFactory()
Definition: qaxserver.cpp:81
#define it(className, varName)
bool underline() const
Returns true if underline has been set; otherwise returns false.
Definition: qfont.cpp:1320
void setUnderline(bool)
If enable is true, sets underline on; otherwise sets underline off.
Definition: qfont.cpp:1331
bool isNull() const
Returns true if the time is null (i.
Definition: qdatetime.h:158
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static HPALETTE hPal()
int month() const
Returns the number corresponding to the month of this date, using the following convention: ...
Definition: qdatetime.cpp:382
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
static QPixmap fromWinHBITMAP(HBITMAP hbitmap, HBitmapFormat format=NoAlpha)
Win32 only: Returns a QPixmap that is equivalent to the given bitmap.
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has type() DateTime , Date , or String ; otherwise ...
Definition: qvariant.cpp:2349
static QFont IFontToQFont(IFont *f)
Definition: qaxtypes.cpp:104
int day() const
Returns the day of the month (1 to 31) of this date.
Definition: qdatetime.cpp:395
QList< QVariant > toList() const
Returns the variant as a QVariantList if the variant has type() List or StringList ; otherwise return...
Definition: qvariant.cpp:2751
bool isValid() const
Returns true if both the date and the time are valid; otherwise returns false.
Definition: qdatetime.cpp:2346
The QDate class provides date functions.
Definition: qdatetime.h:55
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool toBool() const
Returns the variant as a bool if the variant has type() Bool.
Definition: qvariant.cpp:2691
int msec() const
Returns the millisecond part (0 to 999) of the time.
Definition: qdatetime.cpp:1611
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
ITypeLib * qAxTypeLibrary
Definition: qaxserver.cpp:66
The QString class provides a Unicode character string.
Definition: qstring.h:83
int qstrcmp(const char *str1, const char *str2)
A safe strcmp() function.
Definition: qbytearray.cpp:231
QColor OLEColorToQColor(uint col)
Definition: qaxtypes.cpp:216
The QAxObject class provides a QObject that wraps a COM object.
Definition: qaxobject.h:54
void setValue(const T &value)
Stores a copy of value.
Definition: qvariant.h:527
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
static DATE QDateTimeToDATE(const QDateTime &dt)
Definition: qaxtypes.cpp:189
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has type() ByteArray or String (converted using QS...
Definition: qvariant.cpp:2383
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
Definition: qvariant.cpp:2625
QStringList toStringList() const
Returns the variant as a QStringList if the variant has type() StringList, String ...
Definition: qvariant.cpp:2259
The QTime class provides clock time functions.
Definition: qdatetime.h:148
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
CLSID CLSID_QSize
qlonglong toLongLong(bool *ok=0) const
Returns the variant as a long long int if the variant has type() LongLong , Bool , ByteArray , Char , Double , Int , String , UInt , or ULongLong ; otherwise returns 0.
Definition: qvariant.cpp:2659
QObject * object
void setBold(bool)
If enable is true sets the font&#39;s weight to QFont::Bold ; otherwise sets the weight to QFont::Normal...
Definition: qfont.h:352
int lastIndexOf(char c, int from=-1) const
Returns the index position of the last occurrence of character ch in the byte array, searching backward from index position from.
bool canConvert(Type t) const
Returns true if the variant&#39;s type can be cast to the requested type, t.
Definition: qvariant.cpp:2886
static IPictureDisp * QPixmapToIPicture(const QPixmap &pixmap)
Definition: qaxtypes.cpp:131
unsigned __int64 quint64
Definition: qglobal.h:943
const char * typeName
Definition: qmetatype.cpp:239
void setStrikeOut(bool)
If enable is true, sets strikeout on; otherwise sets strikeout off.
Definition: qfont.cpp:1378
const char * name
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out)
Definition: qaxtypes.cpp:246
qulonglong toULongLong(bool *ok=0) const
Returns the variant as as an unsigned long long int if the variant has type() ULongLong ...
Definition: qvariant.cpp:2675
Q_CORE_EXPORT void qWarning(const char *,...)
int second() const
Returns the second part (0 to 59) of the time.
Definition: qdatetime.cpp:1600
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
Type
This enum type defines the types of variable that a QVariant can contain.
Definition: qvariant.h:95
static uint QColorToOLEColor(const QColor &col)
Definition: qaxtypes.h:81
__int64 qint64
Definition: qglobal.h:942
QByteArray left(int len) const
Returns a byte array that contains the leftmost len bytes of this byte array.
int minute() const
Returns the minute part (0 to 59) of the time.
Definition: qdatetime.cpp:1589
static int type(const char *typeName)
Returns a handle to the type called typeName, or 0 if there is no such type.
Definition: qmetatype.cpp:607
virtual bool createObjectWrapper(QObject *object, IDispatch **wrapper)
Reimplement this function to provide the COM object for object in wrapper.
static QVariant fromValue(const T &value)
Returns a QVariant containing a copy of value.
Definition: qvariant.h:336
void * qax_createObjectWrapper(int metaType, IUnknown *iface)
Definition: qaxbase.cpp:4448
const char * typeName() const
Returns the name of the type stored in the variant.
Definition: qvariant.cpp:1984
QSize toSize() const
Returns the variant as a QSize if the variant has type() Size ; otherwise returns an invalid QSize...
Definition: qvariant.cpp:2432
QVariantList
Synonym for QList<QVariant>.
bool convert(Type t)
Casts the variant to the requested type, t.
Definition: qvariant.cpp:2959
int length() const
Same as size().
Definition: qbytearray.h:356
bool QVariantToVoidStar(const QVariant &var, void *data, const QByteArray &typeName, uint type)
Copies the data in var into data.
Definition: qaxtypes.cpp:814
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QDate date() const
Returns the date part of the datetime.
Definition: qdatetime.cpp:2357
QDate toDate() const
Returns the variant as a QDate if the variant has type() Date , DateTime , or String ; otherwise retu...
Definition: qvariant.cpp:2311
long HRESULT
void * resolve(const char *symbol)
The QDateTime class provides date and time functions.
Definition: qdatetime.h:216
HBITMAP toWinHBITMAP(HBitmapFormat format=NoAlpha) const
It is the caller&#39;s responsibility to free the HBITMAP data after use.
int count(char c) const
Returns the number of occurrences of character ch in the byte array.
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
QRect toRect() const
Returns the variant as a QRect if the variant has type() Rect ; otherwise returns an invalid QRect...
Definition: qvariant.cpp:2416
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
QString family() const
Returns the requested font family name, i.e.
Definition: qfont.cpp:906
Type type() const
Returns the storage type of the value stored in the variant.
Definition: qvariant.cpp:1901
const void * constData() const
Definition: qvariant.cpp:3065
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
static BSTR QStringToBSTR(const QString &str)
Definition: qaxtypes.h:76
void resize(int size)
Sets the size of the byte array to size bytes.
uint toUInt(bool *ok=0) const
Returns the variant as an unsigned int if the variant has type() UInt , Bool , ByteArray ...
Definition: qvariant.cpp:2644
QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint type)
Returns arg as a QVariant of type type.
Definition: qaxtypes.cpp:919
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
static QPixmap IPictureToQPixmap(IPicture *ipic)
Definition: qaxtypes.cpp:163
int weight() const
Returns the weight of the font which is one of the enumerated values from QFont::Weight.
Definition: qfont.cpp:1248
GUID IID_IAxServerBase
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
double toDouble(bool *ok=0) const
Returns the variant as a double if the variant has type() Double , QMetaType::Float ...
Definition: qvariant.cpp:2710
quint16 index
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
bool italic() const
Returns true if the style() of the font is not QFont::StyleNormal.
Definition: qfont.h:355
int pointSize() const
Returns the point size of the font.
Definition: qfont.cpp:981
int year() const
Returns the year of this date.
Definition: qdatetime.cpp:353
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
QTime time() const
Returns the time part of the datetime.
Definition: qdatetime.cpp:2368
QTime toTime() const
Returns the variant as a QTime if the variant has type() Time , DateTime , or String ; otherwise retu...
Definition: qvariant.cpp:2330
const char * variant
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
Definition: qpixmap.cpp:615
bool strikeOut() const
Returns true if strikeout has been set; otherwise returns false.
Definition: qfont.cpp:1367
static IFontDisp * QFontToIFont(const QFont &font)
Definition: qaxtypes.cpp:75
CLSID CLSID_QRect
static QDateTime DATEToQDateTime(DATE ole)
Definition: qaxtypes.cpp:178
static Type nameToType(const char *name)
Converts the string representation of the storage type given in name, to its enum representation...
Definition: qvariant.cpp:2026
long queryInterface(const QUuid &, void **) const
Requests the interface uuid from the COM object and sets the value of iface to the provided interface...
Definition: qaxbase.cpp:1479
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
CLSID CLSID_QPoint
QPoint toPoint() const
Returns the variant as a QPoint if the variant has type() Point or PointF ; otherwise returns a null ...
Definition: qvariant.cpp:2400
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
bool isValid() const
Returns true if the time is valid; otherwise returns false.
Definition: qdatetime.cpp:1566
int hour() const
Returns the hour part (0 to 23) of the time.
Definition: qdatetime.cpp:1578
bool endsWith(const QByteArray &a) const
Returns true if this byte array ends with byte array ba; otherwise returns false. ...
T qvariant_cast(const QVariant &value)
Returns the given value converted to the template type T.
Definition: qvariant.h:571