Qt 4.8
qaxserverbase.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 #define QT_NO_CAST_TO_ASCII
42 
43 #ifndef QT_NO_WIN_ACTIVEQT
44 
46 #include <qapplication.h>
47 #include <qbuffer.h>
48 #include <qdatastream.h>
49 #include <qdebug.h>
50 #include <qevent.h>
51 #include <qeventloop.h>
52 #include <qfile.h>
53 #include <qpointer.h>
54 #include <qhash.h>
55 #include <qmap.h>
56 #include <qmenubar.h>
57 #include <qmenu.h>
58 #include <qmetaobject.h>
59 #include <qpixmap.h>
60 #include <qstatusbar.h>
61 #include <qwhatsthis.h>
62 #include <ocidl.h>
63 #include <olectl.h>
64 #include <private/qcoreapplication_p.h>
65 
66 #include "qaxfactory.h"
67 #include "qaxbindable.h"
68 #include "qaxaggregated.h"
69 
70 #include "../shared/qaxtypes.h"
71 
72 #if defined Q_CC_GNU
73 # include <w32api.h>
74 #endif
75 
76 #ifndef Q_OS_WIN64
77 #define ULONG_PTR DWORD
78 #endif
79 
81 
82 extern HHOOK qax_hhook;
83 
84 // in qaxserver.cpp
85 extern ITypeLib *qAxTypeLibrary;
86 extern QAxFactory *qAxFactory();
87 extern unsigned long qAxLock();
88 extern unsigned long qAxUnlock();
89 extern HANDLE qAxInstance;
90 extern bool qAxOutProcServer;
91 
92 static int invokeCount = 0;
93 
94 #ifdef QT_DEBUG
95 unsigned long qaxserverbase_instance_count = 0;
96 #endif
97 
98 // in qaxserverdll.cpp
99 extern bool qax_ownQApp;
100 
102 {
103  QAxExceptInfo(int c, const QString &s, const QString &d, const QString &x)
104  : code(c), src(s), desc(d), context(x)
105  {
106  }
107  int code;
111 };
112 
113 
115 
116 /*
117  \class QAxServerBase
118  \brief The QAxServerBase class is an ActiveX control hosting a QWidget.
119 
120  \internal
121 */
123  public QObject,
124  public IAxServerBase,
125  public IDispatch,
126  public IOleObject,
127  public IOleControl,
128 #if defined Q_CC_GNU
129 # if (__W32API_MAJOR_VERSION < 2 || (__W32API_MAJOR_VERSION == 2 && __W32API_MINOR_VERSION < 5))
130  public IViewObject, // this should not be needed as IViewObject2 is meant to inherit from this,
131  // untill the mingw headers are fixed this will need to stay.
132 # endif
133 #endif
134  public IViewObject2,
135  public IOleInPlaceObject,
136  public IOleInPlaceActiveObject,
137  public IProvideClassInfo2,
138  public IConnectionPointContainer,
139  public IPersistStream,
140  public IPersistStreamInit,
141  public IPersistStorage,
142  public IPersistPropertyBag,
143  public IPersistFile,
144  public IDataObject
145 {
146 public:
149 
150  QAxServerBase(const QString &classname, IUnknown *outerUnknown);
152 
153  void init();
154 
155  ~QAxServerBase();
156 
157 // Window creation
158  HWND create(HWND hWndParent, RECT& rcPos);
159  HMENU createPopup(QMenu *popup, HMENU oldMenu = 0);
160  void createMenu(QMenuBar *menuBar);
161  void removeMenu();
162 
163  static LRESULT QT_WIN_CALLBACK ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
164 
165 // Object registration with OLE
166  void registerActiveObject(IUnknown *object);
167  void revokeActiveObject();
168 
169 // IUnknown
170  unsigned long WINAPI AddRef()
171  {
172  if (m_outerUnknown)
173  return m_outerUnknown->AddRef();
174 
175  EnterCriticalSection(&refCountSection);
176  unsigned long r = ++ref;
177  LeaveCriticalSection(&refCountSection);
178 
179  return r;
180  }
181  unsigned long WINAPI Release()
182  {
183  if (m_outerUnknown)
184  return m_outerUnknown->Release();
185 
186  EnterCriticalSection(&refCountSection);
187  unsigned long r = --ref;
188  LeaveCriticalSection(&refCountSection);
189 
190  if (!r) {
191  delete this;
192  return 0;
193  }
194  return r;
195  }
196  HRESULT WINAPI QueryInterface(REFIID iid, void **iface);
197  HRESULT InternalQueryInterface(REFIID iid, void **iface);
198 
199 // IAxServerBase
200  IUnknown *clientSite() const
201  {
202  return m_spClientSite;
203  }
204 
205  void emitPropertyChanged(const char*);
206  bool emitRequestPropertyChange(const char*);
207  QObject *qObject() const
208  {
209  return theObject;
210  }
211  void ensureMetaData();
212  bool isPropertyExposed(int index);
213 
214  void reportError(int code, const QString &src, const QString &desc, const QString &context)
215  {
216  if (exception)
217  delete exception;
218  exception = new QAxExceptInfo(code, src, desc, context);
219  }
220 
221 // IDispatch
222  STDMETHOD(GetTypeInfoCount)(UINT* pctinfo);
223  STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo);
224  STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid);
225  STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
226  LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
227  EXCEPINFO* pexcepinfo, UINT* puArgErr);
228 
229 // IProvideClassInfo
230  STDMETHOD(GetClassInfo)(ITypeInfo** pptinfo);
231 
232 // IProvideClassInfo2
233  STDMETHOD(GetGUID)(DWORD dwGuidKind, GUID* pGUID);
234 
235 // IOleObject
236  STDMETHOD(Advise)(IAdviseSink* pAdvSink, DWORD* pdwConnection);
237  STDMETHOD(Close)(DWORD dwSaveOption);
238  STDMETHOD(DoVerb)(LONG iVerb, LPMSG lpmsg, IOleClientSite* pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect);
239  STDMETHOD(EnumAdvise)(IEnumSTATDATA** ppenumAdvise);
240  STDMETHOD(EnumVerbs)(IEnumOLEVERB** ppEnumOleVerb);
241  STDMETHOD(GetClientSite)(IOleClientSite** ppClientSite);
242  STDMETHOD(GetClipboardData)(DWORD dwReserved, IDataObject** ppDataObject);
243  STDMETHOD(GetExtent)(DWORD dwDrawAspect, SIZEL* psizel);
244  STDMETHOD(GetMiscStatus)(DWORD dwAspect, DWORD *pdwStatus);
245  STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk);
246  STDMETHOD(GetUserClassID)(CLSID* pClsid);
247  STDMETHOD(GetUserType)(DWORD dwFormOfType, LPOLESTR *pszUserType);
248  STDMETHOD(InitFromData)(IDataObject* pDataObject, BOOL fCreation, DWORD dwReserved);
249  STDMETHOD(IsUpToDate)();
250  STDMETHOD(SetClientSite)(IOleClientSite* pClientSite);
251  STDMETHOD(SetColorScheme)(LOGPALETTE* pLogPal);
252  STDMETHOD(SetExtent)(DWORD dwDrawAspect, SIZEL* psizel);
253  STDMETHOD(SetHostNames)(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj);
254  STDMETHOD(SetMoniker)(DWORD dwWhichMoniker, IMoniker* ppmk);
255  STDMETHOD(Unadvise)(DWORD dwConnection);
256  STDMETHOD(Update)();
257 
258 // IViewObject
259  STDMETHOD(Draw)(DWORD dwAspect, LONG lIndex, void *pvAspect, DVTARGETDEVICE *ptd,
260  HDC hicTargetDevice, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds,
261  BOOL(__stdcall*pfnContinue)(ULONG_PTR), ULONG_PTR dwContinue);
262  STDMETHOD(GetColorSet)(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
263  HDC hicTargetDev, LOGPALETTE **ppColorSet);
264  STDMETHOD(Freeze)(DWORD dwAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze);
265  STDMETHOD(Unfreeze)(DWORD dwFreeze);
266  STDMETHOD(SetAdvise)(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink);
267  STDMETHOD(GetAdvise)(DWORD *aspects, DWORD *advf, IAdviseSink **pAdvSink);
268 
269 // IViewObject2
270  STDMETHOD(GetExtent)(DWORD dwAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel);
271 
272 // IOleControl
273  STDMETHOD(FreezeEvents)(BOOL);
274  STDMETHOD(GetControlInfo)(LPCONTROLINFO);
275  STDMETHOD(OnAmbientPropertyChange)(DISPID);
276  STDMETHOD(OnMnemonic)(LPMSG);
277 
278 // IOleWindow
279  STDMETHOD(GetWindow)(HWND *pHwnd);
280  STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode);
281 
282 // IOleInPlaceObject
283  STDMETHOD(InPlaceDeactivate)();
284  STDMETHOD(UIDeactivate)();
285  STDMETHOD(SetObjectRects)(LPCRECT lprcPosRect, LPCRECT lprcClipRect);
286  STDMETHOD(ReactivateAndUndo)();
287 
288 // IOleInPlaceActiveObject
289  STDMETHOD(TranslateAcceleratorW)(MSG *pMsg);
290  STDMETHOD(TranslateAcceleratorA)(MSG *pMsg);
291  STDMETHOD(OnFrameWindowActivate)(BOOL);
292  STDMETHOD(OnDocWindowActivate)(BOOL fActivate);
293  STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow);
294  STDMETHOD(EnableModeless)(BOOL);
295 
296 // IConnectionPointContainer
297  STDMETHOD(EnumConnectionPoints)(IEnumConnectionPoints**);
298  STDMETHOD(FindConnectionPoint)(REFIID, IConnectionPoint**);
299 
300 // IPersist
301  STDMETHOD(GetClassID)(GUID*clsid)
302  {
303  *clsid = qAxFactory()->classID(class_name);
304  return S_OK;
305  }
306 
307 // IPersistStreamInit
308  STDMETHOD(InitNew)(VOID);
309  STDMETHOD(IsDirty)();
310  STDMETHOD(Load)(IStream *pStm);
311  STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty);
312  STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize);
313 
314 // IPersistPropertyBag
315  STDMETHOD(Load)(IPropertyBag *, IErrorLog *);
316  STDMETHOD(Save)(IPropertyBag *, BOOL, BOOL);
317 
318 // IPersistStorage
319  STDMETHOD(InitNew)(IStorage *pStg);
320  STDMETHOD(Load)(IStorage *pStg);
321  STDMETHOD(Save)(IStorage *pStg, BOOL fSameAsLoad);
322  STDMETHOD(SaveCompleted)(IStorage *pStgNew);
323  STDMETHOD(HandsOffStorage)();
324 
325 // IPersistFile
326  STDMETHOD(SaveCompleted)(LPCOLESTR fileName);
327  STDMETHOD(GetCurFile)(LPOLESTR *currentFile);
328  STDMETHOD(Load)(LPCOLESTR fileName, DWORD mode);
329  STDMETHOD(Save)(LPCOLESTR fileName, BOOL fRemember);
330 
331 // IDataObject
332  STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
333  STDMETHOD(GetDataHere)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */);
334  STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */);
335  STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */);
336  STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */);
337  STDMETHOD(EnumFormatEtc)(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */);
338  STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
339  STDMETHOD(DUnadvise)(DWORD dwConnection);
340  STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise);
341 
342 // QObject
343  int qt_metacall(QMetaObject::Call, int index, void **argv);
344 
345  bool eventFilter(QObject *o, QEvent *e);
346 private:
347  void update();
348  void resize(const QSize &newSize);
349  void updateGeometry();
350  void updateMask();
351  bool internalCreate();
352  void internalBind();
353  void internalConnect();
354  HRESULT internalActivate();
355 
356  friend class QAxBindable;
357  friend class QAxPropertyPage;
358 
360  ConnectionPoints points;
361 
362  union {
365  } qt;
367  unsigned isWidget :1;
368  unsigned ownObject :1;
369  unsigned initNewCalled :1;
370  unsigned dirtyflag :1;
371  unsigned hasStockEvents :1;
372  unsigned stayTopLevel :1;
373  unsigned isInPlaceActive :1;
374  unsigned isUIActive :1;
375  unsigned wasUIActive :1;
376  unsigned inDesignMode :1;
377  unsigned canTakeFocus :1;
379 
380  HWND m_hWnd;
381 
382  HMENU hmenuShared;
383  HOLEMENU holemenu;
391 
392  CRITICAL_SECTION refCountSection;
393  CRITICAL_SECTION createWindowSection;
394 
395  unsigned long ref;
396  unsigned long ole_ref;
397 
400 
403 
404  IUnknown *m_outerUnknown;
405  IAdviseSink *m_spAdviseSink;
407  IOleClientSite *m_spClientSite;
408  IOleInPlaceSiteWindowless *m_spInPlaceSite;
409  IOleInPlaceFrame *m_spInPlaceFrame;
410  ITypeInfo *m_spTypeInfo;
411  IStorage *m_spStorage;
413 };
414 
415 class QAxServerAggregate : public IUnknown
416 {
417 public:
418  QAxServerAggregate(const QString &className, IUnknown *outerUnknown)
419  : m_outerUnknown(outerUnknown), ref(0)
420  {
421  object = new QAxServerBase(className, outerUnknown);
422  object->registerActiveObject(this);
423 
424  InitializeCriticalSection(&refCountSection);
425  InitializeCriticalSection(&createWindowSection);
426  }
428  {
429  DeleteCriticalSection(&refCountSection);
430  DeleteCriticalSection(&createWindowSection);
431 
432  delete object;
433  }
434 
435 // IUnknown
436  unsigned long WINAPI AddRef()
437  {
438  EnterCriticalSection(&refCountSection);
439  unsigned long r = ++ref;
440  LeaveCriticalSection(&refCountSection);
441 
442  return r;
443  }
444  unsigned long WINAPI Release()
445  {
446  EnterCriticalSection(&refCountSection);
447  unsigned long r = --ref;
448  LeaveCriticalSection(&refCountSection);
449 
450  if (!r) {
451  delete this;
452  return 0;
453  }
454  return r;
455  }
456  HRESULT WINAPI QueryInterface(REFIID iid, void **iface)
457  {
458  *iface = 0;
459 
460  HRESULT res = E_NOINTERFACE;
461  if (iid == IID_IUnknown) {
462  *iface = (IUnknown*)this;
463  AddRef();
464  return S_OK;
465  }
466  return object->InternalQueryInterface(iid, iface);
467  }
468 
469 private:
471  IUnknown *m_outerUnknown;
472  unsigned long ref;
473 
474  CRITICAL_SECTION refCountSection;
475  CRITICAL_SECTION createWindowSection;
476 };
477 
478 bool QAxFactory::createObjectWrapper(QObject *object, IDispatch **wrapper)
479 {
480  *wrapper = 0;
481  QAxServerBase *obj = new QAxServerBase(object);
482  obj->QueryInterface(IID_IDispatch, (void**)wrapper);
483  if (*wrapper)
484  return true;
485 
486  delete obj;
487  return false;
488 }
489 
490 
491 /*
492  Helper class to enumerate all supported event interfaces.
493 */
494 class QAxSignalVec : public IEnumConnectionPoints
495 {
496 public:
498  : cpoints(points.values())
499  , current(0)
500  , ref(0)
501  {
502  InitializeCriticalSection(&refCountSection);
503  const int count = cpoints.count();
504  for (int i = 0; i < count; ++i)
505  cpoints.at(i)->AddRef();
506  }
508  : cpoints(old.cpoints)
509  , current(old.current)
510  {
511  InitializeCriticalSection(&refCountSection);
512  ref = 0;
513  const int count = cpoints.count();
514  for (int i = 0; i < count; ++i)
515  cpoints.at(i)->AddRef();
516  }
518  {
519  const int count = cpoints.count();
520  for (int i = 0; i < count; ++i)
521  cpoints.at(i)->Release();
522 
523  DeleteCriticalSection(&refCountSection);
524  }
525 
526  unsigned long __stdcall AddRef()
527  {
528  EnterCriticalSection(&refCountSection);
529  unsigned long r = ++ref;
530  LeaveCriticalSection(&refCountSection);
531  return ++r;
532  }
533  unsigned long __stdcall Release()
534  {
535  EnterCriticalSection(&refCountSection);
536  unsigned long r = --ref;
537  LeaveCriticalSection(&refCountSection);
538 
539  if (!r) {
540  delete this;
541  return 0;
542  }
543  return r;
544  }
545  STDMETHOD(QueryInterface)(REFIID iid, void **iface)
546  {
547  if (!iface)
548  return E_POINTER;
549  *iface = 0;
550  if (iid == IID_IUnknown)
551  *iface = this;
552  else if (iid == IID_IEnumConnectionPoints)
553  *iface = this;
554  else
555  return E_NOINTERFACE;
556 
557  AddRef();
558  return S_OK;
559  }
560  STDMETHOD(Next)(ULONG cConnections, IConnectionPoint **cpoint, ULONG *pcFetched)
561  {
562  if (!cpoint)
563  return E_POINTER;
564 
565  if (!pcFetched && cConnections > 1)
566  return E_POINTER;
567 
568  const int count = cpoints.count();
569  unsigned long i;
570  for (i = 0; i < cConnections; i++) {
571  if (current==count)
572  break;
573  IConnectionPoint *cp = cpoints.at(current);
574  cp->AddRef();
575  cpoint[i] = cp;
576  ++current;
577  }
578  if (pcFetched)
579  *pcFetched = i;
580  return i == cConnections ? S_OK : S_FALSE;
581  }
582  STDMETHOD(Skip)(ULONG cConnections)
583  {
584  const int count = cpoints.count();
585  while (cConnections) {
586  if (current == count)
587  return S_FALSE;
588  ++current;
589  --cConnections;
590  }
591  return S_OK;
592  }
593  STDMETHOD(Reset)()
594  {
595  current = 0;
596  return S_OK;
597  }
598  STDMETHOD(Clone)(IEnumConnectionPoints **ppEnum)
599  {
600  if (!ppEnum)
601  return E_POINTER;
602  *ppEnum = new QAxSignalVec(*this);
603  (*ppEnum)->AddRef();
604 
605  return S_OK;
606  }
607 
609  int current;
610 
611 private:
612  CRITICAL_SECTION refCountSection;
613 
614  unsigned long ref;
615 };
616 
617 /*
618  Helper class to store and enumerate all connected event listeners.
619 */
620 class QAxConnection : public IConnectionPoint,
621  public IEnumConnections
622 {
623 public:
626 
627  QAxConnection(QAxServerBase *parent, const QUuid &uuid)
628  : that(parent), iid(uuid), current(0), ref(1)
629  {
630  InitializeCriticalSection(&refCountSection);
631  }
633  : current(old.current)
634  {
635  InitializeCriticalSection(&refCountSection);
636  ref = 0;
637  connections = old.connections;
638  that = old.that;
639  iid = old.iid;
640  QList<CONNECTDATA>::Iterator it = connections.begin();
641  while (it != connections.end()) {
642  CONNECTDATA connection = *it;
643  ++it;
644  connection.pUnk->AddRef();
645  }
646  }
648  {
649  DeleteCriticalSection(&refCountSection);
650  }
651 
652  unsigned long __stdcall AddRef()
653  {
654  EnterCriticalSection(&refCountSection);
655  unsigned long r = ++ref;
656  LeaveCriticalSection(&refCountSection);
657  return r;
658  }
659  unsigned long __stdcall Release()
660  {
661  EnterCriticalSection(&refCountSection);
662  unsigned long r = --ref;
663  LeaveCriticalSection(&refCountSection);
664 
665  if (!r) {
666  delete this;
667  return 0;
668  }
669  return r;
670  }
671  STDMETHOD(QueryInterface)(REFIID iid, void **iface)
672  {
673  if (!iface)
674  return E_POINTER;
675  *iface = 0;
676  if (iid == IID_IUnknown)
677  *iface = (IConnectionPoint*)this;
678  else if (iid == IID_IConnectionPoint)
679  *iface = this;
680  else if (iid == IID_IEnumConnections)
681  *iface = this;
682  else
683  return E_NOINTERFACE;
684 
685  AddRef();
686  return S_OK;
687  }
688  STDMETHOD(GetConnectionInterface)(IID *pIID)
689  {
690  *pIID = iid;
691  return S_OK;
692  }
693  STDMETHOD(GetConnectionPointContainer)(IConnectionPointContainer **ppCPC)
694  {
695  return that->QueryInterface(IID_IConnectionPointContainer, (void**)ppCPC);
696  }
697  STDMETHOD(Advise)(IUnknown*pUnk, DWORD *pdwCookie)
698  {
699  if (!pUnk || !pdwCookie)
700  return E_POINTER;
701 
702  {
703  IDispatch *checkImpl = 0;
704  pUnk->QueryInterface(iid, (void**)&checkImpl);
705  if (!checkImpl)
706  return CONNECT_E_CANNOTCONNECT;
707  checkImpl->Release();
708  }
709 
710  CONNECTDATA cd;
711  cd.dwCookie = connections.count()+1;
712  cd.pUnk = pUnk;
713  cd.pUnk->AddRef();
714  connections.append(cd);
715  *pdwCookie = cd.dwCookie;
716  return S_OK;
717  }
718  STDMETHOD(Unadvise)(DWORD dwCookie)
719  {
720  const int count = connections.count();
721  for (int i = 0; i < count; ++i) {
722  if (connections.at(i).dwCookie == dwCookie) {
723  connections.removeAt(i);
724  if (current >= i && current != 0)
725  --current;
726  return S_OK;
727  }
728  }
729  return CONNECT_E_NOCONNECTION;
730  }
731  STDMETHOD(EnumConnections)(IEnumConnections **ppEnum)
732  {
733  if (!ppEnum)
734  return E_POINTER;
735  *ppEnum = this;
736  AddRef();
737 
738  return S_OK;
739  }
740  STDMETHOD(Next)(ULONG cConnections, CONNECTDATA *cd, ULONG *pcFetched)
741  {
742  if (!cd)
743  return E_POINTER;
744 
745  if (!pcFetched && cConnections > 1)
746  return E_POINTER;
747 
748  const int count = connections.count();
749 
750  unsigned long i;
751  for (i = 0; i < cConnections; i++) {
752  if (current == count)
753  break;
754  cd[i] = connections.at(current);
755  cd[i].pUnk->AddRef();
756  ++current;
757  }
758  if (pcFetched)
759  *pcFetched = i;
760  return i == cConnections ? S_OK : S_FALSE;
761  }
762  STDMETHOD(Skip)(ULONG cConnections)
763  {
764  const int count = connections.count();
765  while (cConnections) {
766  if (current == count)
767  return S_FALSE;
768  ++current;
769  --cConnections;
770  }
771  return S_OK;
772  }
773  STDMETHOD(Reset)()
774  {
775  current = 0;
776  return S_OK;
777  }
778  STDMETHOD(Clone)(IEnumConnections **ppEnum)
779  {
780  if (!ppEnum)
781  return E_POINTER;
782  *ppEnum = new QAxConnection(*this);
783  (*ppEnum)->AddRef();
784 
785  return S_OK;
786  }
787 
788 private:
791  Connections connections;
792  int current;
793 
794  CRITICAL_SECTION refCountSection;
795  unsigned long ref;
796 };
797 
798 // callback for DLL server to hook into non-Qt eventloop
799 LRESULT QT_WIN_CALLBACK axs_FilterProc(int nCode, WPARAM wParam, LPARAM lParam)
800 {
801  if (qApp && !invokeCount)
802  qApp->sendPostedEvents();
803 
804  return CallNextHookEx(qax_hhook, nCode, wParam, lParam);
805 }
806 
807 // filter for executable case to hook into Qt eventloop
808 // for DLLs the client calls TranslateAccelerator
809 bool qax_winEventFilter(void *message)
810 {
811  MSG *pMsg = (MSG*)message;
812  if (pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST)
813  return false;
814 
815  bool ret = false;
816  QWidget *aqt = QWidget::find(pMsg->hwnd);
817  if (!aqt)
818  return ret;
819 
820  HWND baseHwnd = ::GetParent(aqt->winId());
821  QAxServerBase *axbase = 0;
822  while (!axbase && baseHwnd) {
823 #ifdef GWLP_USERDATA
824  axbase = (QAxServerBase*)GetWindowLongPtr(baseHwnd, GWLP_USERDATA);
825 #else
826  axbase = (QAxServerBase*)GetWindowLong(baseHwnd, GWL_USERDATA);
827 #endif
828 
829  baseHwnd = ::GetParent(baseHwnd);
830  }
831  if (!axbase)
832  return ret;
833 
834  HRESULT hres = axbase->TranslateAcceleratorW(pMsg);
835  return hres == S_OK;
836 }
837 
838 extern void qWinMsgHandler(QtMsgType t, const char* str);
839 
840 // COM Factory class, mapping COM requests to ActiveQt requests.
841 // One instance of this class for each ActiveX the server can provide.
842 class QClassFactory : public IClassFactory2
843 {
844 public:
845  QClassFactory(CLSID clsid)
846  : ref(0), licensed(false)
847  {
848  InitializeCriticalSection(&refCountSection);
849 
850  // COM only knows the CLSID, but QAxFactory is class name based...
852  for (QStringList::Iterator key = keys.begin(); key != keys.end(); ++key) {
853  if (qAxFactory()->classID(*key) == clsid) {
854  className = *key;
855  break;
856  }
857  }
858 
859  const QMetaObject *mo = qAxFactory()->metaObject(className);
860  if (mo) {
861  classKey = QLatin1String(mo->classInfo(mo->indexOfClassInfo("LicenseKey")).value());
862  licensed = !classKey.isEmpty();
863  }
864  }
865 
867  {
868  DeleteCriticalSection(&refCountSection);
869  }
870 
871  // IUnknown
872  unsigned long WINAPI AddRef()
873  {
874  EnterCriticalSection(&refCountSection);
875  unsigned long r = ++ref;
876  LeaveCriticalSection(&refCountSection);
877  return ++r;
878  }
879  unsigned long WINAPI Release()
880  {
881  EnterCriticalSection(&refCountSection);
882  unsigned long r = --ref;
883  LeaveCriticalSection(&refCountSection);
884 
885  if (!r) {
886  delete this;
887  return 0;
888  }
889  return r;
890  }
891  HRESULT WINAPI QueryInterface(REFIID iid, LPVOID *iface)
892  {
893  *iface = 0;
894  if (iid == IID_IUnknown)
895  *iface = (IUnknown*)this;
896  else if (iid == IID_IClassFactory)
897  *iface = (IClassFactory*)this;
898  else if (iid == IID_IClassFactory2 && licensed)
899  *iface = (IClassFactory2*)this;
900  else
901  return E_NOINTERFACE;
902 
903  AddRef();
904  return S_OK;
905  }
906 
907  HRESULT WINAPI CreateInstanceHelper(IUnknown *pUnkOuter, REFIID iid, void **ppObject)
908  {
909  if (pUnkOuter) {
910  if (iid != IID_IUnknown)
911  return CLASS_E_NOAGGREGATION;
912  const QMetaObject *mo = qAxFactory()->metaObject(className);
913  if (mo && !qstricmp(mo->classInfo(mo->indexOfClassInfo("Aggregatable")).value(), "no"))
914  return CLASS_E_NOAGGREGATION;
915  }
916 
917  // Make sure a QApplication instance is present (inprocess case)
918  if (!qApp) {
920  qax_ownQApp = true;
921  int argc = 0;
922  QApplication *app = new QApplication(argc, 0);
923  }
924  qApp->setQuitOnLastWindowClosed(false);
925 
926  if (qAxOutProcServer)
928  else
929  QApplication::instance()->d_func()->in_exec = true;
930 
931  // hook into eventloop; this allows a server to create his own QApplication object
932  if (!qax_hhook && qax_ownQApp) {
933  qax_hhook = SetWindowsHookEx(WH_GETMESSAGE, axs_FilterProc, 0, GetCurrentThreadId());
934  }
935 
936  HRESULT res;
937  // Create the ActiveX wrapper - aggregate if requested
938  if (pUnkOuter) {
939  QAxServerAggregate *aggregate = new QAxServerAggregate(className, pUnkOuter);
940  res = aggregate->QueryInterface(iid, ppObject);
941  if (FAILED(res))
942  delete aggregate;
943  } else {
944  QAxServerBase *activeqt = new QAxServerBase(className, pUnkOuter);
945  res = activeqt->QueryInterface(iid, ppObject);
946  if (FAILED(res))
947  delete activeqt;
948  else
949  activeqt->registerActiveObject((IUnknown*)(IDispatch*)activeqt);
950  }
951  return res;
952  }
953 
954  // IClassFactory
955  HRESULT WINAPI CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppObject)
956  {
957  // class is licensed
958  if (licensed && !qAxFactory()->validateLicenseKey(className, QString()))
959  return CLASS_E_NOTLICENSED;
960 
961  return CreateInstanceHelper(pUnkOuter, iid, ppObject);
962  }
963  HRESULT WINAPI LockServer(BOOL fLock)
964  {
965  if (fLock)
966  qAxLock();
967  else
968  qAxUnlock();
969 
970  return S_OK;
971  }
972 
973  // IClassFactory2
974  HRESULT WINAPI RequestLicKey(DWORD, BSTR *pKey)
975  {
976  if (!pKey)
977  return E_POINTER;
978  *pKey = 0;
979 
980  // This of course works only on fully licensed machines
981  if (!qAxFactory()->validateLicenseKey(className, QString()))
982  return CLASS_E_NOTLICENSED;
983 
984  *pKey = QStringToBSTR(classKey);
985  return S_OK;
986  }
987 
988  HRESULT WINAPI GetLicInfo(LICINFO *pLicInfo)
989  {
990  if (!pLicInfo)
991  return E_POINTER;
992  pLicInfo->cbLicInfo = sizeof(LICINFO);
993 
994  // class specific license key?
995  const QMetaObject *mo = qAxFactory()->metaObject(className);
996  const char *key = mo->classInfo(mo->indexOfClassInfo("LicenseKey")).value();
997  pLicInfo->fRuntimeKeyAvail = key && key[0];
998 
999  // machine fully licensed?
1000  pLicInfo->fLicVerified = qAxFactory()->validateLicenseKey(className, QString());
1001 
1002  return S_OK;
1003  }
1004 
1005  HRESULT WINAPI CreateInstanceLic(IUnknown *pUnkOuter, IUnknown *pUnkReserved, REFIID iid, BSTR bKey, PVOID *ppObject)
1006  {
1007  QString licenseKey = QString::fromWCharArray(bKey);
1008  if (!qAxFactory()->validateLicenseKey(className, licenseKey))
1009  return CLASS_E_NOTLICENSED;
1010  return CreateInstanceHelper(pUnkOuter, iid, ppObject);
1011  }
1012 
1014 
1015 protected:
1016  CRITICAL_SECTION refCountSection;
1017  unsigned long ref;
1018  bool licensed;
1020 };
1021 
1022 // Create a QClassFactory object for class \a iid
1023 HRESULT GetClassObject(REFIID clsid, REFIID iid, void **ppUnk)
1024 {
1025  QClassFactory *factory = new QClassFactory(clsid);
1026  if (!factory)
1027  return E_OUTOFMEMORY;
1028  if (factory->className.isEmpty()) {
1029  delete factory;
1030  return E_NOINTERFACE;
1031  }
1032  HRESULT res = factory->QueryInterface(iid, ppUnk);
1033  if (res != S_OK)
1034  delete factory;
1035  return res;
1036 }
1037 
1038 
1046 QAxServerBase::QAxServerBase(const QString &classname, IUnknown *outerUnknown)
1047 : aggregatedObject(0), ref(0), ole_ref(0), class_name(classname),
1048  m_hWnd(0), hmenuShared(0), hwndMenuOwner(0),
1049  m_outerUnknown(outerUnknown)
1050 {
1051  init();
1052 
1053  internalCreate();
1054 }
1055 
1060 : aggregatedObject(0), ref(0), ole_ref(0),
1061  m_hWnd(0), hmenuShared(0), hwndMenuOwner(0),
1062  m_outerUnknown(0)
1063 {
1064  init();
1065 
1066  qt.object = o;
1067  if (o) {
1068  theObject = o;
1069  isWidget = false;
1071  }
1072  internalBind();
1073  internalConnect();
1074 }
1075 
1080 {
1081  qt.object = 0;
1082  isWidget = false;
1083  ownObject = false;
1084  initNewCalled = false;
1085  dirtyflag = false;
1086  hasStockEvents = false;
1087  stayTopLevel = false;
1088  isInPlaceActive = false;
1089  isUIActive = false;
1090  wasUIActive = false;
1091  inDesignMode = false;
1092  canTakeFocus = false;
1093  freezeEvents = 0;
1094  exception = 0;
1095 
1096  m_spAdviseSink = 0;
1097  m_spClientSite = 0;
1098  m_spInPlaceSite = 0;
1099  m_spInPlaceFrame = 0;
1100  m_spTypeInfo = 0;
1101  m_spStorage = 0;
1102 
1103  InitializeCriticalSection(&refCountSection);
1104  InitializeCriticalSection(&createWindowSection);
1105 
1106 #ifdef QT_DEBUG
1107  EnterCriticalSection(&refCountSection);
1109  LeaveCriticalSection(&refCountSection);
1110 #endif
1111 
1112  qAxLock();
1113 
1114  points[IID_IPropertyNotifySink] = new QAxConnection(this, IID_IPropertyNotifySink);
1115 }
1116 
1122 {
1123 #ifdef QT_DEBUG
1124  EnterCriticalSection(&refCountSection);
1126  LeaveCriticalSection(&refCountSection);
1127 #endif
1128 
1130 
1132  if (it.value())
1133  (*it)->Release();
1134  }
1135  delete aggregatedObject;
1136  aggregatedObject = 0;
1137  if (theObject) {
1138  qt.object->disconnect(this);
1139  QObject *aqt = qt.object;
1140  qt.object = 0;
1141  if (ownObject)
1142  delete aqt;
1143  }
1144 
1145  if (m_spAdviseSink) m_spAdviseSink->Release();
1146  m_spAdviseSink = 0;
1147  for (int i = 0; i < adviseSinks.count(); ++i) {
1148  adviseSinks.at(i).pAdvSink->Release();
1149  }
1150  if (m_spClientSite) m_spClientSite->Release();
1151  m_spClientSite = 0;
1152  if (m_spInPlaceFrame) m_spInPlaceFrame->Release();
1153  m_spInPlaceFrame = 0;
1154  if (m_spInPlaceSite) m_spInPlaceSite->Release();
1155  m_spInPlaceSite = 0;
1156  if (m_spTypeInfo) m_spTypeInfo->Release();
1157  m_spTypeInfo = 0;
1158  if (m_spStorage) m_spStorage->Release();
1159  m_spStorage = 0;
1160 
1161  DeleteCriticalSection(&refCountSection);
1162  DeleteCriticalSection(&createWindowSection);
1163 
1164  qAxUnlock();
1165 }
1166 
1167 /*
1168  Registering with OLE
1169 */
1171 {
1172  if (ole_ref || !qt.object || !qAxOutProcServer)
1173  return;
1174 
1175  const QMetaObject *mo = qt.object->metaObject();
1176  if (!qstricmp(mo->classInfo(mo->indexOfClassInfo("RegisterObject")).value(), "yes"))
1177  RegisterActiveObject(object, qAxFactory()->classID(class_name), ACTIVEOBJECT_WEAK, &ole_ref);
1178 }
1179 
1181 {
1182  if (!ole_ref)
1183  return;
1184 
1185  RevokeActiveObject(ole_ref, 0);
1186  ole_ref = 0;
1187 }
1188 
1189 /*
1190  QueryInterface implementation.
1191 */
1192 HRESULT WINAPI QAxServerBase::QueryInterface(REFIID iid, void **iface)
1193 {
1194  if (m_outerUnknown)
1195  return m_outerUnknown->QueryInterface(iid, iface);
1196 
1197  return InternalQueryInterface(iid, iface);
1198 }
1199 
1201 {
1202  *iface = 0;
1203 
1204  if (iid == IID_IUnknown) {
1205  *iface = (IUnknown*)(IDispatch*)this;
1206  } else {
1207  HRESULT res = S_OK;
1208  if (aggregatedObject)
1209  res = aggregatedObject->queryInterface(iid, iface);
1210  if (*iface)
1211  return res;
1212  }
1213 
1214  if (!(*iface)) {
1215  if (iid == qAxFactory()->interfaceID(class_name))
1216  *iface = (IDispatch*)this;
1217  if (iid == IID_IDispatch)
1218  *iface = (IDispatch*)this;
1219  else if (iid == IID_IAxServerBase)
1220  *iface = (IAxServerBase*)this;
1221  else if (iid == IID_IOleObject)
1222  *iface = (IOleObject*)this;
1223  else if (iid == IID_IConnectionPointContainer)
1224  *iface = (IConnectionPointContainer*)this;
1225  else if (iid == IID_IProvideClassInfo)
1226  *iface = (IProvideClassInfo*)this;
1227  else if (iid == IID_IProvideClassInfo2)
1228  *iface = (IProvideClassInfo2*)this;
1229  else if (iid == IID_IPersist)
1230  *iface = (IPersist*)(IPersistStream*)this;
1231  else if (iid == IID_IPersistStream)
1232  *iface = (IPersistStream*)this;
1233  else if (iid == IID_IPersistStreamInit)
1234  *iface = (IPersistStreamInit*)this;
1235  else if (iid == IID_IPersistStorage)
1236  *iface = (IPersistStorage*)this;
1237  else if (iid == IID_IPersistPropertyBag)
1238  *iface = (IPersistPropertyBag*)this;
1239  else if (iid == IID_IPersistFile &&
1240  qAxFactory()->metaObject(class_name)->indexOfClassInfo("MIME") != -1)
1241  *iface = (IPersistFile*)this;
1242  else if (iid == IID_IViewObject)
1243  *iface = (IViewObject*)this;
1244  else if (iid == IID_IViewObject2)
1245  *iface = (IViewObject2*)this;
1246  else if (isWidget) {
1247  if (iid == IID_IOleControl)
1248  *iface = (IOleControl*)this;
1249  else if (iid == IID_IOleWindow)
1250  *iface = (IOleWindow*)(IOleInPlaceObject*)this;
1251  else if (iid == IID_IOleInPlaceObject)
1252  *iface = (IOleInPlaceObject*)this;
1253  else if (iid == IID_IOleInPlaceActiveObject)
1254  *iface = (IOleInPlaceActiveObject*)this;
1255  else if (iid == IID_IDataObject)
1256  *iface = (IDataObject*)this;
1257  }
1258  }
1259  if (!*iface)
1260  return E_NOINTERFACE;
1261 
1262  AddRef();
1263  return S_OK;
1264 }
1265 
1270 {
1271  QAxBindable *axb = (QAxBindable*)qt.object->qt_metacast("QAxBindable");
1272  if (axb) {
1273  // no addref; this is aggregated
1274  axb->activex = this;
1275  if (!aggregatedObject)
1277  if (aggregatedObject) {
1278  aggregatedObject->controlling_unknown = (IUnknown*)(IDispatch*)this;
1279  aggregatedObject->the_object = qt.object;
1280  }
1281  }
1282 }
1283 
1288 {
1289  QUuid eventsID = qAxFactory()->eventsID(class_name);
1290  if (!eventsID.isNull()) {
1291  if (!points[eventsID])
1292  points[eventsID] = new QAxConnection(this, eventsID);
1293 
1294  // connect the generic slot to all signals of qt.object
1295  const QMetaObject *mo = qt.object->metaObject();
1296  for (int isignal = mo->methodCount()-1; isignal >= 0; --isignal) {
1297  if (mo->method(isignal).methodType() == QMetaMethod::Signal)
1298  QMetaObject::connect(qt.object, isignal, this, isignal);
1299  }
1300  }
1301 }
1302 
1310 {
1311  if (qt.object)
1312  return true;
1313 
1314  qt.object = qAxFactory()->createObject(class_name);
1315  Q_ASSERT(qt.object);
1316  if (!qt.object)
1317  return false;
1318 
1319  theObject = qt.object;
1320  ownObject = true;
1321  isWidget = qt.object->isWidgetType();
1324 
1325  internalBind();
1326  if (isWidget) {
1327  if (!stayTopLevel) {
1329  QApplication::sendEvent(qt.widget, &e);
1330  ::SetWindowLong(qt.widget->winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
1331  }
1332  qt.widget->setAttribute(Qt::WA_QuitOnClose, false);
1333  qt.widget->move(0, 0);
1334 
1335  // initialize to sizeHint, but don't set resized flag so that container has a chance to override
1336  bool wasResized = qt.widget->testAttribute(Qt::WA_Resized);
1337  updateGeometry();
1338  if (!wasResized && qt.widget->testAttribute(Qt::WA_Resized)
1339  && qt.widget->sizePolicy() != QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)) {
1340  qt.widget->setAttribute(Qt::WA_Resized, false);
1341  }
1342  }
1343 
1344  internalConnect();
1345  // install an event filter for stock events
1346  if (isWidget) {
1347  qt.object->installEventFilter(this);
1348  const QList<QWidget*> children = qt.object->findChildren<QWidget*>();
1350  while (it != children.constEnd()) {
1351  (*it)->installEventFilter(this);
1352  ++it;
1353  }
1354  }
1355  return true;
1356 }
1357 
1358 /*
1359 class HackMenuData : public QMenuData
1360 {
1361  friend class QAxServerBase;
1362 };
1363 */
1364 
1365 class HackWidget : public QWidget
1366 {
1367  friend class QAxServerBase;
1368 };
1369 /*
1370  Message handler. \a hWnd is always the ActiveX widget hosting the Qt widget.
1371  \a uMsg is handled as follows
1372  \list
1373  <li> WM_CREATE The ActiveX control is created
1374  <li> WM_DESTROY The QWidget is destroyed
1375  <li> WM_SHOWWINDOW The QWidget is parented into the ActiveX window
1376  <li> WM_PAINT The QWidget is updated
1377  <li> WM_SIZE The QWidget is resized to the new size
1378  <li> WM_SETFOCUS and
1379  <li> WM_KILLFOCUS The client site is notified about the focus transfer
1380  <li> WM_MOUSEACTIVATE The ActiveX is activated
1381  \endlist
1382 
1383  The semantics of \a wParam and \a lParam depend on the value of \a uMsg.
1384 */
1385 LRESULT QT_WIN_CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1386 {
1387  if (uMsg == WM_CREATE) {
1388  CREATESTRUCT *cs = (CREATESTRUCT*)lParam;
1389  QAxServerBase *that = (QAxServerBase*)cs->lpCreateParams;
1390 
1391 #ifdef GWLP_USERDATA
1392  SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)that);
1393 #else
1394  SetWindowLong(hWnd, GWL_USERDATA, (LONG)that);
1395 #endif
1396 
1397  that->m_hWnd = hWnd;
1398 
1399  return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
1400  }
1401 
1402  QAxServerBase *that = 0;
1403 
1404 #ifdef GWLP_USERDATA
1405  that = (QAxServerBase*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
1406 #else
1407  that = (QAxServerBase*)GetWindowLong(hWnd, GWL_USERDATA);
1408 #endif
1409 
1410  if (that) {
1411  int width = that->qt.widget ? that->qt.widget->width() : 0;
1412  int height = that->qt.widget ? that->qt.widget->height() : 0;
1413  RECT rcPos = {0, 0, width + 1, height + 1};
1414 
1415  switch (uMsg) {
1416  case WM_NCDESTROY:
1417  that->m_hWnd = 0;
1418  break;
1419 
1420  case WM_QUERYENDSESSION:
1421  case WM_DESTROY:
1422  // save the window handle
1423  if (that->qt.widget) {
1424  that->qt.widget->hide();
1425  ::SetParent(that->qt.widget->winId(), 0);
1426  }
1427  break;
1428 
1429  case WM_SHOWWINDOW:
1430  if(wParam) {
1431  that->internalCreate();
1432  if (!that->stayTopLevel) {
1433  ::SetParent(that->qt.widget->winId(), that->m_hWnd);
1434  that->qt.widget->raise();
1435  that->qt.widget->move(0, 0);
1436  }
1437  that->qt.widget->show();
1438  } else if (that->qt.widget) {
1439  that->qt.widget->hide();
1440  }
1441  break;
1442 
1443  case WM_ERASEBKGND:
1444  that->updateMask();
1445  break;
1446 
1447  case WM_SIZE:
1448  that->resize(QSize(LOWORD(lParam), HIWORD(lParam)));
1449  break;
1450 
1451  case WM_SETFOCUS:
1452  if (that->isInPlaceActive && that->m_spClientSite && !that->inDesignMode && that->canTakeFocus) {
1453  that->DoVerb(OLEIVERB_UIACTIVATE, NULL, that->m_spClientSite, 0, that->m_hWnd, &rcPos);
1454  if (that->isUIActive) {
1455  IOleControlSite *spSite = 0;
1456  that->m_spClientSite->QueryInterface(IID_IOleControlSite, (void**)&spSite);
1457  if (spSite) {
1458  spSite->OnFocus(true);
1459  spSite->Release();
1460  }
1461  QWidget *candidate = that->qt.widget;
1462  while (!(candidate->focusPolicy() & Qt::TabFocus)) {
1463  candidate = candidate->nextInFocusChain();
1464  if (candidate == that->qt.widget) {
1465  candidate = 0;
1466  break;
1467  }
1468  }
1469  if (candidate) {
1470  candidate->setFocus();
1471  HackWidget *widget = (HackWidget*)that->qt.widget;
1472  if (::GetKeyState(VK_SHIFT) < 0)
1473  widget->focusNextPrevChild(false);
1474  }
1475  }
1476  }
1477  break;
1478 
1479  case WM_KILLFOCUS:
1480  if (that->isInPlaceActive && that->isUIActive && that->m_spClientSite) {
1481  IOleControlSite *spSite = 0;
1482  that->m_spClientSite->QueryInterface(IID_IOleControlSite, (void**)&spSite);
1483  if (spSite) {
1484  if (!::IsChild(that->m_hWnd, ::GetFocus()))
1485  spSite->OnFocus(false);
1486  spSite->Release();
1487  }
1488  }
1489  break;
1490 
1491  case WM_MOUSEACTIVATE:
1492  that->DoVerb(OLEIVERB_UIACTIVATE, NULL, that->m_spClientSite, 0, that->m_hWnd, &rcPos);
1493  break;
1494 
1495  case WM_INITMENUPOPUP:
1496  if (that->qt.widget) {
1497  that->currentPopup = that->menuMap[(HMENU)wParam];
1498  if (!that->currentPopup)
1499  break;
1500  const QMetaObject *mo = that->currentPopup->metaObject();
1501  int index = mo->indexOfSignal("aboutToShow()");
1502  if (index < 0)
1503  break;
1504 
1505  that->currentPopup->qt_metacall(QMetaObject::InvokeMetaMethod, index, 0);
1506  that->createPopup(that->currentPopup, (HMENU)wParam);
1507  return 0;
1508  }
1509  break;
1510 
1511  case WM_MENUSELECT:
1512  case WM_COMMAND:
1513  if (that->qt.widget) {
1514  QMenuBar *menuBar = that->menuBar;
1515  if (!menuBar)
1516  break;
1517 
1518  QObject *menuObject = 0;
1519  bool menuClosed = false;
1520 
1521  if (uMsg == WM_COMMAND) {
1522  menuObject = that->actionMap.value(wParam);
1523  } else if (!lParam) {
1524  menuClosed = true;
1525  menuObject = that->currentPopup;
1526  } else {
1527  menuObject = that->actionMap.value(LOWORD(wParam));
1528  }
1529 
1530  if (menuObject) {
1531  const QMetaObject *mo = menuObject->metaObject();
1532  int index = -1;
1533 
1534  if (uMsg == WM_COMMAND)
1535  index = mo->indexOfSignal("activated()");
1536  else if (menuClosed)
1537  index = mo->indexOfSignal("aboutToHide()");
1538  else
1539  index = mo->indexOfSignal("hovered()");
1540 
1541  if (index < 0)
1542  break;
1543 
1544  menuObject->qt_metacall(QMetaObject::InvokeMetaMethod, index, 0);
1545  if (menuClosed || uMsg == WM_COMMAND)
1546  that->currentPopup = 0;
1547  return 0;
1548  }
1549  }
1550  break;
1551 
1552  default:
1553  break;
1554  }
1555  }
1556 
1557  return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
1558 }
1559 
1563 HWND QAxServerBase::create(HWND hWndParent, RECT& rcPos)
1564 {
1565  Q_ASSERT(isWidget && qt.widget);
1566 
1567  static ATOM atom = 0;
1568  HINSTANCE hInst = (HINSTANCE)qAxInstance;
1569  EnterCriticalSection(&createWindowSection);
1570  QString cn(QLatin1String("QAxControl"));
1572  if (!atom) {
1573  WNDCLASS wcTemp;
1574  wcTemp.style = CS_DBLCLKS;
1575  wcTemp.cbClsExtra = 0;
1576  wcTemp.cbWndExtra = 0;
1577  wcTemp.hbrBackground = 0;
1578  wcTemp.hCursor = 0;
1579  wcTemp.hIcon = 0;
1580  wcTemp.hInstance = hInst;
1581  wcTemp.lpszClassName = (wchar_t*)cn.utf16();
1582  wcTemp.lpszMenuName = 0;
1583  wcTemp.lpfnWndProc = ActiveXProc;
1584 
1585  atom = RegisterClass(&wcTemp);
1586  }
1587  LeaveCriticalSection(&createWindowSection);
1588  if (!atom && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
1589  return 0;
1590 
1591  Q_ASSERT(!m_hWnd);
1592  HWND hWnd = ::CreateWindow((wchar_t*)cn.utf16(), 0,
1593  WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
1594  rcPos.left, rcPos.top, rcPos.right - rcPos.left,
1595  rcPos.bottom - rcPos.top, hWndParent, 0, hInst, this);
1596 
1597  Q_ASSERT(m_hWnd == hWnd);
1598 
1599  updateMask();
1600  EnableWindow(m_hWnd, qt.widget->isEnabled());
1601 
1602  return hWnd;
1603 }
1604 
1605 /*
1606  Recoursively creates Win32 submenus.
1607 */
1608 HMENU QAxServerBase::createPopup(QMenu *popup, HMENU oldMenu)
1609 {
1610  HMENU popupMenu = oldMenu ? oldMenu : CreatePopupMenu();
1611  menuMap.insert(popupMenu, popup);
1612 
1613  if (oldMenu) while (GetMenuItemCount(oldMenu)) {
1614  DeleteMenu(oldMenu, 0, MF_BYPOSITION);
1615  }
1616 
1617  const QList<QAction*> actions = popup->actions();
1618  for (int i = 0; i < actions.count(); ++i) {
1619  QAction *action = actions.at(i);
1620 
1621  uint flags = action->isEnabled() ? MF_ENABLED : MF_GRAYED;
1622  if (action->isSeparator())
1623  flags |= MF_SEPARATOR;
1624  else if (action->menu())
1625  flags |= MF_POPUP;
1626  else
1627  flags |= MF_STRING;
1628  if (action->isChecked())
1629  flags |= MF_CHECKED;
1630 
1631  ushort itemId;
1632  if (flags & MF_POPUP) {
1633  itemId = static_cast<ushort>(
1634  reinterpret_cast<quintptr>(createPopup(action->menu()))
1635  );
1636  } else {
1637  itemId = static_cast<ushort>(reinterpret_cast<quintptr>(action));
1638  actionMap.remove(itemId);
1639  actionMap.insert(itemId, action);
1640  }
1641  AppendMenu(popupMenu, flags, itemId, (const wchar_t *)action->text().utf16());
1642  }
1643  if (oldMenu)
1644  DrawMenuBar(hwndMenuOwner);
1645  return popupMenu;
1646 }
1647 
1652 {
1653  hmenuShared = ::CreateMenu();
1654 
1655  int edit = 0;
1656  int object = 0;
1657  int help = 0;
1658 
1659  const QList<QAction*> actions = menuBar->actions();
1660  for (int i = 0; i < actions.count(); ++i) {
1661  QAction *action = actions.at(i);
1662 
1663  uint flags = action->isEnabled() ? MF_ENABLED : MF_GRAYED;
1664  if (action->isSeparator())
1665  flags |= MF_SEPARATOR;
1666  else if (action->menu())
1667  flags |= MF_POPUP;
1668  else
1669  flags |= MF_STRING;
1670 
1671  if (action->text() == QCoreApplication::translate(qt.widget->metaObject()->className(), "&Edit"))
1672  edit++;
1673  else if (action->text() == QCoreApplication::translate(qt.widget->metaObject()->className(), "&Help"))
1674  help++;
1675  else
1676  object++;
1677 
1678  ushort itemId;
1679  if (flags & MF_POPUP) {
1680  itemId = static_cast<ushort>(
1681  reinterpret_cast<quintptr>(createPopup(action->menu()))
1682  );
1683  } else {
1684  itemId = static_cast<ushort>(reinterpret_cast<quintptr>(action));
1685  actionMap.insert(itemId, action);
1686  }
1687  AppendMenu(hmenuShared, flags, itemId, (const wchar_t *)action->text().utf16());
1688  }
1689 
1690  OLEMENUGROUPWIDTHS menuWidths = {0,edit,0,object,0,help};
1691  HRESULT hres = m_spInPlaceFrame->InsertMenus(hmenuShared, &menuWidths);
1692  if (FAILED(hres)) {
1693  ::DestroyMenu(hmenuShared);
1694  hmenuShared = 0;
1695  return;
1696  }
1697 
1698  m_spInPlaceFrame->GetWindow(&hwndMenuOwner);
1699 
1700  holemenu = OleCreateMenuDescriptor(hmenuShared, &menuWidths);
1701  hres = m_spInPlaceFrame->SetMenu(hmenuShared, holemenu, m_hWnd);
1702  if (FAILED(hres)) {
1703  ::DestroyMenu(hmenuShared);
1704  hmenuShared = 0;
1705  OleDestroyMenuDescriptor(holemenu);
1706  }
1707 }
1708 
1713 {
1714  if (hmenuShared)
1715  m_spInPlaceFrame->RemoveMenus(hmenuShared);
1716  holemenu = 0;
1717  m_spInPlaceFrame->SetMenu(0, 0, m_hWnd);
1718  if (hmenuShared) {
1719  DestroyMenu(hmenuShared);
1720  hmenuShared = 0;
1721  menuMap.clear();
1722  }
1723  hwndMenuOwner = 0;
1724 }
1725 
1726 extern bool ignoreSlots(const char *test);
1727 extern bool ignoreProps(const char *test);
1728 
1733 {
1734  if (!m_spTypeInfo) {
1735  qAxTypeLibrary->GetTypeInfoOfGuid(qAxFactory()->interfaceID(class_name), &m_spTypeInfo);
1736  m_spTypeInfo->AddRef();
1737  }
1738 }
1739 
1749 {
1750  if (!theObject)
1751  return false;
1752 
1753  bool result = false;
1754  const QMetaObject *mo = theObject->metaObject();
1755 
1756  int qtProps = 0;
1757  if (theObject->isWidgetType())
1758  qtProps = QWidget::staticMetaObject.propertyCount();
1759  QMetaProperty property = mo->property(index);
1760  if (index <= qtProps && ignoreProps(property.name()))
1761  return result;
1762 
1763  BSTR bstrNames = QStringToBSTR(QLatin1String(property.name()));
1764  DISPID dispId;
1765  GetIDsOfNames(IID_NULL, (BSTR*)&bstrNames, 1, LOCALE_USER_DEFAULT, &dispId);
1766  result = dispId != DISPID_UNKNOWN;
1767  SysFreeString(bstrNames);
1768 
1769  return result;
1770 }
1771 
1772 
1781 {
1782  if (isInPlaceActive) {
1783  if (m_hWnd)
1784  ::InvalidateRect(m_hWnd, 0, true);
1785  else if (m_spInPlaceSite)
1786  m_spInPlaceSite->InvalidateRect(NULL, true);
1787  } else if (m_spAdviseSink) {
1788  m_spAdviseSink->OnViewChange(DVASPECT_CONTENT, -1);
1789  for (int i = 0; i < adviseSinks.count(); ++i) {
1790  adviseSinks.at(i).pAdvSink->OnViewChange(DVASPECT_CONTENT, -1);
1791  }
1792  }
1793 }
1794 
1798 void QAxServerBase::resize(const QSize &size)
1799 {
1800  if (!isWidget || !qt.widget || !size.isValid() || size == QSize(0, 0))
1801  return;
1802 
1803  QSize oldSize = qt.widget->size();
1804  qt.widget->resize(size);
1805  QSize newSize = qt.widget->size();
1806  // make sure we get a resize event even if not embedded as a control
1807  if (!m_hWnd && !qt.widget->isVisible() && newSize != oldSize) {
1808  QResizeEvent resizeEvent(newSize, oldSize);
1809 #ifndef QT_DLL // import from static library
1810  extern bool qt_sendSpontaneousEvent(QObject*,QEvent*);
1811 #endif
1812  qt_sendSpontaneousEvent(qt.widget, &resizeEvent);
1813  }
1814  m_currentExtent = qt.widget->size();
1815 }
1816 
1826 {
1827  if (!isWidget || !qt.widget)
1828  return;
1829 
1830  const QSize sizeHint = qt.widget->sizeHint();
1831  const QSize size = qt.widget->size();
1832  if (sizeHint.isValid()) { // if provided, adjust to sizeHint
1833  QSize newSize = size;
1834  if (!qt.widget->testAttribute(Qt::WA_Resized)) {
1835  newSize = sizeHint;
1836  } else { // according to sizePolicy rules if already resized
1837  QSizePolicy sizePolicy = qt.widget->sizePolicy();
1838  if (sizeHint.width() > size.width() && !(sizePolicy.horizontalPolicy() & QSizePolicy::ShrinkFlag))
1839  newSize.setWidth(sizeHint.width());
1840  if (sizeHint.width() < size.width() && !(sizePolicy.horizontalPolicy() & QSizePolicy::GrowFlag))
1841  newSize.setWidth(sizeHint.width());
1842  if (sizeHint.height() > size.height() && !(sizePolicy.verticalPolicy() & QSizePolicy::ShrinkFlag))
1843  newSize.setHeight(sizeHint.height());
1844  if (sizeHint.height() < size.height() && !(sizePolicy.verticalPolicy() & QSizePolicy::GrowFlag))
1845  newSize.setHeight(sizeHint.height());
1846  }
1847  resize(newSize);
1848 
1849  // set an initial size suitable for embedded controls
1850  } else if (!qt.widget->testAttribute(Qt::WA_Resized)) {
1851  resize(QSize(100, 100));
1852  qt.widget->setAttribute(Qt::WA_Resized, false);
1853  }
1854 }
1855 
1865 {
1866  if (!isWidget || !qt.widget || qt.widget->mask().isEmpty())
1867  return;
1868 
1869  QRegion rgn = qt.widget->mask();
1870  HRGN hrgn = rgn.handle();
1871 
1872  // Since SetWindowRegion takes ownership
1873  HRGN wr = CreateRectRgn(0,0,0,0);
1874  CombineRgn(wr, hrgn, 0, RGN_COPY);
1875  SetWindowRgn(m_hWnd, wr, true);
1876 }
1877 
1878 static bool checkHRESULT(HRESULT hres)
1879 {
1880  const char *name = 0;
1881  switch(hres) {
1882  case S_OK:
1883  return true;
1884  case DISP_E_BADPARAMCOUNT:
1885 #if defined(QT_CHECK_STATE)
1886  qWarning("QAxBase: Error calling IDispatch member %s: Bad parameter count", name);
1887 #endif
1888  return false;
1889  case DISP_E_BADVARTYPE:
1890 #if defined(QT_CHECK_STATE)
1891  qWarning("QAxBase: Error calling IDispatch member %s: Bad variant type", name);
1892 #endif
1893  return false;
1894  case DISP_E_EXCEPTION:
1895 #if defined(QT_CHECK_STATE)
1896  qWarning("QAxBase: Error calling IDispatch member %s: Exception thrown by server", name);
1897 #endif
1898  return false;
1899  case DISP_E_MEMBERNOTFOUND:
1900 #if defined(QT_CHECK_STATE)
1901  qWarning("QAxBase: Error calling IDispatch member %s: Member not found", name);
1902 #endif
1903  return false;
1904  case DISP_E_NONAMEDARGS:
1905 #if defined(QT_CHECK_STATE)
1906  qWarning("QAxBase: Error calling IDispatch member %s: No named arguments", name);
1907 #endif
1908  return false;
1909  case DISP_E_OVERFLOW:
1910 #if defined(QT_CHECK_STATE)
1911  qWarning("QAxBase: Error calling IDispatch member %s: Overflow", name);
1912 #endif
1913  return false;
1914  case DISP_E_PARAMNOTFOUND:
1915 #if defined(QT_CHECK_STATE)
1916  qWarning("QAxBase: Error calling IDispatch member %s: Parameter not found", name);
1917 #endif
1918  return false;
1919  case DISP_E_TYPEMISMATCH:
1920 #if defined(QT_CHECK_STATE)
1921  qWarning("QAxBase: Error calling IDispatch member %s: Type mismatch", name);
1922 #endif
1923  return false;
1924  case DISP_E_UNKNOWNINTERFACE:
1925 #if defined(QT_CHECK_STATE)
1926  qWarning("QAxBase: Error calling IDispatch member %s: Unknown interface", name);
1927 #endif
1928  return false;
1929  case DISP_E_UNKNOWNLCID:
1930 #if defined(QT_CHECK_STATE)
1931  qWarning("QAxBase: Error calling IDispatch member %s: Unknown locale ID", name);
1932 #endif
1933  return false;
1934  case DISP_E_PARAMNOTOPTIONAL:
1935 #if defined(QT_CHECK_STATE)
1936  qWarning("QAxBase: Error calling IDispatch member %s: Non-optional parameter missing", name);
1937 #endif
1938  return false;
1939  default:
1940 #if defined(QT_CHECK_STATE)
1941  qWarning("QAxBase: Error calling IDispatch member %s: Unknown error", name);
1942 #endif
1943  return false;
1944  }
1945 }
1946 
1947 static inline QByteArray paramType(const QByteArray &ptype, bool *out)
1948 {
1949  *out = ptype.endsWith('&') || ptype.endsWith("**");
1950  if (*out) {
1951  QByteArray res(ptype);
1952  res.truncate(res.length() - 1);
1953  return res;
1954  }
1955 
1956  return ptype;
1957 }
1958 
1966 {
1968 
1969  if (index == -1) {
1970  if (sender() && m_spInPlaceFrame) {
1971  if (qobject_cast<QStatusBar*>(sender()) != statusBar)
1972  return true;
1973 
1974  if (statusBar->isHidden()) {
1975  QString message = *(QString*)argv[1];
1976  m_spInPlaceFrame->SetStatusText(QStringToBSTR(message));
1977  }
1978  }
1979  return true;
1980  }
1981 
1982  if (freezeEvents || inDesignMode)
1983  return true;
1984 
1985  ensureMetaData();
1986 
1987  // get the signal information.
1988  const QMetaObject *mo = qt.object->metaObject();
1989  QMetaMethod signal;
1990  DISPID eventId = index;
1991  int pcount = 0;
1992  QByteArray type;
1993  QList<QByteArray> ptypes;
1994 
1995  switch(index) {
1996  case DISPID_KEYDOWN:
1997  case DISPID_KEYUP:
1998  pcount = 2;
1999  ptypes << "int&" << "int";
2000  break;
2001  case DISPID_KEYPRESS:
2002  pcount = 1;
2003  ptypes << "int&";
2004  break;
2005  case DISPID_MOUSEDOWN:
2006  case DISPID_MOUSEMOVE:
2007  case DISPID_MOUSEUP:
2008  pcount = 4;
2009  ptypes << "int" << "int" << "int" << "int";
2010  break;
2011  case DISPID_CLICK:
2012  pcount = 0;
2013  break;
2014  case DISPID_DBLCLICK:
2015  pcount = 0;
2016  break;
2017  default:
2018  {
2019  signal = mo->method(index);
2021  type = signal.typeName();
2022  QByteArray signature(signal.signature());
2023  QByteArray name(signature);
2024  name.truncate(name.indexOf('('));
2025 
2026  eventId = signalCache.value(index, -1);
2027  if (eventId == -1) {
2028  ITypeInfo *eventInfo = 0;
2029  qAxTypeLibrary->GetTypeInfoOfGuid(qAxFactory()->eventsID(class_name), &eventInfo);
2030  if (eventInfo) {
2031  QString uni_name = QLatin1String(name);
2032  const OLECHAR *olename = reinterpret_cast<const OLECHAR *>(uni_name.utf16());
2033  eventInfo->GetIDsOfNames((OLECHAR**)&olename, 1, &eventId);
2034  eventInfo->Release();
2035  }
2036  }
2037 
2038  signature = signature.mid(name.length() + 1);
2039  signature.truncate(signature.length() - 1);
2040 
2041  if (!signature.isEmpty())
2042  ptypes = signature.split(',');
2043 
2044  pcount = ptypes.count();
2045  }
2046  break;
2047  }
2048  if (pcount && !argv) {
2049  qWarning("QAxServerBase::qt_metacall: Missing %d arguments", pcount);
2050  return false;
2051  }
2052  if (eventId == -1)
2053  return false;
2054 
2055  // For all connected event sinks...
2056  IConnectionPoint *cpoint = 0;
2057  GUID IID_QAxEvents = qAxFactory()->eventsID(class_name);
2058  FindConnectionPoint(IID_QAxEvents, &cpoint);
2059  if (cpoint) {
2060  IEnumConnections *clist = 0;
2061  cpoint->EnumConnections(&clist);
2062  if (clist) {
2063  clist->Reset();
2064  ULONG cc = 1;
2065  CONNECTDATA c[1];
2066  clist->Next(cc, (CONNECTDATA*)&c, &cc);
2067  if (cc) {
2068  // setup parameters
2069  unsigned int argErr = 0;
2070  DISPPARAMS dispParams;
2071  dispParams.cArgs = pcount;
2072  dispParams.cNamedArgs = 0;
2073  dispParams.rgdispidNamedArgs = 0;
2074  dispParams.rgvarg = 0;
2075 
2076  if (pcount) // Use malloc/free for eval package compatibility
2077  dispParams.rgvarg = (VARIANTARG*)malloc(pcount * sizeof(VARIANTARG));
2078  int p = 0;
2079  for (p = 0; p < pcount; ++p) {
2080  VARIANT *arg = dispParams.rgvarg + (pcount - p - 1);
2081  VariantInit(arg);
2082 
2083  bool out;
2084  QByteArray ptype = paramType(ptypes.at(p), &out);
2085  QVariant variant;
2086  if (mo->indexOfEnumerator(ptype) != -1) {
2087  // convert enum values to int
2088  variant = QVariant(*reinterpret_cast<int *>(argv[p+1]));
2089  } else {
2091  if (vt == QVariant::UserType) {
2092  if (ptype.endsWith('*')) {
2093  variant = QVariant(QMetaType::type(ptype), (void**)argv[p+1]);
2094  // variant.setValue(*(void**)(argv[p + 1]), ptype);
2095  } else {
2096  variant = QVariant(QMetaType::type(ptype), argv[p+1]);
2097  // variant.setValue(argv[p + 1], ptype);
2098  }
2099  } else {
2100  variant = QVariant(vt, argv[p + 1]);
2101  }
2102  }
2103 
2104  QVariantToVARIANT(variant, *arg, type, out);
2105  }
2106 
2107  VARIANT retval;
2108  VariantInit(&retval);
2109  VARIANT *pretval = 0;
2110  if (!type.isEmpty())
2111  pretval = &retval;
2112 
2113  // call listeners (through IDispatch)
2114  while (cc) {
2115  if (c->pUnk) {
2116  IDispatch *disp = 0;
2117  c->pUnk->QueryInterface(IID_QAxEvents, (void**)&disp);
2118  if (disp) {
2119  disp->Invoke(eventId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispParams, pretval, 0, &argErr);
2120 
2121  // update out-parameters and return value
2122  if (index > 0) {
2123  for (p = 0; p < pcount; ++p) {
2124  bool out;
2125  QByteArray ptype = paramType(ptypes.at(p), &out);
2126  if (out)
2127  QVariantToVoidStar(VARIANTToQVariant(dispParams.rgvarg[pcount - p - 1], ptype), argv[p+1], ptype);
2128  }
2129  if (pretval)
2130  QVariantToVoidStar(VARIANTToQVariant(retval, type), argv[0], type);
2131  }
2132  disp->Release();
2133  }
2134  c->pUnk->Release(); // AddRef'ed by clist->Next implementation
2135  }
2136  clist->Next(cc, (CONNECTDATA*)&c, &cc);
2137  }
2138 
2139  // clean up
2140  for (p = 0; p < pcount; ++p)
2141  clearVARIANT(dispParams.rgvarg+p);
2142  free(dispParams.rgvarg);
2143  }
2144  clist->Release();
2145  }
2146  cpoint->Release();
2147  }
2148 
2149  return true;
2150 }
2151 
2157 {
2158  long dispId = -1;
2159 
2160  IConnectionPoint *cpoint = 0;
2161  FindConnectionPoint(IID_IPropertyNotifySink, &cpoint);
2162  if (cpoint) {
2163  IEnumConnections *clist = 0;
2164  cpoint->EnumConnections(&clist);
2165  if (clist) {
2166  clist->Reset();
2167  ULONG cc = 1;
2168  CONNECTDATA c[1];
2169  clist->Next(cc, (CONNECTDATA*)&c, &cc);
2170  if (cc) {
2171  if (dispId == -1) {
2172  BSTR bstr = QStringToBSTR(QLatin1String(property));
2173  GetIDsOfNames(IID_NULL, &bstr, 1, LOCALE_USER_DEFAULT, &dispId);
2174  SysFreeString(bstr);
2175  }
2176  if (dispId != -1) while (cc) {
2177  if (c->pUnk) {
2178  IPropertyNotifySink *sink = 0;
2179  c->pUnk->QueryInterface(IID_IPropertyNotifySink, (void**)&sink);
2180  bool disallows = sink && sink->OnRequestEdit(dispId) == S_FALSE;
2181  sink->Release();
2182  c->pUnk->Release();
2183  if (disallows) { // a client disallows the property to change
2184  clist->Release();
2185  cpoint->Release();
2186  return false;
2187  }
2188  }
2189  clist->Next(cc, (CONNECTDATA*)&c, &cc);
2190  }
2191  }
2192  clist->Release();
2193  }
2194  cpoint->Release();
2195  }
2196  dirtyflag = true;
2197  return true;
2198 }
2199 
2205 {
2206  long dispId = -1;
2207 
2208  IConnectionPoint *cpoint = 0;
2209  FindConnectionPoint(IID_IPropertyNotifySink, &cpoint);
2210  if (cpoint) {
2211  IEnumConnections *clist = 0;
2212  cpoint->EnumConnections(&clist);
2213  if (clist) {
2214  clist->Reset();
2215  ULONG cc = 1;
2216  CONNECTDATA c[1];
2217  clist->Next(cc, (CONNECTDATA*)&c, &cc);
2218  if (cc) {
2219  if (dispId == -1) {
2220  BSTR bstr = QStringToBSTR(QLatin1String(property));
2221  GetIDsOfNames(IID_NULL, &bstr, 1, LOCALE_USER_DEFAULT, &dispId);
2222  SysFreeString(bstr);
2223  }
2224  if (dispId != -1) while (cc) {
2225  if (c->pUnk) {
2226  IPropertyNotifySink *sink = 0;
2227  c->pUnk->QueryInterface(IID_IPropertyNotifySink, (void**)&sink);
2228  if (sink) {
2229  sink->OnChanged(dispId);
2230  sink->Release();
2231  }
2232  c->pUnk->Release();
2233  }
2234  clist->Next(cc, (CONNECTDATA*)&c, &cc);
2235  }
2236  }
2237  clist->Release();
2238  }
2239  cpoint->Release();
2240  }
2241  dirtyflag = true;
2242 }
2243 
2244 //**** IProvideClassInfo
2245 /*
2246  Provide the ITypeInfo implementation for the COM class.
2247 */
2248 HRESULT WINAPI QAxServerBase::GetClassInfo(ITypeInfo** pptinfo)
2249 {
2250  if (!pptinfo)
2251  return E_POINTER;
2252 
2253  *pptinfo = 0;
2254  if (!qAxTypeLibrary)
2255  return DISP_E_BADINDEX;
2256 
2257  return qAxTypeLibrary->GetTypeInfoOfGuid(qAxFactory()->classID(class_name), pptinfo);
2258 }
2259 
2260 //**** IProvideClassInfo2
2261 /*
2262  Provide the ID of the event interface.
2263 */
2264 HRESULT WINAPI QAxServerBase::GetGUID(DWORD dwGuidKind, GUID* pGUID)
2265 {
2266  if (!pGUID)
2267  return E_POINTER;
2268 
2269  if (dwGuidKind == GUIDKIND_DEFAULT_SOURCE_DISP_IID) {
2270  *pGUID = qAxFactory()->eventsID(class_name);
2271  return S_OK;
2272  }
2273  *pGUID = GUID_NULL;
2274  return E_FAIL;
2275 }
2276 
2277 //**** IDispatch
2278 /*
2279  Returns the number of class infos for this IDispatch.
2280 */
2282 {
2283  if (!pctinfo)
2284  return E_POINTER;
2285 
2286  *pctinfo = qAxTypeLibrary ? 1 : 0;
2287  return S_OK;
2288 }
2289 
2290 /*
2291  Provides the ITypeInfo for this IDispatch implementation.
2292 */
2293 HRESULT WINAPI QAxServerBase::GetTypeInfo(UINT itinfo, LCID /*lcid*/, ITypeInfo** pptinfo)
2294 {
2295  if (!pptinfo)
2296  return E_POINTER;
2297 
2298  if (!qAxTypeLibrary)
2299  return DISP_E_BADINDEX;
2300 
2301  ensureMetaData();
2302 
2303  *pptinfo = m_spTypeInfo;
2304  (*pptinfo)->AddRef();
2305 
2306  return S_OK;
2307 }
2308 
2309 /*
2310  Provides the names of the methods implemented in this IDispatch implementation.
2311 */
2312 HRESULT WINAPI QAxServerBase::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
2313  LCID /*lcid*/, DISPID* rgdispid)
2314 {
2315  if (!rgszNames || !rgdispid)
2316  return E_POINTER;
2317 
2318  if (!qAxTypeLibrary)
2319  return DISP_E_UNKNOWNNAME;
2320 
2321  ensureMetaData();
2322  if (!m_spTypeInfo)
2323  return DISP_E_UNKNOWNNAME;
2324 
2325  return m_spTypeInfo->GetIDsOfNames(rgszNames, cNames, rgdispid);
2326 }
2327 
2328 /*
2329  Map the COM call to the Qt slot/property for \a dispidMember.
2330 */
2331 HRESULT WINAPI QAxServerBase::Invoke(DISPID dispidMember, REFIID riid,
2332  LCID /*lcid*/, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult,
2333  EXCEPINFO* pexcepinfo, UINT* puArgErr)
2334 {
2335  if (riid != IID_NULL)
2336  return DISP_E_UNKNOWNINTERFACE;
2337  if (!theObject)
2338  return E_UNEXPECTED;
2339 
2340  HRESULT res = DISP_E_MEMBERNOTFOUND;
2341 
2342  bool uniqueIndex = wFlags == DISPATCH_PROPERTYGET || wFlags == DISPATCH_PROPERTYPUT || wFlags == DISPATCH_METHOD;
2343 
2344  int index = uniqueIndex ? indexCache.value(dispidMember, -1) : -1;
2345  QByteArray name;
2346  if (index == -1) {
2347  ensureMetaData();
2348 
2349  // This property or method is invoked when an ActiveX client specifies
2350  // the object name without a property or method. We only support property.
2351  if (dispidMember == DISPID_VALUE && (wFlags == DISPATCH_PROPERTYGET || wFlags == DISPATCH_PROPERTYPUT)) {
2352  const QMetaObject *mo = qt.object->metaObject();
2353  index = mo->indexOfClassInfo("DefaultProperty");
2354  if (index != -1) {
2355  name = mo->classInfo(index).value();
2356  index = mo->indexOfProperty(name);
2357  }
2358  } else {
2359  BSTR bname;
2360  UINT cname = 0;
2361  if (m_spTypeInfo)
2362  m_spTypeInfo->GetNames(dispidMember, &bname, 1, &cname);
2363  if (!cname)
2364  return res;
2365 
2366  name = QString::fromWCharArray(bname).toLatin1();
2367  SysFreeString(bname);
2368  }
2369  }
2370 
2371  const QMetaObject *mo = qt.object->metaObject();
2372  QSize oldSizeHint;
2373  if (isWidget)
2374  oldSizeHint = qt.widget->sizeHint();
2375 
2376  switch (wFlags) {
2377  case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
2378  case DISPATCH_PROPERTYGET:
2379  {
2380  if (index == -1) {
2381  index = mo->indexOfProperty(name);
2382  if (index == -1 && wFlags == DISPATCH_PROPERTYGET)
2383  return res;
2384  }
2385 
2387  if (index < mo->propertyCount())
2388  property = mo->property(index);
2389 
2390  if (property.isReadable()) {
2391  if (!pvarResult)
2392  return DISP_E_PARAMNOTOPTIONAL;
2393  if (pDispParams->cArgs ||
2394  pDispParams->cNamedArgs)
2395  return DISP_E_BADPARAMCOUNT;
2396 
2397  QVariant var = qt.object->property(property.name());
2398  if (!var.isValid())
2399  res = DISP_E_MEMBERNOTFOUND;
2400  else if (!QVariantToVARIANT(var, *pvarResult))
2401  res = DISP_E_TYPEMISMATCH;
2402  else
2403  res = S_OK;
2404  break;
2405  } else if (wFlags == DISPATCH_PROPERTYGET) {
2406  break;
2407  }
2408  }
2409  // FALLTHROUGH if wFlags == DISPATCH_PROPERTYGET|DISPATCH_METHOD AND not a property.
2410  case DISPATCH_METHOD:
2411  {
2412  int nameLength = 0;
2413  if (index == -1) {
2414  nameLength = name.length();
2415  name += '(';
2416  // no parameter - shortcut
2417  if (!pDispParams->cArgs)
2418  index = mo->indexOfSlot((name + ')'));
2419  // search
2420  if (index == -1) {
2421  for (int i = 0; i < mo->methodCount(); ++i) {
2422  const QMetaMethod slot(mo->method(i));
2423  if (slot.methodType() == QMetaMethod::Slot && QByteArray(slot.signature()).startsWith(name)) {
2424  index = i;
2425  break;
2426  }
2427  }
2428  // resolve overloads
2429  if (index == -1) {
2430  QRegExp regexp(QLatin1String("_([0-9])\\("));
2431  if (regexp.lastIndexIn(QString::fromLatin1(name.constData())) != -1) {
2432  name = name.left(name.length() - regexp.cap(0).length()) + '(';
2433  int overload = regexp.cap(1).toInt() + 1;
2434 
2435  for (int s = 0; s < qt.object->metaObject()->methodCount(); ++s) {
2436  QMetaMethod slot = qt.object->metaObject()->method(s);
2437  if (slot.methodType() == QMetaMethod::Slot && QByteArray(slot.signature()).startsWith(name)) {
2438  if (!--overload) {
2439  index = s;
2440  break;
2441  }
2442  }
2443  }
2444  }
2445  }
2446  if (index == -1)
2447  return res;
2448  }
2449  }
2450 
2451  int lookupIndex = index;
2452 
2453  // get slot info
2454  QMetaMethod slot(mo->method(index));
2455  Q_ASSERT(slot.methodType() == QMetaMethod::Slot);
2456  QByteArray type = slot.typeName();
2457  name = slot.signature();
2458  nameLength = name.indexOf('(');
2459  QByteArray prototype = name.mid(nameLength + 1);
2460  prototype.truncate(prototype.length() - 1);
2461  QList<QByteArray> ptypes;
2462  if (!prototype.isEmpty())
2463  ptypes = prototype.split(',');
2464  int pcount = ptypes.count();
2465 
2466  // verify parameter count
2467  if (pcount > pDispParams->cArgs) {
2468  // count cloned slots immediately following the real thing
2469  int defArgs = 0;
2470  while (index < mo->methodCount()) {
2471  ++index;
2472  slot = mo->method(index);
2473  if (!(slot.attributes() & QMetaMethod::Cloned))
2474  break;
2475  --pcount;
2476  // found a matching overload. ptypes still valid
2477  if (pcount <= pDispParams->cArgs)
2478  break;
2479  }
2480  // still wrong :(
2481  if (pcount > pDispParams->cArgs)
2482  return DISP_E_PARAMNOTOPTIONAL;
2483  } else if (pcount < pDispParams->cArgs) {
2484  return DISP_E_BADPARAMCOUNT;
2485  }
2486 
2487  // setup parameters (pcount + return)
2488  bool ok = true;
2489  void *static_argv[QAX_NUM_PARAMS + 1];
2490  QVariant static_varp[QAX_NUM_PARAMS + 1];
2491  void *static_argv_pointer[QAX_NUM_PARAMS + 1];
2492 
2493  int totalParam = pcount;
2494  if (!type.isEmpty())
2495  ++totalParam;
2496 
2497  void **argv = 0; // the actual array passed into qt_metacall
2498  void **argv_pointer = 0; // in case we need an additional level of indirection
2499  QVariant *varp = 0; // QVariants to hold the temporary Qt data object for us
2500 
2501  if (totalParam) {
2502  if (totalParam <= QAX_NUM_PARAMS) {
2503  argv = static_argv;
2504  argv_pointer = static_argv_pointer;
2505  varp = static_varp;
2506  } else {
2507  argv = new void*[pcount + 1];
2508  argv_pointer = new void*[pcount + 1];
2509  varp = new QVariant[pcount + 1];
2510  }
2511 
2512  argv_pointer[0] = 0;
2513  }
2514 
2515  for (int p = 0; p < pcount; ++p) {
2516  // map the VARIANT to the void*
2517  bool out;
2518  QByteArray ptype = paramType(ptypes.at(p), &out);
2519  varp[p + 1] = VARIANTToQVariant(pDispParams->rgvarg[pcount - p - 1], ptype);
2520  argv_pointer[p + 1] = 0;
2521  if (varp[p + 1].isValid()) {
2522  if (varp[p + 1].type() == QVariant::UserType) {
2523  argv[p + 1] = varp[p + 1].data();
2524  } else if (ptype == "QVariant") {
2525  argv[p + 1] = varp + p + 1;
2526  } else {
2527  argv[p + 1] = const_cast<void*>(varp[p + 1].constData());
2528  if (ptype.endsWith('*')) {
2529  argv_pointer[p + 1] = argv[p + 1];
2530  argv[p + 1] = argv_pointer + p + 1;
2531  }
2532  }
2533  } else if (ptype == "QVariant") {
2534  argv[p + 1] = varp + p + 1;
2535  } else {
2536  if (puArgErr)
2537  *puArgErr = pcount-p-1;
2538  ok = false;
2539  }
2540  }
2541 
2542  // return value
2543  if (!type.isEmpty()) {
2545  if (vt == QVariant::UserType)
2546  vt = QVariant::Invalid;
2547  varp[0] = QVariant(vt);
2548  if (varp[0].type() == QVariant::Invalid && mo->indexOfEnumerator(slot.typeName()) != -1)
2549  varp[0] = QVariant(QVariant::Int);
2550 
2551  if (varp[0].type() == QVariant::Invalid) {
2552  if (type == "QVariant")
2553  argv[0] = varp;
2554  else
2555  argv[0] = 0;
2556  } else {
2557  argv[0] = const_cast<void*>(varp[0].constData());
2558  }
2559  if (type.endsWith('*')) {
2560  argv_pointer[0] = argv[0];
2561  argv[0] = argv_pointer;
2562  }
2563  }
2564 
2565  // call the slot if everthing went fine.
2566  if (ok) {
2567  ++invokeCount;
2568  qt.object->qt_metacall(QMetaObject::InvokeMetaMethod, index, argv);
2569  if (--invokeCount < 0)
2570  invokeCount = 0;
2571 
2572  // update reference parameters and return value
2573  for (int p = 0; p < pcount; ++p) {
2574  bool out;
2575  QByteArray ptype = paramType(ptypes.at(p), &out);
2576  if (out) {
2577  if (!QVariantToVARIANT(varp[p + 1], pDispParams->rgvarg[pcount - p - 1], ptype, out))
2578  ok = false;
2579  }
2580  }
2581  if (!type.isEmpty() && pvarResult) {
2582  if (!varp[0].isValid() && type != "QVariant")
2583  varp[0] = QVariant(QMetaType::type(type), argv_pointer);
2584 // varp[0].setValue(argv_pointer[0], type);
2585  ok = QVariantToVARIANT(varp[0], *pvarResult, type);
2586  }
2587  }
2588  if (argv && argv != static_argv) {
2589  delete []argv;
2590  delete []argv_pointer;
2591  delete []varp;
2592  }
2593 
2594  res = ok ? S_OK : DISP_E_TYPEMISMATCH;
2595 
2596  // reset in case index changed for default-arg handling
2597  index = lookupIndex;
2598  }
2599  break;
2600  case DISPATCH_PROPERTYPUT:
2601  case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF:
2602  {
2603  if (index == -1) {
2604  index = mo->indexOfProperty(name);
2605  if (index == -1)
2606  return res;
2607  }
2608 
2610  if (index < mo->propertyCount())
2611  property = mo->property(index);
2612  if (!property.isWritable())
2613  return DISP_E_MEMBERNOTFOUND;
2614  if (!pDispParams->cArgs)
2615  return DISP_E_PARAMNOTOPTIONAL;
2616  if (pDispParams->cArgs != 1 ||
2617  pDispParams->cNamedArgs != 1 ||
2618  *pDispParams->rgdispidNamedArgs != DISPID_PROPERTYPUT)
2619  return DISP_E_BADPARAMCOUNT;
2620 
2621  QVariant var = VARIANTToQVariant(*pDispParams->rgvarg, property.typeName(), property.type());
2622  if (!var.isValid()) {
2623  if (puArgErr)
2624  *puArgErr = 0;
2625  return DISP_E_BADVARTYPE;
2626  }
2627  if (!qt.object->setProperty(property.name(), var)) {
2628  if (puArgErr)
2629  *puArgErr = 0;
2630  return DISP_E_TYPEMISMATCH;
2631  }
2632 
2633  res = S_OK;
2634  }
2635  break;
2636 
2637  default:
2638  break;
2639  }
2640 
2641  // maybe calling a setter? Notify client about changes
2642  switch(wFlags) {
2643  case DISPATCH_METHOD:
2644  case DISPATCH_PROPERTYPUT:
2645  case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF:
2646  if (m_spAdviseSink || adviseSinks.count()) {
2647  FORMATETC fmt;
2648  fmt.cfFormat = 0;
2649  fmt.ptd = 0;
2650  fmt.dwAspect = DVASPECT_CONTENT;
2651  fmt.lindex = -1;
2652  fmt.tymed = TYMED_NULL;
2653 
2654  STGMEDIUM stg;
2655  stg.tymed = TYMED_NULL;
2656  stg.pUnkForRelease = 0;
2657  stg.hBitmap = 0; // initializes the whole union
2658 
2659  if (m_spAdviseSink) {
2660  m_spAdviseSink->OnViewChange(DVASPECT_CONTENT, -1);
2661  m_spAdviseSink->OnDataChange(&fmt, &stg);
2662  }
2663  for (int i = 0; i < adviseSinks.count(); ++i) {
2664  adviseSinks.at(i).pAdvSink->OnDataChange(&fmt, &stg);
2665  }
2666  }
2667 
2668  dirtyflag = true;
2669  break;
2670  default:
2671  break;
2672  }
2673 
2674  if (index != -1 && uniqueIndex)
2675  indexCache.insert(dispidMember, index);
2676 
2677  if (exception) {
2678  if (pexcepinfo) {
2679  memset(pexcepinfo, 0, sizeof(EXCEPINFO));
2680 
2681  pexcepinfo->wCode = exception->code;
2682  if (!exception->src.isNull())
2683  pexcepinfo->bstrSource = QStringToBSTR(exception->src);
2684  if (!exception->desc.isNull())
2685  pexcepinfo->bstrDescription = QStringToBSTR(exception->desc);
2686  if (!exception->context.isNull()) {
2687  QString context = exception->context;
2688  int contextID = 0;
2689  int br = context.indexOf(QLatin1Char('['));
2690  if (br != -1) {
2691  context = context.mid(br+1);
2692  context = context.left(context.length() - 1);
2693  contextID = context.toInt();
2694 
2695  context = exception->context;
2696  context = context.left(br-1);
2697  }
2698  pexcepinfo->bstrHelpFile = QStringToBSTR(context);
2699  pexcepinfo->dwHelpContext = contextID;
2700  }
2701  }
2702  delete exception;
2703  exception = 0;
2704  return DISP_E_EXCEPTION;
2705  } else if (isWidget) {
2706  QSize sizeHint = qt.widget->sizeHint();
2707  if (oldSizeHint != sizeHint) {
2708  updateGeometry();
2709  if (m_spInPlaceSite) {
2710  RECT rect = {0, 0, sizeHint.width(), sizeHint.height()};
2711  m_spInPlaceSite->OnPosRectChange(&rect);
2712  }
2713  }
2714  updateMask();
2715  }
2716 
2717  return res;
2718 }
2719 
2720 //**** IConnectionPointContainer
2721 /*
2722  Provide the IEnumConnectionPoints implemented in the QAxSignalVec class.
2723 */
2724 HRESULT WINAPI QAxServerBase::EnumConnectionPoints(IEnumConnectionPoints **epoints)
2725 {
2726  if (!epoints)
2727  return E_POINTER;
2728  *epoints = new QAxSignalVec(points);
2729  (*epoints)->AddRef();
2730  return S_OK;
2731 }
2732 
2733 /*
2734  Provide the IConnectionPoint implemented in the QAxConnection for \a iid.
2735 */
2736 HRESULT WINAPI QAxServerBase::FindConnectionPoint(REFIID iid, IConnectionPoint **cpoint)
2737 {
2738  if (!cpoint)
2739  return E_POINTER;
2740 
2741  IConnectionPoint *cp = points[iid];
2742  *cpoint = cp;
2743  if (cp) {
2744  cp->AddRef();
2745  return S_OK;
2746  }
2747  return CONNECT_E_NOCONNECTION;
2748 }
2749 
2750 //**** IPersistStream
2751 /*
2752  \reimp
2753 
2754  See documentation of IPersistStorage::IsDirty.
2755 */
2757 {
2758  return dirtyflag ? S_OK : S_FALSE;
2759 }
2760 
2761 HRESULT WINAPI QAxServerBase::Load(IStream *pStm)
2762 {
2763  STATSTG stat;
2764  HRESULT hres = pStm->Stat(&stat, STATFLAG_DEFAULT);
2765  bool openAsText = false;
2766  QByteArray qtarray;
2767  if (hres == S_OK) {
2768  QString streamName = QString::fromWCharArray(stat.pwcsName);
2769  CoTaskMemFree(stat.pwcsName);
2770  openAsText = streamName == QLatin1String("SomeStreamName");
2771  if (stat.cbSize.HighPart) // more than 4GB - too large!
2772  return S_FALSE;
2773 
2774  qtarray.resize(stat.cbSize.LowPart);
2775  ULONG read;
2776  pStm->Read(qtarray.data(), stat.cbSize.LowPart, &read);
2777  } else if (hres == E_NOTIMPL) {
2778  ULONG read = 0;
2779  while (hres != S_FALSE) {
2780  QByteArray arrayRead;
2781  arrayRead.resize(4098);
2782  hres = pStm->Read(arrayRead.data(), arrayRead.size(), &read);
2783  if (hres != S_OK && hres != S_FALSE) {
2784  qtarray.resize(0);
2785  break;
2786  } else if (read == 0)
2787  break;
2788  qtarray.append(arrayRead);
2789  }
2790  }
2791  const QMetaObject *mo = qt.object->metaObject();
2792 
2793  QBuffer qtbuffer(&qtarray);
2794  QByteArray mimeType = mo->classInfo(mo->indexOfClassInfo("MIME")).value();
2795  if (!mimeType.isEmpty()) {
2796  mimeType = mimeType.left(mimeType.indexOf(':')); // first type
2797  QAxBindable *axb = (QAxBindable*)qt.object->qt_metacast("QAxBindable");
2798  if (axb && axb->readData(&qtbuffer, QString::fromLatin1(mimeType)))
2799  return S_OK;
2800  }
2801 
2802  qtbuffer.close(); // resets
2803  qtbuffer.open(openAsText ? (QIODevice::ReadOnly | QIODevice::Text) : QIODevice::ReadOnly);
2804 
2805  QDataStream qtstream(&qtbuffer);
2806  int version;
2807  qtstream >> version;
2808  qtstream.setVersion(version);
2809  int more = 0;
2810  qtstream >> more;
2811 
2812  while (!qtbuffer.atEnd() && more) {
2813  QString propname;
2814  QVariant value;
2815  qtstream >> propname;
2816  if (propname.isEmpty())
2817  break;
2818  qtstream >> value;
2819  qtstream >> more;
2820 
2821  int idx = mo->indexOfProperty(propname.toLatin1());
2822  QMetaProperty property = mo->property(idx);
2823  if (property.isWritable())
2824  qt.object->setProperty(propname.toLatin1(), value);
2825  }
2826  return S_OK;
2827 }
2828 
2829 HRESULT WINAPI QAxServerBase::Save(IStream *pStm, BOOL clearDirty)
2830 {
2831  const QMetaObject *mo = qt.object->metaObject();
2832 
2833  QBuffer qtbuffer;
2834  bool saved = false;
2835  QByteArray mimeType = mo->classInfo(mo->indexOfClassInfo("MIME")).value();
2836  if (!mimeType.isEmpty()) {
2837  QAxBindable *axb = (QAxBindable*)qt.object->qt_metacast("QAxBindable");
2838  saved = axb && axb->writeData(&qtbuffer);
2839  qtbuffer.close();
2840  }
2841 
2842  if (!saved) {
2843  qtbuffer.open(QIODevice::WriteOnly);
2844  QDataStream qtstream(&qtbuffer);
2845  qtstream << qtstream.version();
2846 
2847  for (int prop = 0; prop < mo->propertyCount(); ++prop) {
2848  if (!isPropertyExposed(prop))
2849  continue;
2850  QMetaProperty metaprop = mo->property(prop);
2851  if (QByteArray(metaprop.typeName()).endsWith('*'))
2852  continue;
2853  QString property = QLatin1String(metaprop.name());
2854  QVariant qvar = qt.object->property(metaprop.name());
2855  if (qvar.isValid()) {
2856  qtstream << int(1);
2857  qtstream << property;
2858  qtstream << qvar;
2859  }
2860  }
2861 
2862  qtstream << int(0);
2863  qtbuffer.close();
2864  }
2865 
2866  QByteArray qtarray = qtbuffer.buffer();
2867  ULONG written = 0;
2868  const char *data = qtarray.constData();
2869  ULARGE_INTEGER newsize;
2870  newsize.HighPart = 0;
2871  newsize.LowPart = qtarray.size();
2872  pStm->SetSize(newsize);
2873  pStm->Write(data, qtarray.size(), &written);
2874  pStm->Commit(STGC_ONLYIFCURRENT);
2875 
2876  if (clearDirty)
2877  dirtyflag = false;
2878  return S_OK;
2879 }
2880 
2881 HRESULT WINAPI QAxServerBase::GetSizeMax(ULARGE_INTEGER *pcbSize)
2882 {
2883  const QMetaObject *mo = qt.object->metaObject();
2884 
2885  int np = mo->propertyCount();
2886  pcbSize->HighPart = 0;
2887  pcbSize->LowPart = np * 50;
2888 
2889  return S_OK;
2890 }
2891 
2892 //**** IPersistStorage
2893 
2894 HRESULT WINAPI QAxServerBase::InitNew(IStorage *pStg)
2895 {
2896  if (initNewCalled)
2897  return CO_E_ALREADYINITIALIZED;
2898 
2899  dirtyflag = false;
2900  initNewCalled = true;
2901 
2902  m_spStorage = pStg;
2903  if (m_spStorage)
2904  m_spStorage->AddRef();
2905  return S_OK;
2906 }
2907 
2908 HRESULT WINAPI QAxServerBase::Load(IStorage *pStg)
2909 {
2910  if (InitNew(pStg) != S_OK)
2911  return CO_E_ALREADYINITIALIZED;
2912 
2913  IStream *spStream = 0;
2914  QString streamName = QLatin1String(qt.object->metaObject()->className());
2915  streamName.replace(QLatin1Char(':'), QLatin1Char('.'));
2916  /* Also invalid, but not relevant
2917  streamName.replace(QLatin1Char('/'), QLatin1Char('_'));
2918  streamName.replace(QLatin1Char('\\'), QLatin1Char('_'));
2919  */
2920  streamName += QLatin1String("_Stream4.2");
2921 
2922  pStg->OpenStream((const wchar_t *)streamName.utf16(), 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &spStream);
2923  if (!spStream) // support for streams saved with 4.1 and earlier
2924  pStg->OpenStream(L"SomeStreamName", 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &spStream);
2925  if (!spStream)
2926  return E_FAIL;
2927 
2928  Load(spStream);
2929  spStream->Release();
2930 
2931  return S_OK;
2932 }
2933 
2934 HRESULT WINAPI QAxServerBase::Save(IStorage *pStg, BOOL fSameAsLoad)
2935 {
2936  IStream *spStream = 0;
2937  QString streamName = QLatin1String(qt.object->metaObject()->className());
2938  streamName.replace(QLatin1Char(':'), QLatin1Char('.'));
2939  /* Also invalid, but not relevant
2940  streamName.replace(QLatin1Char('/'), QLatin1Char('_'));
2941  streamName.replace(QLatin1Char('\\'), QLatin1Char('_'));
2942  */
2943  streamName += QLatin1String("_Stream4.2");
2944 
2945  pStg->CreateStream((const wchar_t *)streamName.utf16(), STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &spStream);
2946  if (!spStream)
2947  return E_FAIL;
2948 
2949  Save(spStream, true);
2950 
2951  spStream->Release();
2952  return S_OK;
2953 }
2954 
2955 HRESULT WINAPI QAxServerBase::SaveCompleted(IStorage *pStgNew)
2956 {
2957  if (pStgNew) {
2958  if (m_spStorage)
2959  m_spStorage->Release();
2960  m_spStorage = pStgNew;
2961  m_spStorage->AddRef();
2962  }
2963  return S_OK;
2964 }
2965 
2967 {
2968  if (m_spStorage) m_spStorage->Release();
2969  m_spStorage = 0;
2970 
2971  return S_OK;
2972 }
2973 
2974 //**** IPersistPropertyBag
2975 /*
2976  Initialize the properties of the Qt widget.
2977 */
2979 {
2980  if (initNewCalled)
2981  return CO_E_ALREADYINITIALIZED;
2982 
2983  dirtyflag = false;
2984  initNewCalled = true;
2985  return S_OK;
2986 }
2987 
2988 /*
2989  Set the properties of the Qt widget to the values provided in the \a bag.
2990 */
2991 HRESULT WINAPI QAxServerBase::Load(IPropertyBag *bag, IErrorLog * /*log*/)
2992 {
2993  if (!bag)
2994  return E_POINTER;
2995 
2996  if (InitNew() != S_OK)
2997  return E_UNEXPECTED;
2998 
2999  bool error = false;
3000  const QMetaObject *mo = qt.object->metaObject();
3001  for (int prop = 0; prop < mo->propertyCount(); ++prop) {
3002  if (!isPropertyExposed(prop))
3003  continue;
3004  QMetaProperty property = mo->property(prop);
3005  const char* pname = property.name();
3006  BSTR bstr = QStringToBSTR(QLatin1String(pname));
3007  VARIANT var;
3008  var.vt = VT_EMPTY;
3009  HRESULT res = bag->Read(bstr, &var, 0);
3010  if (property.isWritable() && var.vt != VT_EMPTY) {
3011  if (res != S_OK || !qt.object->setProperty(pname, VARIANTToQVariant(var, property.typeName(), property.type())))
3012  error = true;
3013  }
3014  SysFreeString(bstr);
3015  }
3016 
3017  updateGeometry();
3018 
3019  return /*error ? E_FAIL :*/ S_OK;
3020 }
3021 
3022 /*
3023  Save the properties of the Qt widget into the \a bag.
3024 */
3025 HRESULT WINAPI QAxServerBase::Save(IPropertyBag *bag, BOOL clearDirty, BOOL /*saveAll*/)
3026 {
3027  if (!bag)
3028  return E_POINTER;
3029 
3030  if (clearDirty)
3031  dirtyflag = false;
3032  bool error = false;
3033  const QMetaObject *mo = qt.object->metaObject();
3034  for (int prop = 0; prop < mo->propertyCount(); ++prop) {
3035  if (!isPropertyExposed(prop))
3036  continue;
3037  QMetaProperty property = mo->property(prop);
3038  if (QByteArray(property.typeName()).endsWith('*'))
3039  continue;
3040 
3041  BSTR bstr = QStringToBSTR(QLatin1String(property.name()));
3042  QVariant qvar = qt.object->property(property.name());
3043  if (!qvar.isValid())
3044  error = true;
3045  VARIANT var;
3046  QVariantToVARIANT(qvar, var);
3047  bag->Write(bstr, &var);
3048  SysFreeString(bstr);
3049  }
3050  return /*error ? E_FAIL :*/ S_OK;
3051 }
3052 
3053 //**** IPersistFile
3054 /*
3055 */
3057 {
3058  if (qt.object->metaObject()->indexOfClassInfo("MIME") == -1)
3059  return E_NOTIMPL;
3060 
3062  return S_OK;
3063 }
3064 
3065 HRESULT WINAPI QAxServerBase::GetCurFile(LPOLESTR *currentFile)
3066 {
3067  if (qt.object->metaObject()->indexOfClassInfo("MIME") == -1)
3068  return E_NOTIMPL;
3069 
3070  if (currentFileName.isEmpty()) {
3071  *currentFile = 0;
3072  return S_FALSE;
3073  }
3074  IMalloc *malloc = 0;
3075  CoGetMalloc(1, &malloc);
3076  if (!malloc)
3077  return E_OUTOFMEMORY;
3078 
3079  *currentFile = static_cast<wchar_t *>(malloc->Alloc(currentFileName.length() * 2));
3080  malloc->Release();
3081  memcpy(*currentFile, currentFileName.unicode(), currentFileName.length() * 2);
3082 
3083  return S_OK;
3084 }
3085 
3086 HRESULT WINAPI QAxServerBase::Load(LPCOLESTR fileName, DWORD mode)
3087 {
3088  const QMetaObject *mo = qt.object->metaObject();
3089  int mimeIndex = mo->indexOfClassInfo("MIME");
3090  if (mimeIndex == -1)
3091  return E_NOTIMPL;
3092 
3093  QAxBindable *axb = (QAxBindable*)qt.object->qt_metacast("QAxBindable");
3094  if (!axb) {
3095  qWarning() << class_name << ": No QAxBindable implementation for mime-type handling";
3096  return E_NOTIMPL;
3097  }
3098 
3099  QString loadFileName = QString::fromWCharArray(fileName);
3100  QString fileExtension = loadFileName.mid(loadFileName.lastIndexOf(QLatin1Char('.')) + 1);
3101  QFile file(loadFileName);
3102 
3103  QString mimeType = QLatin1String(mo->classInfo(mimeIndex).value());
3104  QStringList mimeTypes = mimeType.split(QLatin1Char(';'));
3105  for (int m = 0; m < mimeTypes.count(); ++m) {
3106  QString mime = mimeTypes.at(m);
3107  if (mime.count(QLatin1Char(':')) != 2) {
3108  qWarning() << class_name << ": Invalid syntax in Q_CLASSINFO for MIME";
3109  continue;
3110  }
3111 
3112  mimeType = mime.left(mimeType.indexOf(QLatin1Char(':'))); // first type
3113  if (mimeType.isEmpty()) {
3114  qWarning() << class_name << ": Invalid syntax in Q_CLASSINFO for MIME";
3115  continue;
3116  }
3117  QString mimeExtension = mime.mid(mimeType.length() + 1);
3118  mimeExtension = mimeExtension.left(mimeExtension.indexOf(QLatin1Char(':')));
3119  if (mimeExtension != fileExtension)
3120  continue;
3121 
3122  if (axb->readData(&file, mimeType)) {
3123  currentFileName = loadFileName;
3124  return S_OK;
3125  }
3126  }
3127 
3128  return E_FAIL;
3129 }
3130 
3131 HRESULT WINAPI QAxServerBase::Save(LPCOLESTR fileName, BOOL fRemember)
3132 {
3133  const QMetaObject *mo = qt.object->metaObject();
3134  int mimeIndex = mo->indexOfClassInfo("MIME");
3135  if (mimeIndex == -1)
3136  return E_NOTIMPL;
3137 
3138  QAxBindable *axb = (QAxBindable*)qt.object->qt_metacast("QAxBindable");
3139  if (!axb) {
3140  qWarning() << class_name << ": No QAxBindable implementation for mime-type handling";
3141  return E_NOTIMPL;
3142  }
3143 
3144  QString saveFileName = QString::fromWCharArray(fileName);
3145  QString fileExtension = saveFileName.mid(saveFileName.lastIndexOf(QLatin1Char('.')) + 1);
3146  QFile file(saveFileName);
3147 
3148  QString mimeType = QLatin1String(mo->classInfo(mimeIndex).value());
3149  QStringList mimeTypes = mimeType.split(QLatin1Char(';'));
3150  for (int m = 0; m < mimeTypes.count(); ++m) {
3151  QString mime = mimeTypes.at(m);
3152  if (mime.count(QLatin1Char(':')) != 2) {
3153  qWarning() << class_name << ": Invalid syntax in Q_CLASSINFO for MIME";
3154  continue;
3155  }
3156  mimeType = mime.left(mimeType.indexOf(QLatin1Char(':'))); // first type
3157  if (mimeType.isEmpty()) {
3158  qWarning() << class_name << ": Invalid syntax in Q_CLASSINFO for MIME";
3159  continue;
3160  }
3161  QString mimeExtension = mime.mid(mimeType.length() + 1);
3162  mimeExtension = mimeExtension.left(mimeExtension.indexOf(QLatin1Char(':')));
3163  if (mimeExtension != fileExtension)
3164  continue;
3165  if (axb->writeData(&file)) {
3166  if (fRemember)
3167  currentFileName = saveFileName;
3168  return S_OK;
3169  }
3170  }
3171  return E_FAIL;
3172 }
3173 
3174 //**** IViewObject
3175 /*
3176  Draws the widget into the provided device context.
3177 */
3178 HRESULT WINAPI QAxServerBase::Draw(DWORD dwAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
3179  HDC hicTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL /*lprcWBounds*/,
3180  BOOL(__stdcall* /*pfnContinue*/)(ULONG_PTR), ULONG_PTR /*dwContinue*/)
3181 {
3182  if (!lprcBounds)
3183  return E_INVALIDARG;
3184 
3185  internalCreate();
3186  if (!isWidget || !qt.widget)
3187  return OLE_E_BLANK;
3188 
3189  switch (dwAspect) {
3190  case DVASPECT_CONTENT:
3191  case DVASPECT_OPAQUE:
3192  case DVASPECT_TRANSPARENT:
3193  break;
3194  default:
3195  return DV_E_DVASPECT;
3196  }
3197  if (!ptd)
3198  hicTargetDev = 0;
3199 
3200  bool bDeleteDC = false;
3201  if (!hicTargetDev) {
3202  hicTargetDev = ::CreateDC(L"DISPLAY", NULL, NULL, NULL);
3203  bDeleteDC = (hicTargetDev != hdcDraw);
3204  }
3205 
3206  RECTL rc = *lprcBounds;
3207  bool bMetaFile = GetDeviceCaps(hdcDraw, TECHNOLOGY) == DT_METAFILE;
3208  if (!bMetaFile)
3209  ::LPtoDP(hicTargetDev, (LPPOINT)&rc, 2);
3210 
3211  QPixmap pm = QPixmap::grabWidget(qt.widget);
3212  HBITMAP hbm = pm.toWinHBITMAP();
3213  HDC hdc = CreateCompatibleDC(0);
3214  SelectObject(hdc, hbm);
3215  ::StretchBlt(hdcDraw, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hdc, 0, 0,pm.width(), pm.height(), SRCCOPY);
3216  DeleteDC(hdc);
3217  DeleteObject(hbm);
3218 
3219  if (bDeleteDC)
3220  DeleteDC(hicTargetDev);
3221 
3222  return S_OK;
3223 }
3224 
3225 /*
3226  Not implemented.
3227 */
3228 HRESULT WINAPI QAxServerBase::GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
3229  HDC hicTargetDev, LOGPALETTE **ppColorSet)
3230 {
3231  return E_NOTIMPL;
3232 }
3233 
3234 /*
3235  Not implemented.
3236 */
3237 HRESULT WINAPI QAxServerBase::Freeze(DWORD dwAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze)
3238 {
3239  return E_NOTIMPL;
3240 }
3241 
3242 /*
3243  Not implemented.
3244 */
3245 HRESULT WINAPI QAxServerBase::Unfreeze(DWORD dwFreeze)
3246 {
3247  return E_NOTIMPL;
3248 }
3249 
3250 /*
3251  Stores the provided advise sink.
3252 */
3253 HRESULT WINAPI QAxServerBase::SetAdvise(DWORD /*aspects*/, DWORD /*advf*/, IAdviseSink *pAdvSink)
3254 {
3255  if (m_spAdviseSink) m_spAdviseSink->Release();
3256 
3257  m_spAdviseSink = pAdvSink;
3258  if (m_spAdviseSink) m_spAdviseSink->AddRef();
3259  return S_OK;
3260 }
3261 
3262 /*
3263  Returns the advise sink.
3264 */
3265 HRESULT WINAPI QAxServerBase::GetAdvise(DWORD* /*aspects*/, DWORD* /*advf*/, IAdviseSink **ppAdvSink)
3266 {
3267  if (!ppAdvSink)
3268  return E_POINTER;
3269 
3270  *ppAdvSink = m_spAdviseSink;
3271  if (*ppAdvSink)
3272  (*ppAdvSink)->AddRef();
3273  return S_OK;
3274 }
3275 
3276 //**** IViewObject2
3277 /*
3278  Returns the current size ONLY if the widget has already been sized.
3279 */
3280 HRESULT WINAPI QAxServerBase::GetExtent(DWORD dwAspect, LONG /*lindex*/, DVTARGETDEVICE* /*ptd*/, LPSIZEL lpsizel)
3281 {
3282  if (!isWidget || !qt.widget || !qt.widget->testAttribute(Qt::WA_Resized))
3283  return OLE_E_BLANK;
3284 
3285  return GetExtent(dwAspect, lpsizel);
3286 }
3287 
3288 //**** IOleControl
3289 /*
3290  Not implemented.
3291 */
3293 {
3294  return E_NOTIMPL;
3295 }
3296 
3297 /*
3298  Turns event firing on and off.
3299 */
3301 {
3302  // member of CComControl
3303  if (bFreeze)
3304  freezeEvents++;
3305  else
3306  freezeEvents--;
3307 
3308  return S_OK;
3309 }
3310 
3311 /*
3312  Not implemented.
3313 */
3315 {
3316  return E_NOTIMPL;
3317 }
3318 
3319 /*
3320  Update the ambient properties of the Qt widget.
3321 */
3323 {
3324  if (!m_spClientSite || !theObject)
3325  return S_OK;
3326 
3327  IDispatch *disp = 0;
3328  m_spClientSite->QueryInterface(IID_IDispatch, (void**)&disp);
3329  if (!disp)
3330  return S_OK;
3331 
3332  VARIANT var;
3333  VariantInit(&var);
3334  DISPPARAMS params = { 0, 0, 0, 0 };
3335  disp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &params, &var, 0, 0);
3336  disp->Release();
3337  disp = 0;
3338 
3339  switch(dispID) {
3340  case DISPID_AMBIENT_APPEARANCE:
3341  break;
3342  case DISPID_AMBIENT_AUTOCLIP:
3343  break;
3344  case DISPID_AMBIENT_BACKCOLOR:
3345  case DISPID_AMBIENT_FORECOLOR:
3346  if (isWidget) {
3347  long rgb;
3348  if (var.vt == VT_UI4)
3349  rgb = var.ulVal;
3350  else if (var.vt == VT_I4)
3351  rgb = var.lVal;
3352  else
3353  break;
3354  QPalette pal = qt.widget->palette();
3355  pal.setColor(dispID == DISPID_AMBIENT_BACKCOLOR ? QPalette::Window : QPalette::WindowText,
3356  OLEColorToQColor(rgb));
3357  qt.widget->setPalette(pal);
3358  }
3359  break;
3360  case DISPID_AMBIENT_DISPLAYASDEFAULT:
3361  break;
3362  case DISPID_AMBIENT_DISPLAYNAME:
3363  if (var.vt != VT_BSTR || !isWidget)
3364  break;
3365  qt.widget->setWindowTitle(QString::fromWCharArray(var.bstrVal));
3366  break;
3367  case DISPID_AMBIENT_FONT:
3368  if (var.vt != VT_DISPATCH || !isWidget)
3369  break;
3370  {
3371  QVariant qvar = VARIANTToQVariant(var, "QFont", QVariant::Font);
3372  QFont qfont = qvariant_cast<QFont>(qvar);
3373  qt.widget->setFont(qfont);
3374  }
3375  break;
3376  case DISPID_AMBIENT_LOCALEID:
3377  break;
3378  case DISPID_AMBIENT_MESSAGEREFLECT:
3379  if (var.vt != VT_BOOL)
3380  break;
3381  if (var.boolVal)
3382  qt.widget->installEventFilter(this);
3383  else
3384  qt.widget->removeEventFilter(this);
3385  break;
3386  case DISPID_AMBIENT_PALETTE:
3387  break;
3388  case DISPID_AMBIENT_SCALEUNITS:
3389  break;
3390  case DISPID_AMBIENT_SHOWGRABHANDLES:
3391  break;
3392  case DISPID_AMBIENT_SHOWHATCHING:
3393  break;
3394  case DISPID_AMBIENT_SUPPORTSMNEMONICS:
3395  break;
3396  case DISPID_AMBIENT_TEXTALIGN:
3397  break;
3398  case DISPID_AMBIENT_UIDEAD:
3399  if (var.vt != VT_BOOL || !isWidget)
3400  break;
3401  qt.widget->setEnabled(!var.boolVal);
3402  break;
3403  case DISPID_AMBIENT_USERMODE:
3404  if (var.vt != VT_BOOL)
3405  break;
3406  inDesignMode = !var.boolVal;
3407  break;
3408  case DISPID_AMBIENT_RIGHTTOLEFT:
3409  if (var.vt != VT_BOOL)
3410  break;
3411  qApp->setLayoutDirection(var.boolVal?Qt::RightToLeft:Qt::LeftToRight);
3412  break;
3413  }
3414 
3415  return S_OK;
3416 }
3417 
3418 //**** IOleWindow
3419 /*
3420  Returns the HWND of the control.
3421 */
3423 {
3424  if (!pHwnd)
3425  return E_POINTER;
3426  *pHwnd = m_hWnd;
3427  return S_OK;
3428 }
3429 
3430 /*
3431  Enters What's This mode.
3432 */
3434 {
3435  if (fEnterMode)
3437  else
3439  return S_OK;
3440 }
3441 
3442 //**** IOleInPlaceObject
3443 /*
3444  Deactivates the control in place.
3445 */
3447 {
3448  if (!isInPlaceActive)
3449  return S_OK;
3450  UIDeactivate();
3451 
3452  isInPlaceActive = false;
3453 
3454  // if we have a window, tell it to go away.
3455  if (m_hWnd) {
3456  if (::IsWindow(m_hWnd))
3457  ::DestroyWindow(m_hWnd);
3458  m_hWnd = 0;
3459  }
3460 
3461  if (m_spInPlaceSite)
3462  m_spInPlaceSite->OnInPlaceDeactivate();
3463 
3464  return S_OK;
3465 }
3466 
3467 /*
3468  Deactivates the control's user interface.
3469 */
3471 {
3472  // if we're not UIActive, not much to do.
3473  if (!isUIActive || !m_spInPlaceSite)
3474  return S_OK;
3475 
3476  isUIActive = false;
3477 
3478  // notify frame windows, if appropriate, that we're no longer ui-active.
3479  HWND hwndParent;
3480  if (m_spInPlaceSite->GetWindow(&hwndParent) == S_OK) {
3481  if (m_spInPlaceFrame) m_spInPlaceFrame->Release();
3482  m_spInPlaceFrame = 0;
3483  IOleInPlaceUIWindow *spInPlaceUIWindow = 0;
3484  RECT rcPos, rcClip;
3485  OLEINPLACEFRAMEINFO frameInfo;
3486  frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
3487 
3488  m_spInPlaceSite->GetWindowContext(&m_spInPlaceFrame, &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
3489  if (spInPlaceUIWindow) {
3490  spInPlaceUIWindow->SetActiveObject(0, 0);
3491  spInPlaceUIWindow->Release();
3492  }
3493  if (m_spInPlaceFrame) {
3494  removeMenu();
3495  if (menuBar) {
3496  menuBar->removeEventFilter(this);
3497  menuBar = 0;
3498  }
3499  if (statusBar) {
3501  const int index = statusBar->metaObject()->indexOfSignal("messageChanged(QString)");
3502  QMetaObject::disconnect(statusBar, index, this, -1);
3503  statusBar = 0;
3504  }
3505  m_spInPlaceFrame->SetActiveObject(0, 0);
3506  m_spInPlaceFrame->Release();
3507  m_spInPlaceFrame = 0;
3508  }
3509  }
3510  // we don't need to explicitly release the focus here since somebody
3511  // else grabbing the focus is usually why we are getting called at all
3512  m_spInPlaceSite->OnUIDeactivate(false);
3513 
3514  return S_OK;
3515 }
3516 
3517 /*
3518  Positions the control, and applies requested clipping.
3519 */
3520 HRESULT WINAPI QAxServerBase::SetObjectRects(LPCRECT prcPos, LPCRECT prcClip)
3521 {
3522  if (prcPos == 0 || prcClip == 0)
3523  return E_POINTER;
3524 
3525  if (m_hWnd) {
3526  // the container wants us to clip, so figure out if we really need to
3527  RECT rcIXect;
3528  BOOL b = IntersectRect(&rcIXect, prcPos, prcClip);
3529  HRGN tempRgn = 0;
3530  if (b && !EqualRect(&rcIXect, prcPos)) {
3531  OffsetRect(&rcIXect, -(prcPos->left), -(prcPos->top));
3532  tempRgn = CreateRectRgnIndirect(&rcIXect);
3533  }
3534 
3535  ::SetWindowRgn(m_hWnd, tempRgn, true);
3536  ::SetWindowPos(m_hWnd, 0, prcPos->left, prcPos->top,
3537  prcPos->right - prcPos->left, prcPos->bottom - prcPos->top,
3538  SWP_NOZORDER | SWP_NOACTIVATE);
3539  }
3540 
3541  //Save the new extent.
3542  m_currentExtent.rwidth() = qBound(qt.widget->minimumWidth(), int(prcPos->right - prcPos->left), qt.widget->maximumWidth());
3543  m_currentExtent.rheight() = qBound(qt.widget->minimumHeight(), int(prcPos->bottom - prcPos->top), qt.widget->maximumHeight());
3544 
3545  return S_OK;
3546 }
3547 
3548 /*
3549  Not implemented.
3550 */
3552 {
3553  return E_NOTIMPL;
3554 }
3555 
3556 //**** IOleInPlaceActiveObject
3557 
3559 
3561 {
3562  if (pMsg->message != WM_KEYDOWN || !isWidget)
3563  return S_FALSE;
3564 
3565  DWORD dwKeyMod = 0;
3566  if (::GetKeyState(VK_SHIFT) < 0)
3567  dwKeyMod |= 1; // KEYMOD_SHIFT
3568  if (::GetKeyState(VK_CONTROL) < 0)
3569  dwKeyMod |= 2; // KEYMOD_CONTROL
3570  if (::GetKeyState(VK_MENU) < 0)
3571  dwKeyMod |= 4; // KEYMOD_ALT
3572 
3573  switch (LOWORD(pMsg->wParam)) {
3574  case VK_TAB:
3575  if (isUIActive) {
3576  bool shift = ::GetKeyState(VK_SHIFT) < 0;
3577  bool giveUp = true;
3578  QWidget *curFocus = qt.widget->focusWidget();
3579  if (curFocus) {
3580  if (shift) {
3581  if (!curFocus->isWindow()) {
3582  QWidget *nextFocus = curFocus->nextInFocusChain();
3583  QWidget *prevFocus = 0;
3584  QWidget *topLevel = 0;
3585  while (nextFocus != curFocus) {
3586  if (nextFocus->focusPolicy() & Qt::TabFocus) {
3587  prevFocus = nextFocus;
3588  topLevel = 0;
3589  } else if (nextFocus->isWindow()) {
3590  topLevel = nextFocus;
3591  }
3592  nextFocus = nextFocus->nextInFocusChain();
3593  }
3594 
3595  if (!topLevel) {
3596  giveUp = false;
3597  ((HackWidget*)curFocus)->focusNextPrevChild(false);
3599  }
3600  }
3601  } else {
3602  QWidget *nextFocus = curFocus;
3603  while (1) {
3604  nextFocus = nextFocus->nextInFocusChain();
3605  if (nextFocus->isWindow())
3606  break;
3607  if (nextFocus->focusPolicy() & Qt::TabFocus) {
3608  giveUp = false;
3609  ((HackWidget*)curFocus)->focusNextPrevChild(true);
3611  break;
3612  }
3613  }
3614  }
3615  }
3616  if (giveUp) {
3617  HWND hwnd = ::GetParent(m_hWnd);
3618  ::SetFocus(hwnd);
3619  } else {
3620  return S_OK;
3621  }
3622 
3623  }
3624  break;
3625 
3626  case VK_LEFT:
3627  case VK_RIGHT:
3628  case VK_UP:
3629  case VK_DOWN:
3630  if (isUIActive)
3631  return S_FALSE;
3632  break;
3633 
3634  default:
3635  if (isUIActive && qt.widget->focusWidget()) {
3636  int state = Qt::NoButton;
3637  if (dwKeyMod & 1)
3638  state |= Qt::ShiftModifier;
3639  if (dwKeyMod & 2)
3640  state |= Qt::ControlModifier;
3641  if (dwKeyMod & 4)
3642  state |= Qt::AltModifier;
3643 
3644  int key = pMsg->wParam;
3645  if (!(key >= 'A' && key <= 'Z') && !(key >= '0' && key <= '9'))
3646  key = qt_translateKeyCode(pMsg->wParam);
3647 
3648  QKeyEvent override(QEvent::ShortcutOverride, key, (Qt::KeyboardModifiers)state);
3649  override.ignore();
3650  QApplication::sendEvent(qt.widget->focusWidget(), &override);
3651  if (override.isAccepted())
3652  return S_FALSE;
3653  }
3654  break;
3655  }
3656 
3657  if (!m_spClientSite)
3658  return S_FALSE;
3659 
3660  IOleControlSite *controlSite = 0;
3661  m_spClientSite->QueryInterface(IID_IOleControlSite, (void**)&controlSite);
3662  if (!controlSite)
3663  return S_FALSE;
3664  bool resetUserData = false;
3665  // set server type in the user-data of the window.
3666 #ifdef GWLP_USERDATA
3667  LONG_PTR serverType = QAX_INPROC_SERVER;
3668 #else
3669  LONG serverType = QAX_INPROC_SERVER;
3670 #endif
3671  if (qAxOutProcServer)
3672  serverType = QAX_OUTPROC_SERVER;
3673 #ifdef GWLP_USERDATA
3674  LONG_PTR oldData = SetWindowLongPtr(pMsg->hwnd, GWLP_USERDATA, serverType);
3675 #else
3676  LONG oldData = SetWindowLong(pMsg->hwnd, GWL_USERDATA, serverType);
3677 #endif
3678  HRESULT hres = controlSite->TranslateAcceleratorW(pMsg, dwKeyMod);
3679  controlSite->Release();
3680  // reset the user-data for the window.
3681 #ifdef GWLP_USERDATA
3682  SetWindowLongPtr(pMsg->hwnd, GWLP_USERDATA, oldData);
3683 #else
3684  SetWindowLong(pMsg->hwnd, GWL_USERDATA, oldData);
3685 #endif
3686  return hres;
3687 }
3688 
3690 {
3691  return TranslateAcceleratorW(pMsg);
3692 }
3693 
3695 {
3696  if (fActivate) {
3697  if (wasUIActive)
3698  ::SetFocus(m_hWnd);
3699  } else {
3701  }
3702  return S_OK;
3703 }
3704 
3706 {
3707  return S_OK;
3708 }
3709 
3710 HRESULT WINAPI QAxServerBase::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow)
3711 {
3712  return S_OK;
3713 }
3714 
3716 {
3717  if (!isWidget)
3718  return S_OK;
3719 
3720  EnableWindow(qt.widget->winId(), fEnable);
3721  return S_OK;
3722 }
3723 
3724 //**** IOleObject
3725 
3726 static inline LPOLESTR QStringToOLESTR(const QString &qstring)
3727 {
3728  LPOLESTR olestr = (wchar_t*)CoTaskMemAlloc(qstring.length()*2+2);
3729  memcpy(olestr, (ushort*)qstring.unicode(), qstring.length()*2);
3730  olestr[qstring.length()] = 0;
3731  return olestr;
3732 }
3733 
3734 /*
3735  \reimp
3736 
3737  See documentation of IOleObject::GetUserType.
3738 */
3739 HRESULT WINAPI QAxServerBase::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
3740 {
3741  if (!pszUserType)
3742  return E_POINTER;
3743 
3744  switch (dwFormOfType) {
3745  case USERCLASSTYPE_FULL:
3746  *pszUserType = QStringToOLESTR(class_name);
3747  break;
3748  case USERCLASSTYPE_SHORT:
3749  if (!qt.widget || !isWidget || qt.widget->windowTitle().isEmpty())
3750  *pszUserType = QStringToOLESTR(class_name);
3751  else
3752  *pszUserType = QStringToOLESTR(qt.widget->windowTitle());
3753  break;
3754  case USERCLASSTYPE_APPNAME:
3755  *pszUserType = QStringToOLESTR(qApp->objectName());
3756  break;
3757  }
3758 
3759  return S_OK;
3760 }
3761 
3762 /*
3763  Returns the status flags registered for this control.
3764 */
3765 HRESULT WINAPI QAxServerBase::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
3766 {
3767  return OleRegGetMiscStatus(qAxFactory()->classID(class_name), dwAspect, pdwStatus);
3768 }
3769 
3770 /*
3771  Stores the provided advise sink.
3772 */
3773 HRESULT WINAPI QAxServerBase::Advise(IAdviseSink* pAdvSink, DWORD* pdwConnection)
3774 {
3775  *pdwConnection = adviseSinks.count() + 1;
3776  STATDATA data = { {0, 0, DVASPECT_CONTENT, -1, TYMED_NULL} , 0, pAdvSink, *pdwConnection };
3777  adviseSinks.append(data);
3778  pAdvSink->AddRef();
3779  return S_OK;
3780 }
3781 
3782 /*
3783  Closes the control.
3784 */
3785 HRESULT WINAPI QAxServerBase::Close(DWORD dwSaveOption)
3786 {
3787  if (dwSaveOption != OLECLOSE_NOSAVE && m_spClientSite)
3788  m_spClientSite->SaveObject();
3789  if (isInPlaceActive) {
3790  HRESULT hr = InPlaceDeactivate();
3791  if (FAILED(hr))
3792  return hr;
3793  }
3794  if (m_hWnd) {
3795  if (IsWindow(m_hWnd))
3796  DestroyWindow(m_hWnd);
3797  m_hWnd = 0;
3798  if (m_spClientSite)
3799  m_spClientSite->OnShowWindow(false);
3800  }
3801 
3802  if (m_spInPlaceSite) m_spInPlaceSite->Release();
3803  m_spInPlaceSite = 0;
3804 
3805  if (m_spAdviseSink)
3806  m_spAdviseSink->OnClose();
3807  for (int i = 0; i < adviseSinks.count(); ++i) {
3808  adviseSinks.at(i).pAdvSink->OnClose();
3809  }
3810 
3811  return S_OK;
3812 }
3813 
3815 
3816 /*
3817  Executes the steps to activate the control.
3818 */
3820 {
3821  if (!m_spClientSite)
3822  return S_OK;
3823  if (!m_spInPlaceSite)
3824  m_spClientSite->QueryInterface(IID_IOleInPlaceSite, (void**)&m_spInPlaceSite);
3825  if (!m_spInPlaceSite)
3826  return E_FAIL;
3827 
3828  HRESULT hr = E_FAIL;
3829  if (!isInPlaceActive) {
3830  BOOL bNoRedraw = false;
3831  hr = m_spInPlaceSite->CanInPlaceActivate();
3832  if (FAILED(hr))
3833  return hr;
3834  if (hr != S_OK)
3835  return E_FAIL;
3836  m_spInPlaceSite->OnInPlaceActivate();
3837  }
3838 
3839  isInPlaceActive = true;
3840  OnAmbientPropertyChange(DISPID_AMBIENT_USERMODE);
3841 
3842  if (isWidget) {
3843  IOleInPlaceUIWindow *spInPlaceUIWindow = 0;
3844  HWND hwndParent;
3845  if (m_spInPlaceSite->GetWindow(&hwndParent) == S_OK) {
3846  // get location in the parent window, as well as some information about the parent
3847  if (m_spInPlaceFrame) m_spInPlaceFrame->Release();
3848  m_spInPlaceFrame = 0;
3849  RECT rcPos, rcClip;
3850  OLEINPLACEFRAMEINFO frameInfo;
3851  frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
3852  m_spInPlaceSite->GetWindowContext(&m_spInPlaceFrame, &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
3853  if (m_hWnd) {
3854  ::ShowWindow(m_hWnd, SW_SHOW);
3855  if (!::IsChild(m_hWnd, ::GetFocus()) && qt.widget->focusPolicy() != Qt::NoFocus)
3856  ::SetFocus(m_hWnd);
3857  } else {
3858  create(hwndParent, rcPos);
3859  }
3860  }
3861 
3862  // Gone active by now, take care of UIACTIVATE
3863  canTakeFocus = qt.widget->focusPolicy() != Qt::NoFocus && !inDesignMode;
3864  if (!canTakeFocus && !inDesignMode) {
3865  QList<QWidget*> widgets = qt.widget->findChildren<QWidget*>();
3866  for (int w = 0; w < widgets.count(); ++w) {
3867  QWidget *widget = widgets[w];
3868  canTakeFocus = widget->focusPolicy() != Qt::NoFocus;
3869  if (canTakeFocus)
3870  break;
3871  }
3872  }
3873  if (!isUIActive && canTakeFocus) {
3874  isUIActive = true;
3875  hr = m_spInPlaceSite->OnUIActivate();
3876  if (FAILED(hr)) {
3877  if (m_spInPlaceFrame) m_spInPlaceFrame->Release();
3878  m_spInPlaceFrame = 0;
3879  if (spInPlaceUIWindow) spInPlaceUIWindow->Release();
3880  return hr;
3881  }
3882 
3883  if (isInPlaceActive) {
3884  if (!::IsChild(m_hWnd, ::GetFocus()))
3885  ::SetFocus(m_hWnd);
3886  }
3887 
3888  if (m_spInPlaceFrame) {
3889  hr = m_spInPlaceFrame->SetActiveObject(this, QStringToBSTR(class_name));
3890  if (!FAILED(hr)) {
3891  menuBar = (qt.widget && !qax_disable_inplaceframe) ? qt.widget->findChild<QMenuBar*>() : 0;
3892  if (menuBar && !menuBar->isVisible()) {
3894  menuBar->hide();
3895  menuBar->installEventFilter(this);
3896  }
3897  statusBar = qt.widget ? qt.widget->findChild<QStatusBar*>() : 0;
3898  if (statusBar && !statusBar->isVisible()) {
3899  const int index = statusBar->metaObject()->indexOfSignal("messageChanged(QString)");
3900  QMetaObject::connect(statusBar, index, this, -1);
3901  statusBar->hide();
3903  }
3904  }
3905  }
3906  if (spInPlaceUIWindow) {
3907  spInPlaceUIWindow->SetActiveObject(this, QStringToBSTR(class_name));
3908  spInPlaceUIWindow->SetBorderSpace(0);
3909  }
3910  }
3911  if (spInPlaceUIWindow) spInPlaceUIWindow->Release();
3912  ShowWindow(m_hWnd, SW_NORMAL);
3913  }
3914 
3915  m_spClientSite->ShowObject();
3916 
3917  return S_OK;
3918 }
3919 
3920 /*
3921  Executes the "verb" \a iVerb.
3922 */
3923 HRESULT WINAPI QAxServerBase::DoVerb(LONG iVerb, LPMSG /*lpmsg*/, IOleClientSite* /*pActiveSite*/, LONG /*lindex*/,
3924  HWND /*hwndParent*/, LPCRECT /*prcPosRect*/)
3925 {
3926  HRESULT hr = E_NOTIMPL;
3927  switch (iVerb)
3928  {
3929  case OLEIVERB_SHOW:
3930  hr = internalActivate();
3931  if (SUCCEEDED(hr))
3932  hr = S_OK;
3933  break;
3934 
3935  case OLEIVERB_PRIMARY:
3936  case OLEIVERB_INPLACEACTIVATE:
3937  hr = internalActivate();
3938  if (SUCCEEDED(hr)) {
3939  hr = S_OK;
3940  update();
3941  }
3942  break;
3943 
3944  case OLEIVERB_UIACTIVATE:
3945  if (!isUIActive) {
3946  hr = internalActivate();
3947  if (SUCCEEDED(hr))
3948  hr = S_OK;
3949  }
3950  break;
3951 
3952  case OLEIVERB_HIDE:
3953  UIDeactivate();
3954  if (m_hWnd)
3955  ::ShowWindow(m_hWnd, SW_HIDE);
3956  hr = S_OK;
3957  return hr;
3958 
3959  default:
3960  break;
3961  }
3962  return hr;
3963 }
3964 
3965 /*
3966  Not implemented.
3967 */
3968 HRESULT WINAPI QAxServerBase::EnumAdvise(IEnumSTATDATA** /*ppenumAdvise*/)
3969 {
3970  return E_NOTIMPL;
3971 }
3972 
3973 /*
3974  Returns an enumerator for the verbs registered for this class.
3975 */
3976 HRESULT WINAPI QAxServerBase::EnumVerbs(IEnumOLEVERB** ppEnumOleVerb)
3977 {
3978  if (!ppEnumOleVerb)
3979  return E_POINTER;
3980  return OleRegEnumVerbs(qAxFactory()->classID(class_name), ppEnumOleVerb);
3981 }
3982 
3983 /*
3984  Returns the current client site..
3985 */
3986 HRESULT WINAPI QAxServerBase::GetClientSite(IOleClientSite** ppClientSite)
3987 {
3988  if (!ppClientSite)
3989  return E_POINTER;
3990  *ppClientSite = m_spClientSite;
3991  if (*ppClientSite)
3992  (*ppClientSite)->AddRef();
3993  return S_OK;
3994 }
3995 
3996 /*
3997  Not implemented.
3998 */
3999 HRESULT WINAPI QAxServerBase::GetClipboardData(DWORD, IDataObject**)
4000 {
4001  return E_NOTIMPL;
4002 }
4003 
4004 /*
4005  Returns the current extent.
4006 */
4007 HRESULT WINAPI QAxServerBase::GetExtent(DWORD dwDrawAspect, SIZEL* psizel)
4008 {
4009  if (dwDrawAspect != DVASPECT_CONTENT || !isWidget || !qt.widget)
4010  return E_FAIL;
4011  if (!psizel)
4012  return E_POINTER;
4013 
4014  psizel->cx = MAP_PIX_TO_LOGHIM(m_currentExtent.width(), qt.widget->logicalDpiX());
4015  psizel->cy = MAP_PIX_TO_LOGHIM(m_currentExtent.height(), qt.widget->logicalDpiY());
4016  return S_OK;
4017 }
4018 
4019 /*
4020  Not implemented.
4021 */
4022 HRESULT WINAPI QAxServerBase::GetMoniker(DWORD, DWORD, IMoniker** )
4023 {
4024  return E_NOTIMPL;
4025 }
4026 
4027 /*
4028  Returns the CLSID of this class.
4029 */
4031 {
4032  if (!pClsid)
4033  return E_POINTER;
4034  *pClsid = qAxFactory()->classID(class_name);
4035  return S_OK;
4036 }
4037 
4038 /*
4039  Not implemented.
4040 */
4041 HRESULT WINAPI QAxServerBase::InitFromData(IDataObject*, BOOL, DWORD)
4042 {
4043  return E_NOTIMPL;
4044 }
4045 
4046 /*
4047  Not implemented.
4048 */
4050 {
4051  return S_OK;
4052 }
4053 
4054 /*
4055  Stores the client site.
4056 */
4057 HRESULT WINAPI QAxServerBase::SetClientSite(IOleClientSite* pClientSite)
4058 {
4059  // release all client site interfaces
4060  if (m_spClientSite) m_spClientSite->Release();
4061  if (m_spInPlaceSite) m_spInPlaceSite->Release();
4062  m_spInPlaceSite = 0;
4063  if (m_spInPlaceFrame) m_spInPlaceFrame->Release();
4064  m_spInPlaceFrame = 0;
4065 
4066  m_spClientSite = pClientSite;
4067  if (m_spClientSite) {
4068  m_spClientSite->AddRef();
4069  m_spClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_spInPlaceSite);
4070  }
4071 
4072  return S_OK;
4073 }
4074 
4075 /*
4076  Not implemented.
4077 */
4079 {
4080  return E_NOTIMPL;
4081 }
4082 
4083 
4084 #ifdef QT_DLL // avoid conflict with symbol in static lib
4086 {
4088 }
4089 #endif
4090 
4091 /*
4092  Tries to set the size of the control.
4093 */
4094 HRESULT WINAPI QAxServerBase::SetExtent(DWORD dwDrawAspect, SIZEL* psizel)
4095 {
4096  if (dwDrawAspect != DVASPECT_CONTENT)
4097  return DV_E_DVASPECT;
4098  if (!psizel)
4099  return E_POINTER;
4100 
4101  if (!isWidget || !qt.widget) // nothing to do
4102  return S_OK;
4103 
4104  QSize proposedSize(MAP_LOGHIM_TO_PIX(psizel->cx, qt.widget->logicalDpiX()),
4105  MAP_LOGHIM_TO_PIX(psizel->cy, qt.widget->logicalDpiY()));
4106 
4107  // can the widget be resized at all?
4108  if (qt.widget->minimumSize() == qt.widget->maximumSize() && qt.widget->minimumSize() != proposedSize)
4109  return E_FAIL;
4110  //Save the extent, bound to the widget restrictions.
4111  m_currentExtent.rwidth() = qBound(qt.widget->minimumWidth(), proposedSize.width(), qt.widget->maximumWidth());
4112  m_currentExtent.rheight() = qBound(qt.widget->minimumHeight(), proposedSize.height(), qt.widget->maximumHeight());
4113 
4114  resize(proposedSize);
4115  return S_OK;
4116 }
4117 
4118 /*
4119  Not implemented.
4120 */
4121 HRESULT WINAPI QAxServerBase::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
4122 {
4123  return S_OK;
4124 }
4125 
4126 /*
4127  Not implemented.
4128 */
4129 HRESULT WINAPI QAxServerBase::SetMoniker(DWORD, IMoniker*)
4130 {
4131  return E_NOTIMPL;
4132 }
4133 
4134 /*
4135  Disconnects an advise sink.
4136 */
4137 HRESULT WINAPI QAxServerBase::Unadvise(DWORD dwConnection)
4138 {
4139  for (int i = 0; i < adviseSinks.count(); ++i) {
4140  STATDATA entry = adviseSinks.at(i);
4141  if (entry.dwConnection == dwConnection) {
4142  entry.pAdvSink->Release();
4143  adviseSinks.removeAt(i);
4144  return S_OK;
4145  }
4146  }
4147  return OLE_E_NOCONNECTION;
4148 }
4149 
4150 /*
4151  Not implemented.
4152 */
4154 {
4155  return S_OK;
4156 }
4157 
4158 //**** IDataObject
4159 /*
4160  Calls IViewObject::Draw after setting up the parameters.
4161 */
4162 HRESULT WINAPI QAxServerBase::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
4163 {
4164  if (!pmedium)
4165  return E_POINTER;
4166  if ((pformatetcIn->tymed & TYMED_MFPICT) == 0)
4167  return DATA_E_FORMATETC;
4168 
4169  internalCreate();
4170  if (!isWidget || !qt.widget)
4171  return E_UNEXPECTED;
4172 
4173  // Container wants to draw, but the size is not defined yet - ask container
4174  if (m_spInPlaceSite && !qt.widget->testAttribute(Qt::WA_Resized)) {
4175  IOleInPlaceUIWindow *spInPlaceUIWindow = 0;
4176  RECT rcPos, rcClip;
4177  OLEINPLACEFRAMEINFO frameInfo;
4178  frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
4179 
4180  HRESULT hres = m_spInPlaceSite->GetWindowContext(&m_spInPlaceFrame, &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
4181  if (hres == S_OK) {
4182  QSize size(rcPos.right - rcPos.left, rcPos.bottom - rcPos.top);
4183  resize(size);
4184  } else {
4185  qt.widget->adjustSize();
4186  }
4187  if (spInPlaceUIWindow) spInPlaceUIWindow->Release(); // no need for it
4188  }
4189 
4190  int width = qt.widget->width();
4191  int height = qt.widget->height();
4192  RECTL rectl = {0, 0, width, height};
4193 
4194  HDC hdc = CreateMetaFile(0);
4195  SaveDC(hdc);
4196  SetWindowOrgEx(hdc, 0, 0, 0);
4197  SetWindowExtEx(hdc, rectl.right, rectl.bottom, 0);
4198 
4199  Draw(pformatetcIn->dwAspect, pformatetcIn->lindex, 0, pformatetcIn->ptd, 0, hdc, &rectl, &rectl, 0, 0);
4200 
4201  RestoreDC(hdc, -1);
4202  HMETAFILE hMF = CloseMetaFile(hdc);
4203  if (!hMF)
4204  return E_UNEXPECTED;
4205 
4206  HGLOBAL hMem = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(METAFILEPICT));
4207  if (!hMem) {
4208  DeleteMetaFile(hMF);
4209  return ResultFromScode(STG_E_MEDIUMFULL);
4210  }
4211 
4212  LPMETAFILEPICT pMF = (LPMETAFILEPICT)GlobalLock(hMem);
4213  pMF->hMF = hMF;
4214  pMF->mm = MM_ANISOTROPIC;
4215  pMF->xExt = MAP_PIX_TO_LOGHIM(width, qt.widget->logicalDpiX());
4216  pMF->yExt = MAP_PIX_TO_LOGHIM(height, qt.widget->logicalDpiY());
4217  GlobalUnlock(hMem);
4218 
4219  memset(pmedium, 0, sizeof(STGMEDIUM));
4220  pmedium->tymed = TYMED_MFPICT;
4221  pmedium->hGlobal = hMem;
4222  pmedium->pUnkForRelease = 0;
4223 
4224  return S_OK;
4225 }
4226 
4227 /*
4228  Not implemented.
4229 */
4230 HRESULT WINAPI QAxServerBase::DAdvise(FORMATETC *pformatetc, DWORD advf,
4231  IAdviseSink *pAdvSink, DWORD *pdwConnection)
4232 {
4233  if (pformatetc->dwAspect != DVASPECT_CONTENT)
4234  return E_FAIL;
4235 
4236  *pdwConnection = adviseSinks.count() + 1;
4237  STATDATA data = {
4238  {pformatetc->cfFormat,pformatetc->ptd,pformatetc->dwAspect,pformatetc->lindex,pformatetc->tymed},
4239  advf, pAdvSink, *pdwConnection
4240  };
4241  adviseSinks.append(data);
4242  pAdvSink->AddRef();
4243  return S_OK;
4244 }
4245 
4246 /*
4247  Not implemented.
4248 */
4249 HRESULT WINAPI QAxServerBase::DUnadvise(DWORD dwConnection)
4250 {
4251  return Unadvise(dwConnection);
4252 }
4253 
4254 /*
4255  Not implemented.
4256 */
4257 HRESULT WINAPI QAxServerBase::EnumDAdvise(IEnumSTATDATA ** /*ppenumAdvise*/)
4258 {
4259  return E_NOTIMPL;
4260 }
4261 
4262 /*
4263  Not implemented.
4264 */
4265 HRESULT WINAPI QAxServerBase::GetDataHere(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */)
4266 {
4267  return E_NOTIMPL;
4268 }
4269 
4270 /*
4271  Not implemented.
4272 */
4274 {
4275  return E_NOTIMPL;
4276 }
4277 
4278 /*
4279  Not implemented.
4280 */
4281 HRESULT WINAPI QAxServerBase::GetCanonicalFormatEtc(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */)
4282 {
4283  return E_NOTIMPL;
4284 }
4285 
4286 /*
4287  Not implemented.
4288 */
4289 HRESULT WINAPI QAxServerBase::SetData(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */)
4290 {
4291  return E_NOTIMPL;
4292 }
4293 
4294 /*
4295  Not implemented.
4296 */
4297 HRESULT WINAPI QAxServerBase::EnumFormatEtc(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */)
4298 {
4299  return E_NOTIMPL;
4300 }
4301 
4302 
4303 
4304 static int mapModifiers(int state)
4305 {
4306  int ole = 0;
4307  if (state & Qt::ShiftModifier)
4308  ole |= 1;
4309  if (state & Qt::ControlModifier)
4310  ole |= 2;
4311  if (state & Qt::AltModifier)
4312  ole |= 4;
4313 
4314  return ole;
4315 }
4316 
4317 /*
4318  \reimp
4319 */
4321 {
4322  if (!theObject)
4323  return QObject::eventFilter(o, e);
4324 
4325  if ((e->type() == QEvent::Show || e->type() == QEvent::Hide) && (o == statusBar || o == menuBar)) {
4326  if (o == menuBar) {
4327  if (e->type() == QEvent::Hide) {
4329  } else if (e->type() == QEvent::Show) {
4330  removeMenu();
4331  }
4332  } else if (statusBar) {
4333  statusBar->setSizeGripEnabled(false);
4334  }
4335  updateGeometry();
4336  if (m_spInPlaceSite && qt.widget->sizeHint().isValid()) {
4337  RECT rect = {0, 0, qt.widget->sizeHint().width(), qt.widget->sizeHint().height()};
4338  m_spInPlaceSite->OnPosRectChange(&rect);
4339  }
4340  }
4341  switch (e->type()) {
4342  case QEvent::ChildAdded:
4343  static_cast<QChildEvent*>(e)->child()->installEventFilter(this);
4344  break;
4345  case QEvent::ChildRemoved:
4346  static_cast<QChildEvent*>(e)->child()->removeEventFilter(this);
4347  break;
4348  case QEvent::KeyPress:
4349  if (o == qt.object && hasStockEvents) {
4350  QKeyEvent *ke = (QKeyEvent*)e;
4351  int key = ke->key();
4352  int state = ke->modifiers();
4353  void *argv[] = {
4354  0,
4355  &key,
4356  &state
4357  };
4358  qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_KEYDOWN, argv);
4359  if (!ke->text().isEmpty())
4360  qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_KEYPRESS, argv);
4361  }
4362  break;
4363  case QEvent::KeyRelease:
4364  if (o == qt.object && hasStockEvents) {
4365  QKeyEvent *ke = (QKeyEvent*)e;
4366  int key = ke->key();
4367  int state = ke->modifiers();
4368  void *argv[] = {
4369  0,
4370  &key,
4371  &state
4372  };
4373  qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_KEYUP, argv);
4374  }
4375  break;
4376  case QEvent::MouseMove:
4377  if (o == qt.object && hasStockEvents) {
4378  QMouseEvent *me = (QMouseEvent*)e;
4379  int button = me->buttons() & Qt::MouseButtonMask;
4380  int state = mapModifiers(me->modifiers());
4381  int x = me->x();
4382  int y = me->y();
4383  void *argv[] = {
4384  0,
4385  &button,
4386  &state,
4387  &x,
4388  &y
4389  };
4390  qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_MOUSEMOVE, argv);
4391  }
4392  break;
4394  if (o == qt.object && hasStockEvents) {
4395  QMouseEvent *me = (QMouseEvent*)e;
4396  int button = me->button();
4397  int state = mapModifiers(me->modifiers());
4398  int x = me->x();
4399  int y = me->y();
4400  void *argv[] = {
4401  0,
4402  &button,
4403  &state,
4404  &x,
4405  &y
4406  };
4407  qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_MOUSEUP, argv);
4408  qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_CLICK, 0);
4409  }
4410  break;
4412  if (o == qt.object && hasStockEvents) {
4413  qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_DBLCLICK, 0);
4414  }
4415  break;
4417  if (m_spInPlaceSite && !isUIActive) {
4418  internalActivate();
4419  }
4420  if (o == qt.widget && hasStockEvents) {
4421  QMouseEvent *me = (QMouseEvent*)e;
4422  int button = me->button();
4423  int state = mapModifiers(me->modifiers());
4424  int x = me->x();
4425  int y = me->y();
4426  void *argv[] = {
4427  0,
4428  &button,
4429  &state,
4430  &x,
4431  &y
4432  };
4433  qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_MOUSEDOWN, argv);
4434  }
4435  break;
4436  case QEvent::Show:
4437  if (m_hWnd && o == qt.widget)
4438  ShowWindow(m_hWnd, SW_SHOW);
4439  updateMask();
4440  break;
4441  case QEvent::Hide:
4442  if (m_hWnd && o == qt.widget)
4443  ShowWindow(m_hWnd, SW_HIDE);
4444  break;
4445 
4446  case QEvent::EnabledChange:
4447  if (m_hWnd && o == qt.widget)
4448  EnableWindow(m_hWnd, qt.widget->isEnabled());
4449  // Fall Through
4450  case QEvent::FontChange:
4452  case QEvent::StyleChange:
4455  case QEvent::Resize:
4456  updateMask();
4457  break;
4458  case QEvent::WindowBlocked: {
4459  if (!m_spInPlaceFrame)
4460  break;
4461  m_spInPlaceFrame->EnableModeless(FALSE);
4462  MSG msg;
4463  // Visual Basic 6.0 posts the message WM_USER+3078 from the EnableModeless().
4464  // While handling this message, VB will disable all current top-levels. After
4465  // this we have to re-enable the Qt modal widget to receive input events.
4466  if (PeekMessage(&msg, 0, WM_USER+3078, WM_USER+3078, PM_REMOVE)) {
4467  TranslateMessage(&msg);
4468  DispatchMessage(&msg);
4469  QWidget *modalWidget = QApplication::activeModalWidget();
4470  if (modalWidget && modalWidget->isVisible() && modalWidget->isEnabled()
4471  && !IsWindowEnabled(modalWidget->effectiveWinId()))
4472  EnableWindow(modalWidget->effectiveWinId(), TRUE);
4473  }
4474  break;
4475  }
4477  if (!m_spInPlaceFrame)
4478  break;
4479  m_spInPlaceFrame->EnableModeless(TRUE);
4480  break;
4481  default:
4482  break;
4483  }
4484  return QObject::eventFilter(o, e);
4485 }
4486 
4488 #endif // QT_NO_WIN_ACTIVEQT
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
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
bool isSeparator() const
Returns true if this action is a separator action; otherwise it returns false.
Definition: qaction.cpp:839
STDMETHOD() InitNew(VOID)
unsigned inDesignMode
QAxFactory * qAxFactory()
Definition: qaxserver.cpp:81
double d
Definition: qnumeric_p.h:62
HRESULT WINAPI QueryInterface(REFIID iid, void **iface)
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:304
union QAxServerBase::@0 qt
The QApplication class manages the GUI application&#39;s control flow and main settings.
Definition: qapplication.h:99
bool isEnabled() const
Definition: qaction.cpp:1208
void clearVARIANT(VARIANT *var)
Definition: qaxtypes.cpp:1408
static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qreal threshold)
Definition: qbezier.cpp:289
The QKeyEvent class describes a key event.
Definition: qevent.h:224
unsigned long qAxUnlock()
Definition: qaxserver.cpp:166
int type
Definition: qmetatype.cpp:239
IUnknown * m_outerUnknown
STDMETHOD() ContextSensitiveHelp(BOOL fEnterMode)
void truncate(int pos)
Truncates the byte array at index position pos.
unsigned long WINAPI Release()
QIntegerForSizeof< void * >::Unsigned quintptr
Definition: qglobal.h:986
bool isWritable() const
Returns true if this property is writable; otherwise returns false.
#define QAX_OUTPROC_SERVER
Definition: qaxtypes.h:94
unsigned char c[8]
Definition: qnumeric_p.h:62
static bool connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type=0, int *types=0)
Definition: qobject.cpp:3194
STDMETHOD() OnFrameWindowActivate(BOOL)
unsigned long __stdcall Release()
QString cap(int nth=0) const
Returns the text captured by the nth subexpression.
Definition: qregexp.cpp:4310
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
CRITICAL_SECTION refCountSection
CRITICAL_SECTION createWindowSection
int width() const
Returns the width of the pixmap.
Definition: qpixmap.cpp:630
int lastIndexIn(const QString &str, int offset=-1, CaretMode caretMode=CaretAtZero) const
Attempts to find a match backwards in str from position offset.
Definition: qregexp.cpp:4167
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
Definition: quuid.h:52
STDMETHOD() SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect)
#define QAX_NUM_PARAMS
Definition: qaxtypes.h:74
int width
the width of the widget excluding any window frame
Definition: qwidget.h:166
The QAxBindable class provides an interface between a QWidget and an ActiveX client.
Definition: qaxbindable.h:60
The QRegExp class provides pattern matching using regular expressions.
Definition: qregexp.h:61
STDMETHOD() GetAdvise(DWORD *aspects, DWORD *advf, IAdviseSink **pAdvSink)
STDMETHOD() GetSizeMax(ULARGE_INTEGER *pcbSize)
int toInt(bool *ok=0, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
Definition: qstring.cpp:6090
Connections connections
QClassFactory(CLSID clsid)
#define it(className, varName)
#define ULONG_PTR
HHOOK qax_hhook
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
bool qax_winEventFilter(void *message)
QByteArray & append(char c)
Appends the character ch to this byte array.
HRESULT internalActivate()
WId effectiveWinId() const
Returns the effective window system identifier of the widget, i.
Definition: qwidget.cpp:2654
QList< CONNECTDATA >::Iterator Iterator
bool isVisible() const
Definition: qwidget.h:1005
Q_GUI_EXPORT int qt_translateKeyCode(int)
static QAbstractEventDispatcher * instance(QThread *thread=0)
Returns a pointer to the event dispatcher object for the specified thread.
STDMETHOD() GetExtent(DWORD dwDrawAspect, SIZEL *psizel)
bool open(OpenMode openMode)
Reimplemented Function
Definition: qbuffer.cpp:338
QAxConnection(const QAxConnection &old)
IStorage * m_spStorage
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
QMetaClassInfo classInfo(int index) const
Returns the meta-data for the item of class information with the given index.
#define error(msg)
QAxServerBase * that
QMap< UINT, QAction * > actionMap
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
STDMETHOD() GetTypeInfoCount(UINT *pctinfo)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
CRITICAL_SECTION refCountSection
STDMETHOD() GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
bool emitRequestPropertyChange(const char *)
Call IPropertyNotifySink of connected clients.
#define MAP_LOGHIM_TO_PIX(x, ppli)
Definition: qaxtypes.h:73
static Expression::Ptr create(Expression *const expr, const YYLTYPE &sourceLocator, const ParserContext *const parseInfo)
Policy horizontalPolicy() const
Definition: qsizepolicy.h:118
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
STDMETHOD() OnAmbientPropertyChange(DISPID)
void close()
Reimplemented Function
Definition: qbuffer.cpp:359
HRESULT InternalQueryInterface(REFIID iid, void **iface)
QString text
the action&#39;s descriptive text
Definition: qaction.h:76
STDMETHOD() FreezeEvents(BOOL)
int qt_metacall(QMetaObject::Call, int index, void **argv)
Catches all signals emitted by the Qt widget and fires the respective COM event.
STDMETHOD() Load(IStream *pStm)
STDMETHOD() Unadvise(DWORD dwConnection)
unsigned long ref
void removeEventFilter(QObject *)
Removes an event filter object obj from this object.
Definition: qobject.cpp:2099
Qt::FocusPolicy focusPolicy
the way the widget accepts keyboard focus
Definition: qwidget.h:187
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
STDMETHOD() Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexcepinfo, UINT *puArgErr)
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
QAxServerBase * object
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the list.
Definition: qlist.h:269
const char * mime
void createMenu(QMenuBar *menuBar)
Creates a Win32 menubar.
static const QMetaObject staticMetaObject
This variable stores the meta-object for the class.
Definition: qobject.h:128
QPointer< QStatusBar > statusBar
void updateMask()
Updates the mask of the widget parent.
The QAxFactory class defines a factory for the creation of COM components.
Definition: qaxfactory.h:64
HRESULT WINAPI CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppObject)
IOleClientSite * m_spClientSite
QWidget * nextInFocusChain() const
Returns the next widget in this widget&#39;s focus chain.
Definition: qwidget.cpp:6873
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
HRESULT WINAPI RequestLicKey(DWORD, BSTR *pKey)
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
STDMETHOD() ReactivateAndUndo()
struct tagFORMATETC FORMATETC
Definition: qmime.h:66
The QBuffer class provides a QIODevice interface for a QByteArray.
Definition: qbuffer.h:57
virtual bool writeData(QIODevice *sink)
If the COM object supports a MIME type then this function is called to store the COM object into sink...
int propertyCount() const
Returns the number of properties in this class, including the number of properties provided by each b...
STDMETHOD() SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
The QString class provides a Unicode character string.
Definition: qstring.h:83
void setHeight(int h)
Sets the height to the given height.
Definition: qsize.h:135
const char * typeName() const
Returns the return type of this method, or an empty string if the return type is void.
QColor OLEColorToQColor(uint col)
Definition: qaxtypes.cpp:216
STDMETHOD() Draw(DWORD dwAspect, LONG lIndex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDevice, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL(__stdcall *pfnContinue)(ULONG_PTR), ULONG_PTR dwContinue)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define SetWindowOrgEx(a, b, c, d)
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
const char * value() const
Returns the value of this item.
ITypeLib * qAxTypeLibrary
Definition: qaxserver.cpp:66
IOleInPlaceFrame * m_spInPlaceFrame
QtMsgType
This enum describes the messages that can be sent to a message handler (QtMsgHandler).
Definition: qglobal.h:1881
STDMETHOD() FindConnectionPoint(REFIID, IConnectionPoint **)
STDMETHOD() Unfreeze(DWORD dwFreeze)
unsigned long ref
virtual QStringList featureList() const =0
Reimplement this function to return a list of the widgets (class names) supported by this factory...
int indexOfProperty(const char *name) const
Finds property name and returns its index; otherwise returns -1.
STDMETHOD() GetCurFile(LPOLESTR *currentFile)
QPointer< QObject > theObject
QStringList keys
unsigned stayTopLevel
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
const char * className
Definition: qwizard.cpp:137
STDMETHOD() DUnadvise(DWORD dwConnection)
QObject * qObject() const
HMENU createPopup(QMenu *popup, HMENU oldMenu=0)
static int mapModifiers(int state)
bool isNull() const
Returns true if this is the null UUID {00000000-0000-0000-0000-000000000000}; otherwise returns false...
Definition: quuid.cpp:700
iterator Iterator
Qt-style synonym for QList::iterator.
Definition: qlist.h:278
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
Definition: qobject.cpp:2327
void setVersion(int)
Sets the version number of the data serialization format to v.
Definition: qdatastream.h:215
STDMETHOD() EnumConnectionPoints(IEnumConnectionPoints **)
QObject * the_object
Definition: qaxaggregated.h:79
The QStatusBar class provides a horizontal bar suitable for presenting status information.
Definition: qstatusbar.h:57
HRESULT WINAPI QueryInterface(REFIID iid, void **iface)
STDMETHOD() Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection)
bool isHidden() const
Returns true if the widget is hidden, otherwise returns false.
Definition: qwidget.h:1008
void setWidth(int w)
Sets the width to the given width.
Definition: qsize.h:132
#define ATOM(x)
Definition: qt_x11_p.h:723
QAxSignalVec(const QAxServerBase::ConnectionPoints &points)
STDMETHOD() OnDocWindowActivate(BOOL fActivate)
The QAxAggregated class is an abstract base class for implementations of additional COM interfaces...
Definition: qaxaggregated.h:58
void internalConnect()
Connects object signals to event dispatcher.
STDMETHOD() TranslateAcceleratorW(MSG *pMsg)
unsigned long qaxserverbase_instance_count
QAxServerBase(const QString &classname, IUnknown *outerUnknown)
Constructs a QAxServerBase object wrapping the QWidget classname into an ActiveX control.
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately after the event occurred.
Definition: qevent.cpp:999
int key() const
Returns the code of the key that was pressed or released.
Definition: qevent.h:231
STDMETHOD() DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
void updateGeometry()
Updates the internal size values.
STDMETHOD() InPlaceDeactivate()
int width() const
Returns the width.
Definition: qsize.h:126
static QWidget * activeModalWidget()
Returns the active modal widget.
virtual QAxAggregated * createAggregate()
Reimplement this function when you want to implement additional COM interfaces in the ActiveX control...
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
QPointer< QMenu > currentPopup
bool atEnd() const
Reimplemented Function
Definition: qbuffer.cpp:408
#define QT_WIN_CALLBACK
Definition: qglobal.h:1178
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QObject * object
QAxAggregated * aggregatedObject
CRITICAL_SECTION refCountSection
STDMETHOD() SetColorScheme(LOGPALETTE *pLogPal)
QAxExceptInfo(int c, const QString &s, const QString &d, const QString &x)
STDMETHOD() EnableModeless(BOOL)
void qWinMsgHandler(QtMsgType t, const char *str)
IAdviseSink * m_spAdviseSink
STDMETHOD() ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow)
STDMETHOD() Freeze(DWORD dwAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze)
CRITICAL_SECTION refCountSection
void init()
Initializes data members.
void registerActiveObject(IUnknown *object)
STDMETHOD() GetUserClassID(CLSID *pClsid)
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
#define WM_NCDESTROY
IAxServerBase * activex
Definition: qaxbindable.h:80
STDMETHOD() GetControlInfo(LPCONTROLINFO)
int height
the height of the widget excluding any window frame
Definition: qwidget.h:167
const QChar * unicode() const
Returns a &#39;\0&#39;-terminated Unicode representation of the string.
Definition: qstring.h:706
void raise()
Raises this widget to the top of the parent widget&#39;s stack.
Definition: qwidget.cpp:11901
QByteArray & buffer()
Returns a reference to the QBuffer&#39;s internal buffer.
Definition: qbuffer.cpp:271
virtual bool hasStockEvents(const QString &key) const
Reimplement this function to return true if the ActiveX control key should support the standard Activ...
Definition: qaxfactory.cpp:353
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
QList< STATDATA > adviseSinks
#define qApp
static bool init
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
STDMETHOD() IsUpToDate()
const char * name
const T value(const Key &key) const
Returns the value associated with the key key.
Definition: qmap.h:499
unsigned long WINAPI Release()
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
void revokeActiveObject()
static QWidget * find(WId)
Returns a pointer to the widget with window identifer/handle id.
Definition: qwidget.cpp:2517
static bool sendSpontaneousEvent(QObject *receiver, QEvent *event)
The QResizeEvent class contains event parameters for resize events.
Definition: qevent.h:349
bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out)
Definition: qaxtypes.cpp:246
Q_CORE_EXPORT void qWarning(const char *,...)
unsigned canTakeFocus
STDMETHOD() EnumAdvise(IEnumSTATDATA **ppenumAdvise)
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
STDMETHOD() DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
Type
This enum type defines the types of variable that a QVariant can contain.
Definition: qvariant.h:95
#define FALSE
Synonym for false.
Definition: qglobal.h:1019
STDMETHOD() InitFromData(IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved)
static bool disconnect(const QObject *sender, int signal_index, const QObject *receiver, int method_index)
Definition: qobject.cpp:3276
HRESULT WINAPI CreateInstanceHelper(IUnknown *pUnkOuter, REFIID iid, void **ppObject)
struct tagSTGMEDIUM STGMEDIUM
Definition: qmime.h:67
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
STDMETHOD() OnMnemonic(LPMSG)
HRESULT WINAPI CreateInstanceLic(IUnknown *pUnkOuter, IUnknown *pUnkReserved, REFIID iid, BSTR bKey, PVOID *ppObject)
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
#define MAP_PIX_TO_LOGHIM(x, ppli)
Definition: qaxtypes.h:72
int indexOfSlot(const char *slot) const
Finds slot and returns its index; otherwise returns -1.
int indexOfSignal(const char *signal) const
Finds signal and returns its index; otherwise returns -1.
virtual bool readData(QIODevice *source, const QString &format)
If the COM object supports a MIME type then this function is called to initialize the COM object from...
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
STDMETHOD() UIDeactivate()
QByteArray left(int len) const
Returns a byte array that contains the leftmost len bytes of this byte array.
STDMETHOD() GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid)
void * HANDLE
Definition: qnamespace.h:1671
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.
quint16 values[128]
void show()
Shows the widget and its child widgets.
QByteArray mid(int index, int len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos...
virtual bool stayTopLevel(const QString &key) const
Reimplement this function to return true if the ActiveX control key should be a top level window...
Definition: qaxfactory.cpp:330
virtual QUuid eventsID(const QString &key) const
Reimplement this function to return the identifier of the event interface for each key returned by th...
Definition: qaxfactory.cpp:228
const char * typeName() const
Returns the name of the type stored in the variant.
Definition: qvariant.cpp:1984
unsigned initNewCalled
int indexOf(char c, int from=0) const
Returns the index position of the first occurrence of the character ch in the byte array...
STDMETHOD() SetMoniker(DWORD dwWhichMoniker, IMoniker *ppmk)
unsigned long WINAPI AddRef()
Qt::MouseButton button() const
Returns the button that caused the event.
Definition: qevent.h:101
int count() const
Definition: qstring.h:103
bool isEnabled() const
Definition: qwidget.h:948
QAxSignalVec(const QAxSignalVec &old)
ITypeInfo * m_spTypeInfo
STDMETHOD() GetClassInfo(ITypeInfo **pptinfo)
void hide()
Hides the widget.
Definition: qwidget.h:501
STDMETHOD() SaveCompleted(IStorage *pStgNew)
virtual bool eventFilter(QObject *, QEvent *)
Filters events if this object has been installed as an event filter for the watched object...
Definition: qobject.cpp:1375
QMap< QUuid, IConnectionPoint * >::Iterator ConnectionPointsIterator
The QMouseEvent class contains parameters that describe a mouse event.
Definition: qevent.h:85
#define rgb(r, g, b)
Definition: qcolor_p.cpp:130
iterator begin()
Returns an STL-style iterator pointing to the first item in the map.
Definition: qmap.h:372
#define TRUE
Synonym for true.
Definition: qglobal.h:1018
int version() const
Returns the version number of the data serialization format.
Definition: qdatastream.h:212
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
The QChildEvent class contains event parameters for child object events.
Definition: qcoreevent.h:353
bool eventFilter(QObject *o, QEvent *e)
Filters events if this object has been installed as an event filter for the watched object...
STDMETHOD() HandsOffStorage()
bool ignoreSlots(const char *test)
Definition: qaxserver.cpp:673
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
CRITICAL_SECTION refCountSection
MethodType methodType() const
Returns the type of this method (signal, slot, or method).
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition: qstring.h:505
static QByteArray prototype(const QList< QByteArray > &parameterTypes, const QList< QByteArray > &parameterNames, bool *ok)
Definition: qaxserver.cpp:685
STDMETHOD() GetDataHere(FORMATETC *, STGMEDIUM *)
HANDLE qAxInstance
Definition: qaxserver.cpp:65
int remove(const Key &key)
Removes all the items that have the key key from the map.
Definition: qmap.h:662
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
QAxServerAggregate(const QString &className, IUnknown *outerUnknown)
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays...
void ensureMetaData()
Makes sure the type info is loaded.
void setFocus()
Gives the keyboard input focus to this widget (or its focus proxy) if this widget or one of its paren...
Definition: qwidget.h:432
void update()
Updates the view, or asks the client site to do so.
HRESULT WINAPI QueryInterface(REFIID iid, LPVOID *iface)
unsigned long ole_ref
struct tagMSG MSG
long HRESULT
bool isWidgetType() const
Returns true if the object is a widget; otherwise returns false.
Definition: qobject.h:146
QMenu * menu() const
Returns the menu contained by this action.
Definition: qaction.cpp:793
QMap< HMENU, QMenu * > menuMap
bool ignoreProps(const char *test)
Definition: qaxserver.cpp:678
#define MM_ANISOTROPIC
IUnknown * m_outerUnknown
unsigned long ref
The QMenuBar class provides a horizontal menu bar.
Definition: qmenubar.h:62
Qt::MouseButtons buttons() const
Returns the button state when the event was generated.
Definition: qevent.h:102
unsigned long qAxLock()
Definition: qaxserver.cpp:158
STDMETHOD() SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink)
STDMETHOD() GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
The QMenu class provides a menu widget for use in menu bars, context menus, and other popup menus...
Definition: qmenu.h:72
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
STDMETHOD() GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
HBITMAP toWinHBITMAP(HBitmapFormat format=NoAlpha) const
It is the caller&#39;s responsibility to free the HBITMAP data after use.
The QMap::iterator class provides an STL-style non-const iterator for QMap and QMultiMap.
Definition: qmap.h:233
unsigned long WINAPI AddRef()
const char * name() const
Returns this property&#39;s name.
LRESULT QT_WIN_CALLBACK axs_FilterProc(int nCode, WPARAM wParam, LPARAM lParam)
unsigned long WINAPI Release()
STDMETHOD() GetCanonicalFormatEtc(FORMATETC *, FORMATETC *)
virtual bool validateLicenseKey(const QString &key, const QString &licenseKey) const
Reimplement this function to return true if licenseKey is a valid license for the class key...
Definition: qaxfactory.cpp:282
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
QtMsgHandler qInstallMsgHandler(QtMsgHandler h)
Definition: qglobal.cpp:2698
HRESULT WINAPI LockServer(BOOL fLock)
unsigned long ref
QString text() const
Returns the Unicode text that this key generated.
Definition: qevent.h:236
void removeMenu()
Remove the Win32 menubar.
IUnknown * controlling_unknown
Definition: qaxaggregated.h:78
STDMETHOD() GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
unsigned short ushort
Definition: qglobal.h:995
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:375
static QByteArray paramType(const QByteArray &ptype, bool *out)
HRESULT WINAPI GetLicInfo(LICINFO *pLicInfo)
int lastIndexOf(QChar c, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:3000
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
int y() const
Returns the y position of the mouse cursor, relative to the widget that received the event...
Definition: qevent.h:98
unsigned dirtyflag
iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:559
EventFilter setEventFilter(EventFilter filter)
Replaces the event filter function for this QAbstractEventDispatcher with filter and returns the repl...
CRITICAL_SECTION createWindowSection
HRESULT GetClassObject(REFIID clsid, REFIID iid, void **ppUnk)
bool qt_sendSpontaneousEvent(QObject *, QEvent *)
static LRESULT QT_WIN_CALLBACK ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
const void * constData() const
Definition: qvariant.cpp:3065
int key
void setColor(ColorGroup cg, ColorRole cr, const QColor &color)
Sets the color in the specified color group, used for the given color role, to the specified solid co...
Definition: qpalette.h:201
Q_DECL_CONSTEXPR const T & qBound(const T &min, const T &val, const T &max)
Definition: qglobal.h:1219
void installEventFilter(QObject *)
Installs an event filter filterObj on this object.
Definition: qobject.cpp:2070
static BSTR QStringToBSTR(const QString &str)
Definition: qaxtypes.h:76
void resize(const QSize &newSize)
Resizes the control, faking a QResizeEvent if required.
virtual bool focusNextPrevChild(bool next)
Finds a new widget to give the keyboard focus to, as appropriate for Tab and Shift+Tab, and returns true if it can find a new widget, or false if it can&#39;t.
Definition: qwidget.cpp:6836
void resize(int size)
Sets the size of the byte array to size bytes.
QList< QAction * > actions() const
Returns the (possibly empty) list of this widget&#39;s actions.
Definition: qwidget.cpp:3407
#define SW_NORMAL
unsigned long __stdcall Release()
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
int & rheight()
Returns a reference to the height.
Definition: qsize.h:144
STDMETHOD() SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
Policy verticalPolicy() const
Definition: qsizepolicy.h:119
bool internalCreate()
Creates the QWidget for the classname passed to the c&#39;tor.
int height() const
Returns the height.
Definition: qsize.h:129
unsigned wasUIActive
if(void) toggleToolbarShown
QList< IConnectionPoint * > cpoints
bool isValid() const
Returns true if both the width and height is equal to or greater than 0; otherwise returns false...
Definition: qsize.h:123
QWidget * widget
STDMETHOD() GetGUID(DWORD dwGuidKind, GUID *pGUID)
GUID IID_IAxServerBase
STDMETHOD() SetClientSite(IOleClientSite *pClientSite)
QString currentFileName
bool isPropertyExposed(int index)
Returns true if the property index is exposed to COM and should be saved/loaded.
const QObjectList & children() const
Returns a list of child objects.
Definition: qobject.h:197
T qvariant_cast(const QVariant &)
Definition: qvariant.h:571
bool isChecked() const
Definition: qaction.cpp:1151
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
void reportError(int code, const QString &src, const QString &desc, const QString &context)
virtual long queryInterface(const QUuid &iid, void **iface)=0
Reimplement this pure virtual function to support additional COM interfaces.
QList< CONNECTDATA > Connections
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
Definition: qwidget.cpp:11087
bool isReadable() const
Returns true if this property is readable; otherwise returns false.
QAxExceptInfo * exception
quint16 index
QVariant property(const char *name) const
Returns the value of the object&#39;s name property.
Definition: qobject.cpp:3807
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
int height() const
Returns the height of the pixmap.
Definition: qpixmap.cpp:645
HWND create(HWND hWndParent, RECT &rcPos)
Creates the window hosting the QWidget.
STDMETHOD() GetClipboardData(DWORD dwReserved, IDataObject **ppDataObject)
STDMETHOD() Update()
STDMETHOD() GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo)
QMetaMethod method(int index) const
Returns the meta-data for the method with the given index.
STDMETHOD() SetData(FORMATETC *, STGMEDIUM *, BOOL)
The QMetaProperty class provides meta-data about a property.
Definition: qmetaobject.h:176
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
QHash< int, DISPID > signalCache
unsigned long __stdcall AddRef()
STDMETHOD() GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet)
bool qAxOutProcServer
Definition: qaxserver.cpp:68
WId winId() const
Returns the window system identifier of the widget.
Definition: qwidget.cpp:2557
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
IUnknown * clientSite() const
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71
STDMETHOD() EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
bool qax_ownQApp
STDMETHOD() GetWindow(HWND *pHwnd)
void setSizeGripEnabled(bool)
Definition: qstatusbar.cpp:504
const char * signature() const
Returns the signature of this method (e.g., setValue(double)).
const char * variant
STDMETHOD() TranslateAcceleratorA(MSG *pMsg)
unsigned long __stdcall AddRef()
void emitPropertyChanged(const char *)
Call IPropertyNotifySink of connected clients.
STDMETHOD() Save(IStream *pStm, BOOL fClearDirty)
virtual const QMetaObject * metaObject(const QString &key) const =0
Reimplement this function to return the QMetaObject corresponding to key, or 0 if this factory doesn&#39;...
static LPOLESTR QStringToOLESTR(const QString &qstring)
Q_CORE_EXPORT int qstricmp(const char *, const char *)
QHash< long, int > indexCache
void internalBind()
Detects and initilaizes implementation of QAxBindable in objects.
virtual QObject * createObject(const QString &key)=0
Reimplement this function to return a new object for key, or 0 if this factory doesn&#39;t support the va...
int indexOfEnumerator(const char *name) const
Finds enumerator name and returns its index; otherwise returns -1.
bool isValid() const
Returns true if the storage type of this variant is not QVariant::Invalid; otherwise returns false...
Definition: qvariant.h:485
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately before the event occurred.
Definition: qevent.h:79
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
QPointer< QMenuBar > menuBar
QAxConnection(QAxServerBase *parent, const QUuid &uuid)
QMap< QUuid, IConnectionPoint * > ConnectionPoints
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
int indexOfClassInfo(const char *name) const
Finds class information item name and returns its index; otherwise returns -1.
unsigned hasStockEvents
unsigned ownObject
ConnectionPoints points
STDMETHOD() EnumFormatEtc(DWORD, IEnumFORMATETC **)
#define QAX_INPROC_SERVER
Definition: qaxtypes.h:93
static QString fileName(const QString &fileUrl)
STDMETHOD() IsDirty()
int methodCount() const
Returns the number of methods known to the meta-object system in this class, including the number of ...
~QAxServerBase()
Destroys the QAxServerBase object, releasing all allocated resources and interfaces.
unsigned long WINAPI AddRef()
STDMETHOD() Close(DWORD dwSaveOption)
bool qax_disable_inplaceframe
const char * typeName() const
Returns the name of this property&#39;s type.
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
unsigned isInPlaceActive
The QMetaMethod class provides meta-data about a member function.
Definition: qmetaobject.h:56
unsigned isUIActive
static QPixmap grabWidget(QWidget *widget, const QRect &rect)
Creates a pixmap and paints the given widget, restricted by the given rectangle, in it...
Definition: qpixmap.cpp:1188
void clear()
Removes all items from the map.
Definition: qmap.h:444
The QAction class provides an abstract user interface action that can be inserted into widgets...
Definition: qaction.h:64
STDMETHOD() QueryGetData(FORMATETC *)
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
The QUuid class stores a Universally Unique Identifier (UUID).
Definition: quuid.h:67
static void enterWhatsThisMode()
This function switches the user interface into "What&#39;s This?" mode.
Definition: qwhatsthis.cpp:633
static void leaveWhatsThisMode()
If the user interface is in "What&#39;s This?" mode, this function switches back to normal mode; otherwis...
Definition: qwhatsthis.cpp:662
#define GMEM_MOVEABLE
QMetaProperty property(int index) const
Returns the meta-data for the property with the given index.
Handle handle() const
Returns a platform-specific region handle.
virtual QUuid classID(const QString &key) const
Reimplement this function to return the class identifier for each key returned by the featureList() i...
Definition: qaxfactory.cpp:191
int & rwidth()
Returns a reference to the width.
Definition: qsize.h:141
void move(int x, int y)
This corresponds to move(QPoint(x, y)).
Definition: qwidget.h:1011
static int invokeCount
bool endsWith(const QByteArray &a) const
Returns true if this byte array ends with byte array ba; otherwise returns false. ...
IOleInPlaceSiteWindowless * m_spInPlaceSite
int x() const
Returns the x position of the mouse cursor, relative to the widget that received the event...
Definition: qevent.h:97
STDMETHOD() EnumVerbs(IEnumOLEVERB **ppEnumOleVerb)
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:272
STDMETHOD() GetClientSite(IOleClientSite **ppClientSite)
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
static bool checkHRESULT(HRESULT hres)
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:61
void removeAt(int i)
Removes the item at index position i.
Definition: qlist.h:480