src/activeqt/container/qaxwidget.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the ActiveQt framework of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:BSD$
       
    10 ** You may use this file under the terms of the BSD license as follows:
       
    11 **
       
    12 ** "Redistribution and use in source and binary forms, with or without
       
    13 ** modification, are permitted provided that the following conditions are
       
    14 ** met:
       
    15 **   * Redistributions of source code must retain the above copyright
       
    16 **     notice, this list of conditions and the following disclaimer.
       
    17 **   * Redistributions in binary form must reproduce the above copyright
       
    18 **     notice, this list of conditions and the following disclaimer in
       
    19 **     the documentation and/or other materials provided with the
       
    20 **     distribution.
       
    21 **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
       
    22 **     the names of its contributors may be used to endorse or promote
       
    23 **     products derived from this software without specific prior written
       
    24 **     permission.
       
    25 **
       
    26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
       
    37 ** $QT_END_LICENSE$
       
    38 **
       
    39 ****************************************************************************/
       
    40 
       
    41 #include "qaxwidget.h"
       
    42 
       
    43 #ifndef QT_NO_WIN_ACTIVEQT
       
    44 
       
    45 #include <ActiveQt/qaxaggregated.h>
       
    46 
       
    47 #include <qabstracteventdispatcher.h>
       
    48 #include <qapplication.h>
       
    49 #include <private/qapplication_p.h>
       
    50 #include <qdockwidget.h>
       
    51 #include <qevent.h>
       
    52 #include <qlayout.h>
       
    53 #include <qmainwindow.h>
       
    54 #include <qmenu.h>
       
    55 #include <qmenubar.h>
       
    56 #include <qmetaobject.h>
       
    57 #include <qpainter.h>
       
    58 #include <qpointer.h>
       
    59 #include <qregexp.h>
       
    60 #include <quuid.h>
       
    61 #include <qwhatsthis.h>
       
    62 
       
    63 #include <windowsx.h>
       
    64 #include <ocidl.h>
       
    65 #include <olectl.h>
       
    66 #include <docobj.h>
       
    67 
       
    68 // #define QAX_DEBUG
       
    69 
       
    70 #ifdef QAX_DEBUG
       
    71 #define AX_DEBUG(x) qDebug(#x);
       
    72 #else
       
    73 #define AX_DEBUG(x);
       
    74 #endif
       
    75 
       
    76 // #define QAX_SUPPORT_WINDOWLESS
       
    77 // #define QAX_SUPPORT_BORDERSPACE
       
    78 
       
    79 // missing interface from win32api
       
    80 #if defined(Q_CC_GNU)
       
    81 #   if !defined(IOleInPlaceObjectWindowless)
       
    82 #       undef INTERFACE
       
    83 #       define INTERFACE IOleInPlaceObjectWindowless
       
    84         DECLARE_INTERFACE_(IOleInPlaceObjectWindowless,IOleInPlaceObject)
       
    85         {
       
    86            STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
       
    87            STDMETHOD_(ULONG,AddRef)(THIS) PURE;
       
    88            STDMETHOD_(ULONG,Release)(THIS) PURE;
       
    89            STDMETHOD(GetWindow)(THIS_ HWND*) PURE;
       
    90            STDMETHOD(ContextSensitiveHelp)(THIS_ BOOL) PURE;
       
    91            STDMETHOD(InPlaceDeactivate)(THIS) PURE;
       
    92            STDMETHOD(UIDeactivate)(THIS) PURE;
       
    93            STDMETHOD(SetObjectRects)(THIS_ LPCRECT,LPCRECT) PURE;
       
    94            STDMETHOD(ReactivateAndUndo)(THIS) PURE;
       
    95            STDMETHOD(OnWindowMessage)(THIS_ UINT, WPARAM, LPARAM, LRESULT*) PURE;
       
    96            STDMETHOD(GetDropTarget)(THIS_ IDropTarget**) PURE;
       
    97         };
       
    98 #   endif
       
    99 #endif
       
   100 
       
   101 #include "../shared/qaxtypes.h"
       
   102 
       
   103 QT_BEGIN_NAMESPACE
       
   104 
       
   105 /*  \class QAxHostWidget
       
   106     \brief The QAxHostWidget class is the actual container widget.
       
   107 
       
   108     \internal
       
   109 */
       
   110 class QAxHostWidget : public QWidget
       
   111 {
       
   112     friend class QAxClientSite;
       
   113 public:
       
   114     Q_OBJECT_CHECK
       
   115     QAxHostWidget(QWidget *parent, QAxClientSite *ax);
       
   116     ~QAxHostWidget();
       
   117 
       
   118     QSize sizeHint() const;
       
   119     QSize minimumSizeHint() const;
       
   120 
       
   121     int qt_metacall(QMetaObject::Call, int isignal, void **argv);
       
   122     void* qt_metacast(const char *clname);
       
   123 
       
   124     inline QAxClientSite *clientSite() const
       
   125     {
       
   126         return axhost;
       
   127     }
       
   128 
       
   129 protected:
       
   130     bool winEvent(MSG *msg, long *result);
       
   131     bool event(QEvent *e);
       
   132     bool eventFilter(QObject *o, QEvent *e);
       
   133     void resizeEvent(QResizeEvent *e);
       
   134     void focusInEvent(QFocusEvent *e);
       
   135     void focusOutEvent(QFocusEvent *e);
       
   136     void paintEvent(QPaintEvent *e);
       
   137     void showEvent(QShowEvent *e);
       
   138     QPaintEngine* paintEngine() const
       
   139     {
       
   140         return 0;
       
   141     }
       
   142 
       
   143 private:
       
   144     void resizeObject();
       
   145 
       
   146     int setFocusTimer;
       
   147     bool hasFocus;
       
   148     QAxClientSite *axhost;
       
   149 };
       
   150 
       
   151 /*  \class QAxClientSite
       
   152     \brief The QAxClientSite class implements the client site interfaces.
       
   153 
       
   154     \internal
       
   155 */
       
   156 class QAxClientSite : public IDispatch,
       
   157                     public IOleClientSite,
       
   158                     public IOleControlSite,
       
   159 #ifdef QAX_SUPPORT_WINDOWLESS
       
   160                     public IOleInPlaceSiteWindowless,
       
   161 #else
       
   162                     public IOleInPlaceSite,
       
   163 #endif
       
   164                     public IOleInPlaceFrame,
       
   165                     public IOleDocumentSite,
       
   166                     public IAdviseSink
       
   167 {
       
   168     friend class QAxHostWidget;
       
   169 public:
       
   170     QAxClientSite(QAxWidget *c);
       
   171     virtual ~QAxClientSite();
       
   172 
       
   173     bool activateObject(bool initialized, const QByteArray &data);
       
   174 
       
   175     void releaseAll();
       
   176     void deactivate();
       
   177     inline void reset(QWidget *p)
       
   178     {
       
   179         if (widget == p)
       
   180             widget = 0;
       
   181         else if (host == p)
       
   182             host = 0;
       
   183     }
       
   184 
       
   185     inline IOleInPlaceActiveObject *inPlaceObject() const
       
   186     {
       
   187         return m_spInPlaceActiveObject;
       
   188     }
       
   189 
       
   190     inline HRESULT doVerb(LONG index)
       
   191     {
       
   192         if (!m_spOleObject)
       
   193             return E_NOTIMPL;
       
   194         if (!host)
       
   195             return OLE_E_NOT_INPLACEACTIVE;
       
   196 
       
   197         RECT rcPos = { host->x(), host->y(), host->x()+host->width(), host->y()+host->height() };
       
   198         return m_spOleObject->DoVerb(index, 0, this, 0, host->winId(), &rcPos);
       
   199     }
       
   200 
       
   201     // IUnknown
       
   202     unsigned long WINAPI AddRef();
       
   203     unsigned long WINAPI Release();
       
   204     STDMETHOD(QueryInterface)(REFIID iid, void **iface);
       
   205 
       
   206     // IDispatch
       
   207     HRESULT __stdcall GetTypeInfoCount(unsigned int *) { return E_NOTIMPL; }
       
   208     HRESULT __stdcall GetTypeInfo(UINT, LCID, ITypeInfo **) { return E_NOTIMPL; }
       
   209     HRESULT __stdcall GetIDsOfNames(const _GUID &, wchar_t **, unsigned int, unsigned long, long *) { return E_NOTIMPL; }
       
   210     HRESULT __stdcall Invoke(DISPID dispIdMember,
       
   211         REFIID riid,
       
   212         LCID lcid,
       
   213         WORD wFlags,
       
   214         DISPPARAMS *pDispParams,
       
   215         VARIANT *pVarResult,
       
   216         EXCEPINFO *pExcepInfo,
       
   217         UINT *puArgErr);
       
   218     void emitAmbientPropertyChange(DISPID dispid);
       
   219 
       
   220     // IOleClientSite
       
   221     STDMETHOD(SaveObject)();
       
   222     STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk);
       
   223     STDMETHOD(GetContainer)(LPOLECONTAINER FAR* ppContainer);
       
   224     STDMETHOD(ShowObject)();
       
   225     STDMETHOD(OnShowWindow)(BOOL fShow);
       
   226     STDMETHOD(RequestNewObjectLayout)();
       
   227 
       
   228     // IOleControlSite
       
   229     STDMETHOD(OnControlInfoChanged)();
       
   230     STDMETHOD(LockInPlaceActive)(BOOL fLock);
       
   231     STDMETHOD(GetExtendedControl)(IDispatch** ppDisp);
       
   232     STDMETHOD(TransformCoords)(POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags);
       
   233     STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, DWORD grfModifiers);
       
   234     STDMETHOD(OnFocus)(BOOL fGotFocus);
       
   235     STDMETHOD(ShowPropertyFrame)();
       
   236 
       
   237     // IOleWindow
       
   238     STDMETHOD(GetWindow)(HWND *phwnd);
       
   239     STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode);
       
   240 
       
   241     // IOleInPlaceSite
       
   242     STDMETHOD(CanInPlaceActivate)();
       
   243     STDMETHOD(OnInPlaceActivate)();
       
   244     STDMETHOD(OnUIActivate)();
       
   245     STDMETHOD(GetWindowContext)(IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo);
       
   246     STDMETHOD(Scroll)(SIZE scrollExtant);
       
   247     STDMETHOD(OnUIDeactivate)(BOOL fUndoable);
       
   248     STDMETHOD(OnInPlaceDeactivate)();
       
   249     STDMETHOD(DiscardUndoState)();
       
   250     STDMETHOD(DeactivateAndUndo)();
       
   251     STDMETHOD(OnPosRectChange)(LPCRECT lprcPosRect);
       
   252 
       
   253 #ifdef QAX_SUPPORT_WINDOWLESS
       
   254 // IOleInPlaceSiteEx ###
       
   255     STDMETHOD(OnInPlaceActivateEx)(BOOL* /*pfNoRedraw*/, DWORD /*dwFlags*/)
       
   256     {
       
   257         return S_OK;
       
   258     }
       
   259     STDMETHOD(OnInPlaceDeactivateEx)(BOOL /*fNoRedraw*/)
       
   260     {
       
   261         return S_OK;
       
   262     }
       
   263     STDMETHOD(RequestUIActivate)()
       
   264     {
       
   265         return S_OK;
       
   266     }
       
   267 
       
   268 // IOleInPlaceSiteWindowless ###
       
   269     STDMETHOD(CanWindowlessActivate)()
       
   270     {
       
   271         return S_OK;
       
   272     }
       
   273     STDMETHOD(GetCapture)()
       
   274     {
       
   275         return S_FALSE;
       
   276     }
       
   277     STDMETHOD(SetCapture)(BOOL /*fCapture*/)
       
   278     {
       
   279         return S_FALSE;
       
   280     }
       
   281     STDMETHOD(GetFocus)()
       
   282     {
       
   283         return S_FALSE;
       
   284     }
       
   285     STDMETHOD(SetFocus)(BOOL /*fCapture*/)
       
   286     {
       
   287         return S_FALSE;
       
   288     }
       
   289     STDMETHOD(GetDC)(LPCRECT /*pRect*/, DWORD /*grfFlags*/, HDC *phDC)
       
   290     {
       
   291         *phDC = 0;
       
   292         return S_OK;
       
   293     }
       
   294     STDMETHOD(ReleaseDC)(HDC hDC)
       
   295     {
       
   296         ::ReleaseDC(widget->winId(), hDC);
       
   297         return S_OK;
       
   298     }
       
   299     STDMETHOD(InvalidateRect)(LPCRECT pRect, BOOL fErase)
       
   300     {
       
   301         ::InvalidateRect(host->winId(), pRect, fErase);
       
   302         return S_OK;
       
   303     }
       
   304     STDMETHOD(InvalidateRgn)(HRGN hRGN, BOOL fErase)
       
   305     {
       
   306         ::InvalidateRgn(host->winId(), hRGN, fErase);
       
   307         return S_OK;
       
   308     }
       
   309     STDMETHOD(ScrollRect)(int /*dx*/, int /*dy*/, LPCRECT /*pRectScroll*/, LPCRECT /*pRectClip*/)
       
   310     {
       
   311         return S_OK;
       
   312     }
       
   313     STDMETHOD(AdjustRect)(LPRECT /*prc*/)
       
   314     {
       
   315         return S_OK;
       
   316     }
       
   317 #ifdef Q_CC_GNU // signature incorrect in win32api
       
   318     STDMETHOD(AdjustRect)(LPCRECT /*prc*/)
       
   319     {
       
   320         RECT rect;
       
   321         return AdjustRect(&rect);
       
   322     }
       
   323 #endif
       
   324 
       
   325     STDMETHOD(OnDefWindowMessage)(UINT /*msg*/, WPARAM /*wPara*/, LPARAM /*lParam*/, LRESULT* /*plResult*/)
       
   326     {
       
   327         return S_FALSE;
       
   328     }
       
   329 #endif
       
   330 
       
   331     // IOleInPlaceFrame
       
   332     STDMETHOD(InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths));
       
   333     STDMETHOD(SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject));
       
   334     STDMETHOD(RemoveMenus(HMENU hmenuShared));
       
   335     STDMETHOD(SetStatusText(LPCOLESTR pszStatusText));
       
   336     STDMETHOD(EnableModeless(BOOL fEnable));
       
   337     STDMETHOD(TranslateAccelerator(LPMSG lpMsg, WORD grfModifiers));
       
   338 
       
   339     // IOleInPlaceUIWindow
       
   340     STDMETHOD(GetBorder(LPRECT lprectBorder));
       
   341     STDMETHOD(RequestBorderSpace(LPCBORDERWIDTHS pborderwidths));
       
   342     STDMETHOD(SetBorderSpace(LPCBORDERWIDTHS pborderwidths));
       
   343     STDMETHOD(SetActiveObject(IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName));
       
   344 
       
   345     // IOleDocumentSite
       
   346     STDMETHOD(ActivateMe(IOleDocumentView *pViewToActivate));
       
   347 
       
   348     // IAdviseSink
       
   349     STDMETHOD_(void, OnDataChange)(FORMATETC* /*pFormatetc*/, STGMEDIUM* /*pStgmed*/)
       
   350     {
       
   351         AX_DEBUG(QAxClientSite::OnDataChange);
       
   352     }
       
   353     STDMETHOD_(void, OnViewChange)(DWORD /*dwAspect*/, LONG /*lindex*/)
       
   354     {
       
   355         AX_DEBUG(QAxClientSite::OnViewChange);
       
   356     }
       
   357     STDMETHOD_(void, OnRename)(IMoniker* /*pmk*/)
       
   358     {
       
   359     }
       
   360     STDMETHOD_(void, OnSave)()
       
   361     {
       
   362     }
       
   363     STDMETHOD_(void, OnClose)()
       
   364     {
       
   365     }
       
   366 
       
   367     QSize sizeHint() const { return sizehint; }
       
   368     QSize minimumSizeHint() const;
       
   369     inline void resize(QSize sz) { if (host) host->resize(sz); }
       
   370 
       
   371     bool translateKeyEvent(int message, int keycode) const
       
   372     {
       
   373         if (!widget)
       
   374             return false;
       
   375         return widget->translateKeyEvent(message, keycode);
       
   376     }
       
   377 
       
   378     int qt_metacall(QMetaObject::Call, int isignal, void **argv);
       
   379     void windowActivationChange();
       
   380 
       
   381     bool eventTranslated : 1;
       
   382 
       
   383 private:
       
   384 #if !defined(Q_WS_WINCE)
       
   385     struct OleMenuItem {
       
   386         OleMenuItem(HMENU hm = 0, int ID = 0, QMenu *menu = 0)
       
   387             : hMenu(hm), id(ID), subMenu(menu)
       
   388         {}
       
   389         HMENU hMenu;
       
   390         int id;
       
   391         QMenu *subMenu;
       
   392     };
       
   393     QMenu *generatePopup(HMENU subMenu, QWidget *parent);
       
   394 #endif
       
   395 
       
   396     IOleObject *m_spOleObject;
       
   397     IOleControl *m_spOleControl;
       
   398     IOleInPlaceObjectWindowless *m_spInPlaceObject;
       
   399     IOleInPlaceActiveObject *m_spInPlaceActiveObject;
       
   400     IOleDocumentView *m_spActiveView;
       
   401 
       
   402     QAxAggregated *aggregatedObject;
       
   403 
       
   404     bool inPlaceObjectWindowless :1;
       
   405     bool inPlaceModelessEnabled :1;
       
   406     bool canHostDocument : 1;
       
   407 
       
   408     DWORD m_dwOleObject;
       
   409 #if !defined(Q_WS_WINCE)
       
   410     HWND m_menuOwner;
       
   411 #endif
       
   412     CONTROLINFO control_info;
       
   413 
       
   414     QSize sizehint;
       
   415     unsigned long ref;
       
   416     QAxWidget *widget;
       
   417     QAxHostWidget *host;
       
   418 #if !defined(Q_WS_WINCE)
       
   419     QPointer<QMenuBar> menuBar;
       
   420     QMap<QAction*,OleMenuItem> menuItemMap;
       
   421 #endif
       
   422 };
       
   423 
       
   424 static const ushort mouseTbl[] = {
       
   425     WM_MOUSEMOVE,       QEvent::MouseMove,              0,
       
   426     WM_LBUTTONDOWN,     QEvent::MouseButtonPress,       Qt::LeftButton,
       
   427     WM_LBUTTONUP,       QEvent::MouseButtonRelease,     Qt::LeftButton,
       
   428     WM_LBUTTONDBLCLK,   QEvent::MouseButtonDblClick,    Qt::LeftButton,
       
   429     WM_RBUTTONDOWN,     QEvent::MouseButtonPress,       Qt::RightButton,
       
   430     WM_RBUTTONUP,       QEvent::MouseButtonRelease,     Qt::RightButton,
       
   431     WM_RBUTTONDBLCLK,   QEvent::MouseButtonDblClick,    Qt::RightButton,
       
   432     WM_MBUTTONDOWN,     QEvent::MouseButtonPress,       Qt::MidButton,
       
   433     WM_MBUTTONUP,       QEvent::MouseButtonRelease,     Qt::MidButton,
       
   434     WM_MBUTTONDBLCLK,   QEvent::MouseButtonDblClick,    Qt::MidButton,
       
   435     0,                  0,                              0
       
   436 };
       
   437 
       
   438 static Qt::MouseButtons translateMouseButtonState(int s)
       
   439 {
       
   440     Qt::MouseButtons bst = 0;
       
   441     if (s & MK_LBUTTON)
       
   442         bst |= Qt::LeftButton;
       
   443     if (s & MK_MBUTTON)
       
   444         bst |= Qt::MidButton;
       
   445     if (s & MK_RBUTTON)
       
   446         bst |= Qt::RightButton;
       
   447 
       
   448     return bst;
       
   449 }
       
   450 
       
   451 static Qt::KeyboardModifiers translateModifierState(int s)
       
   452 {
       
   453     Qt::KeyboardModifiers bst = 0;
       
   454     if (s & MK_SHIFT)
       
   455         bst |= Qt::ShiftModifier;
       
   456     if (s & MK_CONTROL)
       
   457         bst |= Qt::ControlModifier;
       
   458     if (GetKeyState(VK_MENU) < 0)
       
   459         bst |= Qt::AltModifier;
       
   460 
       
   461     return bst;
       
   462 }
       
   463 
       
   464 static QAbstractEventDispatcher::EventFilter previous_filter = 0;
       
   465 #if QT_VERSION >= 0x050000
       
   466 #error "Fix QAbstractEventDispatcher::setEventFilter"
       
   467 #endif
       
   468 #if defined(Q_WS_WINCE)
       
   469 static int filter_ref = 0;
       
   470 #else
       
   471 static const wchar_t *qaxatom = L"QAxContainer4_Atom";
       
   472 #endif
       
   473 
       
   474 // The filter procedure listening to user interaction on the control
       
   475 bool axc_FilterProc(void *m)
       
   476 {
       
   477     MSG *msg = (MSG*)m;
       
   478     const uint message = msg->message;
       
   479     if ((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) || (message >= WM_KEYFIRST && message <= WM_KEYLAST)) {
       
   480         HWND hwnd = msg->hwnd;
       
   481         QAxWidget *ax = 0;
       
   482         QAxHostWidget *host = 0;
       
   483         while (!host && hwnd) {
       
   484             QWidget *widget = QWidget::find(hwnd);
       
   485             if (widget && widget->inherits("QAxHostWidget"))
       
   486                 host = qobject_cast<QAxHostWidget*>(widget);
       
   487             hwnd = ::GetParent(hwnd);
       
   488         }
       
   489         if (host)
       
   490             ax = qobject_cast<QAxWidget*>(host->parentWidget());
       
   491         if (ax && msg->hwnd != host->winId()) {
       
   492             if (message >= WM_KEYFIRST && message <= WM_KEYLAST) {
       
   493                 QAxClientSite *site = host->clientSite();
       
   494                 site->eventTranslated = true; // reset in QAxClientSite::TranslateAccelerator
       
   495                 HRESULT hres = S_FALSE;
       
   496                 if (site && site->inPlaceObject() && site->translateKeyEvent(msg->message, msg->wParam))
       
   497                     hres = site->inPlaceObject()->TranslateAccelerator(msg);
       
   498                 // if the object calls our TranslateAccelerator implementation, then continue with normal event processing
       
   499                 // otherwise the object has translated the accelerator, and the event should be stopped
       
   500                 if (site->eventTranslated && hres == S_OK)
       
   501                     return true;
       
   502             } else {
       
   503                 int i;
       
   504                 for (i = 0; (UINT)mouseTbl[i] != message && mouseTbl[i]; i += 3)
       
   505                     ;
       
   506 
       
   507                 if (mouseTbl[i]) {
       
   508                     QEvent::Type type = (QEvent::Type)mouseTbl[++i];
       
   509                     int button = mouseTbl[++i];
       
   510                     if (type != QEvent::MouseMove || ax->hasMouseTracking() || button) {
       
   511                         if (type == QEvent::MouseMove)
       
   512                             button = 0;
       
   513 
       
   514                         DWORD ol_pos = GetMessagePos();
       
   515                         QPoint gpos(GET_X_LPARAM(ol_pos), GET_Y_LPARAM(ol_pos));
       
   516                         QPoint pos = ax->mapFromGlobal(gpos);
       
   517 
       
   518                         QMouseEvent e(type, pos, gpos, (Qt::MouseButton)button,
       
   519                             translateMouseButtonState(msg->wParam),
       
   520                             translateModifierState(msg->wParam));
       
   521                         QApplication::sendEvent(ax, &e);
       
   522                     }
       
   523                 }
       
   524             }
       
   525         }
       
   526     }
       
   527 
       
   528     if (previous_filter)
       
   529         return previous_filter(m);
       
   530 
       
   531     return false;
       
   532 }
       
   533 
       
   534 QAxClientSite::QAxClientSite(QAxWidget *c)
       
   535 : eventTranslated(true), ref(1), widget(c), host(0)
       
   536 {
       
   537     aggregatedObject = widget->createAggregate();
       
   538     if (aggregatedObject) {
       
   539         aggregatedObject->controlling_unknown = (IUnknown*)(IDispatch*)this;
       
   540         aggregatedObject->the_object = c;
       
   541     }
       
   542 
       
   543     m_spOleObject = 0;
       
   544     m_spOleControl = 0;
       
   545     m_spInPlaceObject = 0;
       
   546     m_spInPlaceActiveObject = 0;
       
   547     m_spActiveView = 0;
       
   548 
       
   549     inPlaceObjectWindowless = false;
       
   550     inPlaceModelessEnabled = true;
       
   551     canHostDocument = false;
       
   552 
       
   553     m_dwOleObject = 0;
       
   554 #if !defined(Q_WS_WINCE)
       
   555     m_menuOwner = 0;
       
   556     menuBar = 0;
       
   557 #endif
       
   558     memset(&control_info, 0, sizeof(control_info));
       
   559 }
       
   560 
       
   561 bool QAxClientSite::activateObject(bool initialized, const QByteArray &data)
       
   562 {
       
   563     if (!host)
       
   564         host = new QAxHostWidget(widget, this);
       
   565 
       
   566     bool showHost = false;
       
   567     HRESULT hr = S_OK;
       
   568     if (!m_spOleObject)
       
   569         widget->queryInterface(IID_IOleObject, (void**)&m_spOleObject);
       
   570     if (m_spOleObject) {
       
   571         DWORD dwMiscStatus = 0;
       
   572         m_spOleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
       
   573 
       
   574 #if !defined(Q_OS_WINCE)
       
   575         IOleDocument *document = 0;
       
   576         m_spOleObject->QueryInterface(IID_IOleDocument, (void**)&document);
       
   577         if (document) {
       
   578             IPersistStorage *persistStorage = 0;
       
   579             document->QueryInterface(IID_IPersistStorage, (void**)&persistStorage);
       
   580             if (persistStorage) {
       
   581             // try to activate as document server
       
   582                 IStorage *storage = 0;
       
   583                 ILockBytes * bytes = 0;
       
   584                 HRESULT hres = ::CreateILockBytesOnHGlobal(0, TRUE, &bytes);
       
   585                 hres = ::StgCreateDocfileOnILockBytes(bytes, STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &storage);
       
   586 
       
   587                 persistStorage->InitNew(storage);
       
   588                 persistStorage->Release();
       
   589                 canHostDocument = true;
       
   590                 storage->Release();
       
   591                 bytes->Release();
       
   592 
       
   593                 m_spOleObject->SetClientSite(this);
       
   594                 OleRun(m_spOleObject);
       
   595             }
       
   596             document->Release();
       
   597         }
       
   598 #endif
       
   599 
       
   600         if (!canHostDocument) {
       
   601             // activate as control
       
   602             if(dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
       
   603                 m_spOleObject->SetClientSite(this);
       
   604 
       
   605             if (!initialized) {
       
   606                 IPersistStreamInit *spPSI = 0;
       
   607                 m_spOleObject->QueryInterface(IID_IPersistStreamInit, (void**)&spPSI);
       
   608                 if (spPSI) {
       
   609                     if (data.length()) {
       
   610                         IStream *pStream = 0;
       
   611                         HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, data.length());
       
   612                         if (hGlobal) {
       
   613                             BYTE *pStByte = (BYTE *)GlobalLock(hGlobal);
       
   614                             if (pStByte)
       
   615                                 memcpy(pStByte, data.data(), data.length());
       
   616                             GlobalUnlock(hGlobal);
       
   617                             if (SUCCEEDED(CreateStreamOnHGlobal(hGlobal, TRUE, &pStream))) {
       
   618                                 spPSI->Load(pStream);
       
   619                                 pStream->Release();
       
   620                             }
       
   621                             GlobalFree(hGlobal);
       
   622                         }
       
   623                     } else {
       
   624                         spPSI->InitNew();
       
   625                     }
       
   626                     spPSI->Release();
       
   627                 } else if (data.length()) { //try initializing using a IPersistStorage
       
   628                     IPersistStorage *spPS = 0;
       
   629                     m_spOleObject->QueryInterface( IID_IPersistStorage, (void**)&spPS );
       
   630                     if (spPS) {
       
   631                         HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, data.length());
       
   632                         if (hGlobal) {
       
   633 #if !defined(Q_OS_WINCE)
       
   634                             BYTE* pbData = (BYTE*)GlobalLock(hGlobal);
       
   635                             if (pbData)
       
   636                                 memcpy(pbData, data.data(), data.length());
       
   637                             GlobalUnlock(hGlobal);
       
   638                             // open an IStorage on the data and pass it to Load
       
   639                             LPLOCKBYTES pLockBytes = 0;
       
   640                             if (SUCCEEDED(CreateILockBytesOnHGlobal(hGlobal, TRUE, &pLockBytes))) {
       
   641                                 LPSTORAGE pStorage = 0;
       
   642                                 if (SUCCEEDED(StgOpenStorageOnILockBytes(pLockBytes, 0,
       
   643                                               STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStorage))) {
       
   644                                     spPS->Load(pStorage);
       
   645                                     pStorage->Release();
       
   646                                 }
       
   647                                 pLockBytes->Release();
       
   648                             }
       
   649                             GlobalFree(hGlobal);
       
   650 #endif
       
   651                         }
       
   652                         spPS->Release();
       
   653                     }
       
   654                 }
       
   655             }
       
   656 
       
   657             if(!(dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
       
   658                 m_spOleObject->SetClientSite(this);
       
   659         }
       
   660 
       
   661         IViewObject *spViewObject = 0;
       
   662         m_spOleObject->QueryInterface(IID_IViewObject, (void**) &spViewObject);
       
   663 
       
   664         m_spOleObject->Advise(this, &m_dwOleObject);
       
   665         IAdviseSink *spAdviseSink = 0;
       
   666         QueryInterface(IID_IAdviseSink, (void**)&spAdviseSink);
       
   667         if (spAdviseSink && spViewObject) {
       
   668             if (spViewObject)
       
   669                 spViewObject->SetAdvise(DVASPECT_CONTENT, 0, spAdviseSink);
       
   670             spAdviseSink->Release();
       
   671         }
       
   672         if (spViewObject)
       
   673             spViewObject->Release();
       
   674 
       
   675         m_spOleObject->SetHostNames(OLESTR("AXWIN"), 0);
       
   676 
       
   677         if (!(dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)) {
       
   678             SIZEL hmSize;
       
   679             hmSize.cx = MAP_PIX_TO_LOGHIM(250, widget->logicalDpiX());
       
   680             hmSize.cy = MAP_PIX_TO_LOGHIM(250, widget->logicalDpiY());
       
   681 
       
   682             m_spOleObject->SetExtent(DVASPECT_CONTENT, &hmSize);
       
   683             m_spOleObject->GetExtent(DVASPECT_CONTENT, &hmSize);
       
   684 
       
   685             sizehint.setWidth(MAP_LOGHIM_TO_PIX(hmSize.cx, widget->logicalDpiX()));
       
   686             sizehint.setHeight(MAP_LOGHIM_TO_PIX(hmSize.cy, widget->logicalDpiY()));
       
   687             showHost = true;
       
   688         } else {
       
   689             sizehint = QSize(0, 0);
       
   690             host->hide();
       
   691         }
       
   692         if (!(dwMiscStatus & OLEMISC_NOUIACTIVATE)) {
       
   693             host->setFocusPolicy(Qt::StrongFocus);
       
   694         } else {
       
   695             host->setFocusPolicy(Qt::NoFocus);
       
   696         }
       
   697 
       
   698         RECT rcPos = { host->x(), host->y(), host->x()+sizehint.width(), host->y()+sizehint.height() };
       
   699 
       
   700         hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, 0, (IOleClientSite*)this, 0, host->winId(), &rcPos);
       
   701 
       
   702         if (!m_spOleControl)
       
   703             m_spOleObject->QueryInterface(IID_IOleControl, (void**)&m_spOleControl);
       
   704         if (m_spOleControl) {
       
   705             m_spOleControl->OnAmbientPropertyChange(DISPID_AMBIENT_BACKCOLOR);
       
   706             m_spOleControl->OnAmbientPropertyChange(DISPID_AMBIENT_FORECOLOR);
       
   707             m_spOleControl->OnAmbientPropertyChange(DISPID_AMBIENT_FONT);
       
   708             m_spOleControl->OnAmbientPropertyChange(DISPID_AMBIENT_USERMODE);
       
   709 
       
   710             control_info.cb = sizeof(control_info);
       
   711             m_spOleControl->GetControlInfo(&control_info);
       
   712         }
       
   713 
       
   714         BSTR userType;
       
   715         HRESULT result = m_spOleObject->GetUserType(USERCLASSTYPE_SHORT, &userType);
       
   716         if (result == S_OK) {
       
   717             widget->setWindowTitle(QString::fromWCharArray(userType));
       
   718             CoTaskMemFree(userType);
       
   719         }
       
   720     } else {
       
   721         IObjectWithSite *spSite = 0;
       
   722         widget->queryInterface(IID_IObjectWithSite, (void**)&spSite);
       
   723         if (spSite) {
       
   724             spSite->SetSite((IUnknown*)(IDispatch*)this);
       
   725             spSite->Release();
       
   726         }
       
   727     }
       
   728 
       
   729     host->resize(widget->size());
       
   730     if (showHost)
       
   731         host->show();
       
   732 
       
   733     if (host->focusPolicy() != Qt::NoFocus) {
       
   734         widget->setFocusProxy(host);
       
   735         widget->setFocusPolicy(host->focusPolicy());
       
   736     }
       
   737 
       
   738     return true;
       
   739 }
       
   740 
       
   741 QAxClientSite::~QAxClientSite()
       
   742 {
       
   743     if (host) {
       
   744         host->axhost = 0;
       
   745     }
       
   746 
       
   747     if (aggregatedObject)
       
   748         aggregatedObject->the_object = 0;
       
   749     delete aggregatedObject;
       
   750     delete host;
       
   751 }
       
   752 
       
   753 void QAxClientSite::releaseAll()
       
   754 {
       
   755     if (m_spOleObject) {
       
   756         m_spOleObject->SetClientSite(0);
       
   757         m_spOleObject->Unadvise(m_dwOleObject);
       
   758         m_spOleObject->Release();
       
   759     }
       
   760     m_spOleObject = 0;
       
   761     if (m_spOleControl) m_spOleControl->Release();
       
   762     m_spOleControl = 0;
       
   763     if (m_spInPlaceObject) m_spInPlaceObject->Release();
       
   764     m_spInPlaceObject = 0;
       
   765     if (m_spInPlaceActiveObject) m_spInPlaceActiveObject->Release();
       
   766     m_spInPlaceActiveObject = 0;
       
   767 
       
   768     inPlaceObjectWindowless = false;
       
   769 }
       
   770 
       
   771 void QAxClientSite::deactivate()
       
   772 {
       
   773     if (m_spInPlaceObject) m_spInPlaceObject->InPlaceDeactivate();
       
   774     // if this assertion fails the control didn't call OnInPlaceDeactivate
       
   775     Q_ASSERT(m_spInPlaceObject == 0);
       
   776 }
       
   777 
       
   778 //**** IUnknown
       
   779 unsigned long WINAPI QAxClientSite::AddRef()
       
   780 {
       
   781     return ++ref;
       
   782 }
       
   783 
       
   784 unsigned long WINAPI QAxClientSite::Release()
       
   785 {
       
   786     if (!--ref) {
       
   787         delete this;
       
   788         return 0;
       
   789     }
       
   790     return ref;
       
   791 }
       
   792 
       
   793 HRESULT WINAPI QAxClientSite::QueryInterface(REFIID iid, void **iface)
       
   794 {
       
   795     *iface = 0;
       
   796 
       
   797     if (iid == IID_IUnknown) {
       
   798         *iface = (IUnknown*)(IDispatch*)this;
       
   799     } else {
       
   800         HRESULT res = S_OK;
       
   801         if (aggregatedObject)
       
   802             res = aggregatedObject->queryInterface(iid, iface);
       
   803         if (*iface)
       
   804             return res;
       
   805     }
       
   806 
       
   807     if (!(*iface)) {
       
   808         if (iid == IID_IDispatch)
       
   809             *iface = (IDispatch*)this;
       
   810         else if (iid == IID_IOleClientSite)
       
   811             *iface = (IOleClientSite*)this;
       
   812         else if (iid == IID_IOleControlSite)
       
   813             *iface = (IOleControlSite*)this;
       
   814         else if (iid == IID_IOleWindow)
       
   815             *iface = (IOleWindow*)(IOleInPlaceSite*)this;
       
   816         else if (iid == IID_IOleInPlaceSite)
       
   817             *iface = (IOleInPlaceSite*)this;
       
   818 #ifdef QAX_SUPPORT_WINDOWLESS
       
   819         else if (iid == IID_IOleInPlaceSiteEx)
       
   820             *iface = (IOleInPlaceSiteEx*)this;
       
   821         else if (iid == IID_IOleInPlaceSiteWindowless)
       
   822             *iface = (IOleInPlaceSiteWindowless*)this;
       
   823 #endif
       
   824         else if (iid == IID_IOleInPlaceFrame)
       
   825             *iface = (IOleInPlaceFrame*)this;
       
   826         else if (iid == IID_IOleInPlaceUIWindow)
       
   827             *iface = (IOleInPlaceUIWindow*)this;
       
   828         else if (iid == IID_IOleDocumentSite && canHostDocument)
       
   829             *iface = (IOleDocumentSite*)this;
       
   830         else if (iid == IID_IAdviseSink)
       
   831             *iface = (IAdviseSink*)this;
       
   832     }
       
   833     if (!*iface)
       
   834         return E_NOINTERFACE;
       
   835 
       
   836     AddRef();
       
   837     return S_OK;
       
   838 }
       
   839 
       
   840 bool qax_runsInDesignMode = false;
       
   841 
       
   842 //**** IDispatch
       
   843 HRESULT WINAPI QAxClientSite::Invoke(DISPID dispIdMember,
       
   844                                      REFIID /*riid*/,
       
   845                                      LCID /*lcid*/,
       
   846                                      WORD /*wFlags*/,
       
   847                                      DISPPARAMS * /*pDispParams*/,
       
   848                                      VARIANT *pVarResult,
       
   849                                      EXCEPINFO * /*pExcepInfo*/,
       
   850                                      UINT * /*puArgErr*/)
       
   851 {
       
   852     if (!pVarResult)
       
   853         return E_POINTER;
       
   854     if (!widget || !host)
       
   855         return E_UNEXPECTED;
       
   856 
       
   857     switch(dispIdMember) {
       
   858     case DISPID_AMBIENT_USERMODE:
       
   859         pVarResult->vt = VT_BOOL;
       
   860         pVarResult->boolVal = !qax_runsInDesignMode;
       
   861         return S_OK;
       
   862 
       
   863     case DISPID_AMBIENT_AUTOCLIP:
       
   864     case DISPID_AMBIENT_SUPPORTSMNEMONICS:
       
   865         pVarResult->vt = VT_BOOL;
       
   866         pVarResult->boolVal = true;
       
   867         return S_OK;
       
   868 
       
   869     case DISPID_AMBIENT_SHOWHATCHING:
       
   870     case DISPID_AMBIENT_SHOWGRABHANDLES:
       
   871     case DISPID_AMBIENT_DISPLAYASDEFAULT:
       
   872     case DISPID_AMBIENT_MESSAGEREFLECT:
       
   873         pVarResult->vt = VT_BOOL;
       
   874         pVarResult->boolVal = false;
       
   875         return S_OK;
       
   876 
       
   877     case DISPID_AMBIENT_DISPLAYNAME:
       
   878         pVarResult->vt = VT_BSTR;
       
   879         pVarResult->bstrVal = QStringToBSTR(widget->windowTitle());
       
   880         return S_OK;
       
   881 
       
   882     case DISPID_AMBIENT_FONT:
       
   883         QVariantToVARIANT(widget->font(), *pVarResult);
       
   884         return S_OK;
       
   885 
       
   886     case DISPID_AMBIENT_BACKCOLOR:
       
   887         pVarResult->vt = VT_UI4;
       
   888         pVarResult->lVal = QColorToOLEColor(widget->palette().color(widget->backgroundRole()));
       
   889         return S_OK;
       
   890 
       
   891     case DISPID_AMBIENT_FORECOLOR:
       
   892         pVarResult->vt = VT_UI4;
       
   893         pVarResult->lVal = QColorToOLEColor(widget->palette().color(widget->foregroundRole()));
       
   894         return S_OK;
       
   895 
       
   896     case DISPID_AMBIENT_UIDEAD:
       
   897         pVarResult->vt = VT_BOOL;
       
   898         pVarResult->boolVal = !widget->isEnabled();
       
   899         return S_OK;
       
   900 
       
   901     default:
       
   902         break;
       
   903     }
       
   904 
       
   905     return DISP_E_MEMBERNOTFOUND;
       
   906 }
       
   907 
       
   908 void QAxClientSite::emitAmbientPropertyChange(DISPID dispid)
       
   909 {
       
   910     if (m_spOleControl)
       
   911         m_spOleControl->OnAmbientPropertyChange(dispid);
       
   912 }
       
   913 
       
   914 //**** IOleClientSite
       
   915 HRESULT WINAPI QAxClientSite::SaveObject()
       
   916 {
       
   917     return E_NOTIMPL;
       
   918 }
       
   919 
       
   920 HRESULT WINAPI QAxClientSite::GetMoniker(DWORD, DWORD, IMoniker **ppmk)
       
   921 {
       
   922     if (!ppmk)
       
   923         return E_POINTER;
       
   924 
       
   925     *ppmk = 0;
       
   926     return E_NOTIMPL;
       
   927 }
       
   928 
       
   929 HRESULT WINAPI QAxClientSite::GetContainer(LPOLECONTAINER *ppContainer)
       
   930 {
       
   931     if (!ppContainer)
       
   932         return E_POINTER;
       
   933 
       
   934     *ppContainer = 0;
       
   935     return E_NOINTERFACE;
       
   936 }
       
   937 
       
   938 HRESULT WINAPI QAxClientSite::ShowObject()
       
   939 {
       
   940     return S_OK;
       
   941 }
       
   942 
       
   943 HRESULT WINAPI QAxClientSite::OnShowWindow(BOOL /*fShow*/)
       
   944 {
       
   945     return S_OK;
       
   946 }
       
   947 
       
   948 HRESULT WINAPI QAxClientSite::RequestNewObjectLayout()
       
   949 {
       
   950     return E_NOTIMPL;
       
   951 }
       
   952 
       
   953 //**** IOleControlSite
       
   954 HRESULT WINAPI QAxClientSite::OnControlInfoChanged()
       
   955 {
       
   956     if (m_spOleControl)
       
   957         m_spOleControl->GetControlInfo(&control_info);
       
   958 
       
   959     return S_OK;
       
   960 }
       
   961 
       
   962 HRESULT WINAPI QAxClientSite::LockInPlaceActive(BOOL /*fLock*/)
       
   963 {
       
   964     AX_DEBUG(QAxClientSite::LockInPlaceActive);
       
   965     return S_OK;
       
   966 }
       
   967 
       
   968 HRESULT WINAPI QAxClientSite::GetExtendedControl(IDispatch** ppDisp)
       
   969 {
       
   970     if (!ppDisp)
       
   971         return E_POINTER;
       
   972 
       
   973     *ppDisp = 0;
       
   974     return E_NOTIMPL;
       
   975 }
       
   976 
       
   977 HRESULT WINAPI QAxClientSite::TransformCoords(POINTL* /*pPtlHimetric*/, POINTF* /*pPtfContainer*/, DWORD /*dwFlags*/)
       
   978 {
       
   979     return S_OK;
       
   980 }
       
   981 
       
   982 HRESULT WINAPI QAxClientSite::TranslateAccelerator(LPMSG lpMsg, DWORD /*grfModifiers*/)
       
   983 {
       
   984     if (lpMsg->message == WM_KEYDOWN && !lpMsg->wParam)
       
   985         return S_OK;
       
   986 
       
   987     bool ActiveQtDetected = false;
       
   988     bool fromInProcServer = false;
       
   989 #ifdef GWLP_USERDATA
       
   990     LONG_PTR serverType = GetWindowLongPtr(lpMsg->hwnd, GWLP_USERDATA);
       
   991 #else
       
   992     LONG serverType = GetWindowLong(lpMsg->hwnd, GWL_USERDATA);
       
   993 #endif
       
   994     if (serverType == QAX_INPROC_SERVER) {
       
   995         ActiveQtDetected = true;
       
   996         fromInProcServer = true;
       
   997     } else if (serverType == QAX_OUTPROC_SERVER) {
       
   998         ActiveQtDetected = true;
       
   999         fromInProcServer = false;
       
  1000     }
       
  1001 
       
  1002     eventTranslated = false;
       
  1003     if (!ActiveQtDetected || !fromInProcServer) {
       
  1004         // if the request is coming from an out-of-proc server or a non ActiveQt server,
       
  1005         // we send the message to the host window. This will make sure this key event
       
  1006         // comes to Qt for processing.
       
  1007         SendMessage(host->winId(), lpMsg->message, lpMsg->wParam, lpMsg->lParam);
       
  1008         if (ActiveQtDetected && !fromInProcServer) {
       
  1009             // ActiveQt based servers will need further processing of the event
       
  1010             // (eg. <SPACE> key for a checkbox), so we return false.
       
  1011             return S_FALSE;
       
  1012         }
       
  1013     }
       
  1014     // ActiveQt based in-processes-servers will handle the event properly, so
       
  1015     // we dont need to send this key event to the host.
       
  1016     return S_OK;
       
  1017 }
       
  1018 
       
  1019 HRESULT WINAPI QAxClientSite::OnFocus(BOOL bGotFocus)
       
  1020 {
       
  1021     AX_DEBUG(QAxClientSite::OnFocus);
       
  1022     if (host) {
       
  1023         host->hasFocus = bGotFocus;
       
  1024         qApp->removeEventFilter(host);
       
  1025         if (bGotFocus)
       
  1026             qApp->installEventFilter(host);
       
  1027     }
       
  1028     return S_OK;
       
  1029 }
       
  1030 
       
  1031 HRESULT WINAPI QAxClientSite::ShowPropertyFrame()
       
  1032 {
       
  1033     return E_NOTIMPL;
       
  1034 }
       
  1035 
       
  1036 //**** IOleWindow
       
  1037 HRESULT WINAPI QAxClientSite::GetWindow(HWND *phwnd)
       
  1038 {
       
  1039     if (!phwnd)
       
  1040         return E_POINTER;
       
  1041 
       
  1042     *phwnd = host->winId();
       
  1043     return S_OK;
       
  1044 }
       
  1045 
       
  1046 HRESULT WINAPI QAxClientSite::ContextSensitiveHelp(BOOL fEnterMode)
       
  1047 {
       
  1048     if (fEnterMode)
       
  1049         QWhatsThis::enterWhatsThisMode();
       
  1050     else
       
  1051         QWhatsThis::leaveWhatsThisMode();
       
  1052 
       
  1053     return S_OK;
       
  1054 }
       
  1055 
       
  1056 //**** IOleInPlaceSite
       
  1057 HRESULT WINAPI QAxClientSite::CanInPlaceActivate()
       
  1058 {
       
  1059     AX_DEBUG(QAxClientSite::CanInPlaceActivate);
       
  1060     return S_OK;
       
  1061 }
       
  1062 
       
  1063 HRESULT WINAPI QAxClientSite::OnInPlaceActivate()
       
  1064 {
       
  1065     AX_DEBUG(QAxClientSite::OnInPlaceActivate);
       
  1066 #if !defined(Q_OS_WINCE)
       
  1067     OleLockRunning(m_spOleObject, true, false);
       
  1068 #endif
       
  1069     if (!m_spInPlaceObject) {
       
  1070 /* ### disabled for now
       
  1071         m_spOleObject->QueryInterface(IID_IOleInPlaceObjectWindowless, (void**) &m_spInPlaceObject);
       
  1072 */
       
  1073         if (m_spInPlaceObject) {
       
  1074             inPlaceObjectWindowless = true;
       
  1075         } else {
       
  1076             inPlaceObjectWindowless = false;
       
  1077             m_spOleObject->QueryInterface(IID_IOleInPlaceObject, (void**) &m_spInPlaceObject);
       
  1078         }
       
  1079     }
       
  1080 
       
  1081     return S_OK;
       
  1082 }
       
  1083 
       
  1084 HRESULT WINAPI QAxClientSite::OnUIActivate()
       
  1085 {
       
  1086     AX_DEBUG(QAxClientSite::OnUIActivate);
       
  1087     return S_OK;
       
  1088 }
       
  1089 
       
  1090 HRESULT WINAPI QAxClientSite::GetWindowContext(IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
       
  1091 {
       
  1092     if (!ppFrame || !ppDoc || !lprcPosRect || !lprcClipRect || !lpFrameInfo)
       
  1093         return E_POINTER;
       
  1094 
       
  1095     QueryInterface(IID_IOleInPlaceFrame, (void**)ppFrame);
       
  1096     QueryInterface(IID_IOleInPlaceUIWindow, (void**)ppDoc);
       
  1097 
       
  1098     ::GetClientRect(host->winId(), lprcPosRect);
       
  1099     ::GetClientRect(host->winId(), lprcClipRect);
       
  1100 
       
  1101     lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
       
  1102     lpFrameInfo->fMDIApp = false;
       
  1103     lpFrameInfo->haccel = 0;
       
  1104     lpFrameInfo->cAccelEntries = 0;
       
  1105     lpFrameInfo->hwndFrame = widget ? widget->window()->winId() : 0;
       
  1106 
       
  1107     return S_OK;
       
  1108 }
       
  1109 
       
  1110 HRESULT WINAPI QAxClientSite::Scroll(SIZE /*scrollExtant*/)
       
  1111 {
       
  1112     return S_FALSE;
       
  1113 }
       
  1114 
       
  1115 HRESULT WINAPI QAxClientSite::OnUIDeactivate(BOOL)
       
  1116 {
       
  1117     AX_DEBUG(QAxClientSite::OnUIDeactivate);
       
  1118     if (host && host->hasFocus) {
       
  1119         qApp->removeEventFilter(host);
       
  1120         host->hasFocus = false;
       
  1121     }
       
  1122     return S_OK;
       
  1123 }
       
  1124 
       
  1125 HRESULT WINAPI QAxClientSite::OnInPlaceDeactivate()
       
  1126 {
       
  1127     AX_DEBUG(QAxClientSite::OnInPlaceDeactivate);
       
  1128     if (m_spInPlaceObject)
       
  1129         m_spInPlaceObject->Release();
       
  1130     m_spInPlaceObject = 0;
       
  1131     inPlaceObjectWindowless = false;
       
  1132 #if !defined(Q_OS_WINCE)
       
  1133     OleLockRunning(m_spOleObject, false, false);
       
  1134 #endif
       
  1135 
       
  1136     return S_OK;
       
  1137 }
       
  1138 
       
  1139 HRESULT WINAPI QAxClientSite::DiscardUndoState()
       
  1140 {
       
  1141     return S_OK;
       
  1142 }
       
  1143 
       
  1144 HRESULT WINAPI QAxClientSite::DeactivateAndUndo()
       
  1145 {
       
  1146     if (m_spInPlaceObject)
       
  1147         m_spInPlaceObject->UIDeactivate();
       
  1148 
       
  1149     return S_OK;
       
  1150 }
       
  1151 
       
  1152 HRESULT WINAPI QAxClientSite::OnPosRectChange(LPCRECT /*lprcPosRect*/)
       
  1153 {
       
  1154     AX_DEBUG(QAxClientSite::OnPosRectChange);
       
  1155     // ###
       
  1156     return S_OK;
       
  1157 }
       
  1158 
       
  1159 //**** IOleInPlaceFrame
       
  1160 #if defined(Q_WS_WINCE)
       
  1161 HRESULT WINAPI QAxClientSite::InsertMenus(HMENU /*hmenuShared*/, LPOLEMENUGROUPWIDTHS /*lpMenuWidths*/)
       
  1162 {
       
  1163     return E_NOTIMPL;
       
  1164 #else
       
  1165 HRESULT WINAPI QAxClientSite::InsertMenus(HMENU /*hmenuShared*/, LPOLEMENUGROUPWIDTHS lpMenuWidths)
       
  1166 {
       
  1167     AX_DEBUG(QAxClientSite::InsertMenus);
       
  1168     QMenuBar *mb = menuBar;
       
  1169     if (!mb)
       
  1170         mb = qFindChild<QMenuBar*>(widget->window());
       
  1171     if (!mb)
       
  1172         return E_NOTIMPL;
       
  1173     menuBar = mb;
       
  1174 
       
  1175     QMenu *fileMenu = 0;
       
  1176     QMenu *viewMenu = 0;
       
  1177     QMenu *windowMenu = 0;
       
  1178     QList<QAction*> actions = menuBar->actions();
       
  1179     for (int i = 0; i < actions.count(); ++i) {
       
  1180         QAction *action = actions.at(i);
       
  1181         QString text = action->text().remove(QLatin1Char('&'));
       
  1182         if (text == QLatin1String("File")) {
       
  1183             fileMenu = action->menu();
       
  1184         } else if (text == QLatin1String("View")) {
       
  1185             viewMenu = action->menu();
       
  1186         } else if (text == QLatin1String("Window")) {
       
  1187             windowMenu = action->menu();
       
  1188         }
       
  1189     }
       
  1190     if (fileMenu)
       
  1191         lpMenuWidths->width[0] = fileMenu->actions().count();
       
  1192     if (viewMenu)
       
  1193         lpMenuWidths->width[2] = viewMenu->actions().count();
       
  1194     if (windowMenu)
       
  1195         lpMenuWidths->width[4] = windowMenu->actions().count();
       
  1196 
       
  1197     return S_OK;
       
  1198 #endif
       
  1199 }
       
  1200 
       
  1201 static int menuItemEntry(HMENU menu, int index, MENUITEMINFO item, QString &text, QPixmap &/*icon*/)
       
  1202 {
       
  1203     if (item.fType == MFT_STRING && item.cch) {
       
  1204         wchar_t *titlebuf = new wchar_t[item.cch + 1];
       
  1205         item.dwTypeData = titlebuf;
       
  1206         item.cch++;
       
  1207         ::GetMenuItemInfo(menu, index, true, &item);
       
  1208         text = QString::fromWCharArray(titlebuf);
       
  1209         delete [] titlebuf;
       
  1210         return MFT_STRING;
       
  1211     }
       
  1212 #if 0
       
  1213     else if (item.fType == MFT_BITMAP) {
       
  1214         HBITMAP hbm = (HBITMAP)LOWORD(item.hbmpItem);
       
  1215         SIZE bmsize;
       
  1216         GetBitmapDimensionEx(hbm, &bmsize);
       
  1217         QPixmap pixmap(1,1);
       
  1218         QSize sz(MAP_LOGHIM_TO_PIX(bmsize.cx, pixmap.logicalDpiX()),
       
  1219                  MAP_LOGHIM_TO_PIX(bmsize.cy, pixmap.logicalDpiY()));
       
  1220 
       
  1221         pixmap.resize(bmsize.cx, bmsize.cy);
       
  1222         if (!pixmap.isNull()) {
       
  1223             HDC hdc = ::CreateCompatibleDC(pixmap.handle());
       
  1224             ::SelectObject(hdc, hbm);
       
  1225             BOOL res = ::BitBlt(pixmap.handle(), 0, 0, pixmap.width(), pixmap.height(), hdc, 0, 0, SRCCOPY);
       
  1226             ::DeleteObject(hdc);
       
  1227         }
       
  1228 
       
  1229         icon = pixmap;
       
  1230     }
       
  1231 #endif
       
  1232     return -1;
       
  1233 }
       
  1234 
       
  1235 #if !defined(Q_OS_WINCE)
       
  1236 QMenu *QAxClientSite::generatePopup(HMENU subMenu, QWidget *parent)
       
  1237 {
       
  1238     QMenu *popup = 0;
       
  1239     int count = GetMenuItemCount(subMenu);
       
  1240     if (count)
       
  1241         popup = new QMenu(parent);
       
  1242     for (int i = 0; i < count; ++i) {
       
  1243         MENUITEMINFO item;
       
  1244         memset(&item, 0, sizeof(MENUITEMINFO));
       
  1245         item.cbSize = sizeof(MENUITEMINFO);
       
  1246         item.fMask = MIIM_ID | MIIM_TYPE | MIIM_SUBMENU;
       
  1247         ::GetMenuItemInfo(subMenu, i, true, &item);
       
  1248 
       
  1249         QAction *action = 0;
       
  1250         QMenu *popupMenu = 0;
       
  1251         if (item.fType == MFT_SEPARATOR) {
       
  1252             action = popup->addSeparator();
       
  1253         } else {
       
  1254             QString text;
       
  1255             QPixmap icon;
       
  1256             QKeySequence accel;
       
  1257             popupMenu = item.hSubMenu ? generatePopup(item.hSubMenu, popup) : 0;
       
  1258             int res = menuItemEntry(subMenu, i, item, text, icon);
       
  1259 
       
  1260             int lastSep = text.lastIndexOf(QRegExp(QLatin1String("[\\s]")));
       
  1261             if (lastSep != -1) {
       
  1262                 QString keyString = text.right(text.length() - lastSep);
       
  1263                 accel = keyString;
       
  1264                 if ((int)accel)
       
  1265                     text = text.left(lastSep);
       
  1266             }
       
  1267 
       
  1268             if (popupMenu)
       
  1269                 popupMenu->setTitle(text);
       
  1270 
       
  1271             switch (res) {
       
  1272             case MFT_STRING:
       
  1273                 if (popupMenu)
       
  1274                     action = popup->addMenu(popupMenu);
       
  1275                 else
       
  1276                     action = popup->addAction(text);
       
  1277                 break;
       
  1278             case MFT_BITMAP:
       
  1279                 if (popupMenu)
       
  1280                     action = popup->addMenu(popupMenu);
       
  1281                 else
       
  1282                     action = popup->addAction(icon, text);
       
  1283                 break;
       
  1284             }
       
  1285 
       
  1286             if (action) {
       
  1287                 if (int(accel))
       
  1288                     action->setShortcut(accel);
       
  1289                 if (!icon.isNull())
       
  1290                     action->setIcon(icon);
       
  1291             }
       
  1292         }
       
  1293 
       
  1294         if (action) {
       
  1295             OleMenuItem oleItem(subMenu, item.wID, popupMenu);
       
  1296             menuItemMap.insert(action, oleItem);
       
  1297         }
       
  1298     }
       
  1299     return popup;
       
  1300 }
       
  1301 #endif
       
  1302 
       
  1303 #if defined(Q_OS_WINCE)
       
  1304 HRESULT WINAPI QAxClientSite::SetMenu(HMENU /*hmenuShared*/, HOLEMENU /*holemenu*/, HWND /*hwndActiveObject*/)
       
  1305 {
       
  1306     return E_NOTIMPL;
       
  1307 #else
       
  1308 HRESULT WINAPI QAxClientSite::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
       
  1309 {
       
  1310     AX_DEBUG(QAxClientSite::SetMenu);
       
  1311 
       
  1312     if (hmenuShared) {
       
  1313         m_menuOwner = hwndActiveObject;
       
  1314         QMenuBar *mb = menuBar;
       
  1315         if (!mb)
       
  1316             mb = qFindChild<QMenuBar*>(widget->window());
       
  1317         if (!mb)
       
  1318             return E_NOTIMPL;
       
  1319         menuBar = mb;
       
  1320 
       
  1321         int count = GetMenuItemCount(hmenuShared);
       
  1322         for (int i = 0; i < count; ++i) {
       
  1323             MENUITEMINFO item;
       
  1324             memset(&item, 0, sizeof(MENUITEMINFO));
       
  1325             item.cbSize = sizeof(MENUITEMINFO);
       
  1326             item.fMask = MIIM_ID | MIIM_TYPE | MIIM_SUBMENU;
       
  1327             ::GetMenuItemInfo(hmenuShared, i, true, &item);
       
  1328 
       
  1329             QAction *action = 0;
       
  1330             QMenu *popupMenu = 0;
       
  1331             if (item.fType == MFT_SEPARATOR) {
       
  1332                 action = menuBar->addSeparator();
       
  1333             } else {
       
  1334                 QString text;
       
  1335                 QPixmap icon;
       
  1336                 popupMenu = item.hSubMenu ? generatePopup(item.hSubMenu, menuBar) : 0;
       
  1337                 int res = menuItemEntry(hmenuShared, i, item, text, icon);
       
  1338 
       
  1339                 if (popupMenu)
       
  1340                     popupMenu->setTitle(text);
       
  1341 
       
  1342                 switch(res) {
       
  1343                 case MFT_STRING:
       
  1344                     if (popupMenu)
       
  1345                         action = menuBar->addMenu(popupMenu);
       
  1346                     else
       
  1347                         action = menuBar->addAction(text);
       
  1348                     break;
       
  1349                 case MFT_BITMAP:
       
  1350                     if (popupMenu)
       
  1351                         action = menuBar->addMenu(popupMenu);
       
  1352                     else
       
  1353                         action = menuBar->addAction(text);
       
  1354                     break;
       
  1355                 default:
       
  1356                     break;
       
  1357                 }
       
  1358                 if (action && !icon.isNull())
       
  1359                     action->setIcon(icon);
       
  1360             }
       
  1361 
       
  1362             if (action) {
       
  1363                 OleMenuItem oleItem(hmenuShared, item.wID, popupMenu);
       
  1364                 menuItemMap.insert(action, oleItem);
       
  1365             }
       
  1366         }
       
  1367         if (count) {
       
  1368             const QMetaObject *mbmo = menuBar->metaObject();
       
  1369             int index = mbmo->indexOfSignal("triggered(QAction*)");
       
  1370             Q_ASSERT(index != -1);
       
  1371             menuBar->disconnect(SIGNAL(triggered(QAction*)), host);
       
  1372             QMetaObject::connect(menuBar, index, host, index);
       
  1373         }
       
  1374     } else if (menuBar) {
       
  1375         m_menuOwner = 0;
       
  1376         QMap<QAction*, OleMenuItem>::Iterator it;
       
  1377         for (it = menuItemMap.begin(); it != menuItemMap.end(); ++it) {
       
  1378             QAction *action = it.key();
       
  1379             delete action;
       
  1380         }
       
  1381         menuItemMap.clear();
       
  1382     }
       
  1383 
       
  1384     OleSetMenuDescriptor(holemenu, widget ? widget->window()->winId() : 0, m_menuOwner, this, m_spInPlaceActiveObject);
       
  1385     return S_OK;
       
  1386 #endif
       
  1387 }
       
  1388 
       
  1389 #if defined(Q_OS_WINCE)
       
  1390 int QAxClientSite::qt_metacall(QMetaObject::Call /*call*/, int isignal, void ** /*argv*/)
       
  1391 {
       
  1392     return isignal;
       
  1393 #else
       
  1394 int QAxClientSite::qt_metacall(QMetaObject::Call call, int isignal, void **argv)
       
  1395 {
       
  1396     if (!m_spOleObject || call != QMetaObject::InvokeMetaMethod || !menuBar)
       
  1397         return isignal;
       
  1398 
       
  1399     if (isignal != menuBar->metaObject()->indexOfSignal("triggered(QAction*)"))
       
  1400         return isignal;
       
  1401 
       
  1402     QAction *action = *(QAction**)argv[1];
       
  1403     // ###
       
  1404 
       
  1405     OleMenuItem oleItem = menuItemMap.value(action);
       
  1406     if (oleItem.hMenu)
       
  1407         ::PostMessage(m_menuOwner, WM_COMMAND, oleItem.id, 0);
       
  1408     return -1;
       
  1409 #endif
       
  1410 }
       
  1411 
       
  1412 
       
  1413 HRESULT WINAPI QAxClientSite::RemoveMenus(HMENU /*hmenuShared*/)
       
  1414 {
       
  1415 #if defined(Q_OS_WINCE)
       
  1416     return E_NOTIMPL;
       
  1417 #else
       
  1418     AX_DEBUG(QAxClientSite::RemoveMenus);
       
  1419     QMap<QAction*, OleMenuItem>::Iterator it;
       
  1420     for (it = menuItemMap.begin(); it != menuItemMap.end(); ++it) {
       
  1421         QAction *action = it.key();
       
  1422         action->setVisible(false);
       
  1423         delete action;
       
  1424     }
       
  1425     menuItemMap.clear();
       
  1426     return S_OK;
       
  1427 #endif
       
  1428 }
       
  1429 
       
  1430 HRESULT WINAPI QAxClientSite::SetStatusText(LPCOLESTR pszStatusText)
       
  1431 {
       
  1432     QStatusTipEvent tip(QString::fromWCharArray(pszStatusText));
       
  1433     QApplication::sendEvent(widget, &tip);
       
  1434     return S_OK;
       
  1435 }
       
  1436 
       
  1437 extern Q_GUI_EXPORT bool qt_win_ignoreNextMouseReleaseEvent;
       
  1438 
       
  1439 HRESULT WINAPI QAxClientSite::EnableModeless(BOOL fEnable)
       
  1440 {
       
  1441 #if !defined(Q_OS_WINCE)
       
  1442     LockWindowUpdate(host->window()->winId());
       
  1443 #endif
       
  1444     EnableWindow(host->window()->winId(), fEnable);
       
  1445 
       
  1446     if (!fEnable) {
       
  1447         if (!QApplicationPrivate::isBlockedByModal(host))
       
  1448             QApplicationPrivate::enterModal(host);
       
  1449     } else {
       
  1450         if (QApplicationPrivate::isBlockedByModal(host))
       
  1451             QApplicationPrivate::leaveModal(host);
       
  1452     }
       
  1453     qt_win_ignoreNextMouseReleaseEvent = false;
       
  1454 #if !defined(Q_OS_WINCE)
       
  1455     LockWindowUpdate(0);
       
  1456 #endif
       
  1457     return S_OK;
       
  1458 }
       
  1459 
       
  1460 HRESULT WINAPI QAxClientSite::TranslateAccelerator(LPMSG lpMsg, WORD grfModifiers)
       
  1461 {
       
  1462     return TranslateAccelerator(lpMsg, (DWORD)grfModifiers);
       
  1463 }
       
  1464 
       
  1465 //**** IOleInPlaceUIWindow
       
  1466 HRESULT WINAPI QAxClientSite::GetBorder(LPRECT lprectBorder)
       
  1467 {
       
  1468 #ifndef QAX_SUPPORT_BORDERSPACE
       
  1469     Q_UNUSED(lprectBorder);
       
  1470     return INPLACE_E_NOTOOLSPACE;
       
  1471 #else
       
  1472     AX_DEBUG(QAxClientSite::GetBorder);
       
  1473 
       
  1474     QMainWindow *mw = qobject_cast<QMainWindow*>(widget->window());
       
  1475     if (!mw)
       
  1476         return INPLACE_E_NOTOOLSPACE;
       
  1477 
       
  1478     RECT border = { 0,0, 300, 200 };
       
  1479     *lprectBorder = border;
       
  1480     return S_OK;
       
  1481 #endif
       
  1482 }
       
  1483 
       
  1484 HRESULT WINAPI QAxClientSite::RequestBorderSpace(LPCBORDERWIDTHS /*pborderwidths*/)
       
  1485 {
       
  1486 #ifndef QAX_SUPPORT_BORDERSPACE
       
  1487     return INPLACE_E_NOTOOLSPACE;
       
  1488 #else
       
  1489     AX_DEBUG(QAxClientSite::RequestBorderSpace);
       
  1490 
       
  1491     QMainWindow *mw = qobject_cast<QMainWindow*>(widget->window());
       
  1492     if (!mw)
       
  1493         return INPLACE_E_NOTOOLSPACE;
       
  1494 
       
  1495     return S_OK;
       
  1496 #endif
       
  1497 }
       
  1498 
       
  1499 HRESULT WINAPI QAxClientSite::SetBorderSpace(LPCBORDERWIDTHS pborderwidths)
       
  1500 {
       
  1501 #ifndef QAX_SUPPORT_BORDERSPACE
       
  1502     Q_UNUSED(pborderwidths);
       
  1503     return OLE_E_INVALIDRECT;
       
  1504 #else
       
  1505     AX_DEBUG(QAxClientSite::SetBorderSpace);
       
  1506 
       
  1507     // object has no toolbars and wants container toolbars to remain
       
  1508     if (!pborderwidths)
       
  1509         return S_OK;
       
  1510 
       
  1511     QMainWindow *mw = qobject_cast<QMainWindow*>(widget->window());
       
  1512     if (!mw)
       
  1513         return OLE_E_INVALIDRECT;
       
  1514 
       
  1515     bool removeToolBars = !(pborderwidths->left || pborderwidths->top || pborderwidths->right || pborderwidths->bottom);
       
  1516 
       
  1517     // object has toolbars, and wants container to remove toolbars
       
  1518     if (removeToolBars) {
       
  1519         if (mw) {
       
  1520             //### remove our toolbars
       
  1521         }
       
  1522     }
       
  1523 
       
  1524     if (pborderwidths->left) {
       
  1525         QDockWidget *left = new QDockWidget(mw);
       
  1526         left->setFixedWidth(pborderwidths->left);
       
  1527         mw->addDockWidget(Qt::LeftDockWidgetArea, left);
       
  1528         left->show();
       
  1529     }
       
  1530     if (pborderwidths->top) {
       
  1531         QDockWidget *top = new QDockWidget(mw);
       
  1532         top->setFixedHeight(pborderwidths->top);
       
  1533         mw->addDockWidget(Qt::TopDockWidgetArea, top);
       
  1534         top->show();
       
  1535     }
       
  1536 
       
  1537     return S_OK;
       
  1538 #endif
       
  1539 }
       
  1540 
       
  1541 HRESULT WINAPI QAxClientSite::SetActiveObject(IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
       
  1542 {
       
  1543     AX_DEBUG(QAxClientSite::SetActiveObject);
       
  1544     
       
  1545     Q_UNUSED(pszObjName);
       
  1546     // we are ignoring the name of the object, as suggested by MSDN documentation 
       
  1547     // for IOleInPlaceUIWindow::SetActiveObject().
       
  1548 
       
  1549     if (m_spInPlaceActiveObject) {
       
  1550         if (!inPlaceModelessEnabled)
       
  1551             m_spInPlaceActiveObject->EnableModeless(true);
       
  1552         inPlaceModelessEnabled = true;
       
  1553         m_spInPlaceActiveObject->Release();
       
  1554     }
       
  1555 
       
  1556     m_spInPlaceActiveObject = pActiveObject;
       
  1557     if (m_spInPlaceActiveObject)
       
  1558         m_spInPlaceActiveObject->AddRef();
       
  1559 
       
  1560     return S_OK;
       
  1561 }
       
  1562 
       
  1563 //**** IOleDocumentSite
       
  1564 HRESULT WINAPI QAxClientSite::ActivateMe(IOleDocumentView *pViewToActivate)
       
  1565 {
       
  1566     AX_DEBUG(QAxClientSite::ActivateMe);
       
  1567 
       
  1568     if (m_spActiveView)
       
  1569         m_spActiveView->Release();
       
  1570     m_spActiveView = 0;
       
  1571 
       
  1572     if (!pViewToActivate) {
       
  1573         IOleDocument *document = 0;
       
  1574         m_spOleObject->QueryInterface(IID_IOleDocument, (void**)&document);
       
  1575         if (!document)
       
  1576             return E_FAIL;
       
  1577 
       
  1578         document->CreateView(this, 0, 0, &pViewToActivate);
       
  1579 
       
  1580         document->Release();
       
  1581         if (!pViewToActivate)
       
  1582             return E_OUTOFMEMORY;
       
  1583     } else {
       
  1584         pViewToActivate->SetInPlaceSite(this);
       
  1585     }
       
  1586 
       
  1587     m_spActiveView = pViewToActivate;
       
  1588     m_spActiveView->AddRef();
       
  1589 
       
  1590     m_spActiveView->UIActivate(TRUE);
       
  1591 
       
  1592     RECT rect;
       
  1593     GetClientRect(widget->winId(), &rect);
       
  1594     m_spActiveView->SetRect(&rect);
       
  1595     m_spActiveView->Show(TRUE);
       
  1596 
       
  1597     return S_OK;
       
  1598 }
       
  1599 
       
  1600 QSize QAxClientSite::minimumSizeHint() const
       
  1601 {
       
  1602     if (!m_spOleObject)
       
  1603         return QSize();
       
  1604 
       
  1605     SIZE sz = { 0, 0 };
       
  1606     m_spOleObject->SetExtent(DVASPECT_CONTENT, &sz);
       
  1607     HRESULT res = m_spOleObject->GetExtent(DVASPECT_CONTENT, &sz);
       
  1608     if (SUCCEEDED(res)) {
       
  1609         return QSize(MAP_LOGHIM_TO_PIX(sz.cx, widget->logicalDpiX()),
       
  1610             MAP_LOGHIM_TO_PIX(sz.cy, widget->logicalDpiY()));
       
  1611     }
       
  1612     return QSize();
       
  1613 }
       
  1614 
       
  1615 void QAxClientSite::windowActivationChange()
       
  1616 {
       
  1617     AX_DEBUG(QAxClientSite::windowActivationChange);
       
  1618 
       
  1619     if (m_spInPlaceActiveObject && widget) {
       
  1620         QWidget *modal = QApplication::activeModalWidget();
       
  1621         if (modal && inPlaceModelessEnabled) {
       
  1622             m_spInPlaceActiveObject->EnableModeless(false);
       
  1623             inPlaceModelessEnabled = false;
       
  1624         } else if (!inPlaceModelessEnabled) {
       
  1625             m_spInPlaceActiveObject->EnableModeless(true);
       
  1626             inPlaceModelessEnabled = true;
       
  1627         }
       
  1628         m_spInPlaceActiveObject->OnFrameWindowActivate(widget->isActiveWindow());
       
  1629     }
       
  1630 }
       
  1631 
       
  1632 
       
  1633 //**** QWidget
       
  1634 
       
  1635 QAxHostWidget::QAxHostWidget(QWidget *parent, QAxClientSite *ax)
       
  1636 : QWidget(parent), setFocusTimer(0), hasFocus(false), axhost(ax)
       
  1637 {
       
  1638     setAttribute(Qt::WA_NoBackground);
       
  1639     setAttribute(Qt::WA_NoSystemBackground);
       
  1640     setAttribute(Qt::WA_OpaquePaintEvent);
       
  1641     setAttribute(Qt::WA_PaintOnScreen);
       
  1642 
       
  1643     setObjectName(parent->objectName() + QLatin1String(" - QAxHostWidget"));
       
  1644 }
       
  1645 
       
  1646 QAxHostWidget::~QAxHostWidget()
       
  1647 {
       
  1648     if (axhost)
       
  1649         axhost->reset(this);
       
  1650 }
       
  1651 
       
  1652 int QAxHostWidget::qt_metacall(QMetaObject::Call call, int isignal, void **argv)
       
  1653 {
       
  1654     if (axhost)
       
  1655         return axhost->qt_metacall(call, isignal, argv);
       
  1656     return -1;
       
  1657 }
       
  1658 
       
  1659 void* QAxHostWidget::qt_metacast(const char *clname)
       
  1660 {
       
  1661     if (!clname) return 0;
       
  1662     if (!qstrcmp(clname,"QAxHostWidget"))
       
  1663         return static_cast<void*>(const_cast< QAxHostWidget*>(this));
       
  1664     return QWidget::qt_metacast(clname);
       
  1665 }
       
  1666 
       
  1667 QSize QAxHostWidget::sizeHint() const
       
  1668 {
       
  1669     return axhost ? axhost->sizeHint() : QWidget::sizeHint();
       
  1670 }
       
  1671 
       
  1672 QSize QAxHostWidget::minimumSizeHint() const
       
  1673 {
       
  1674     QSize size;
       
  1675     if (axhost)
       
  1676         size = axhost->minimumSizeHint();
       
  1677     if (size.isValid())
       
  1678         return size;
       
  1679     return QWidget::minimumSizeHint();
       
  1680 }
       
  1681 
       
  1682 void QAxHostWidget::resizeObject()
       
  1683 {
       
  1684     if (!axhost)
       
  1685         return;
       
  1686 
       
  1687     // document server - talk to view?
       
  1688     if (axhost->m_spActiveView) {
       
  1689         RECT rect;
       
  1690         GetClientRect(winId(), &rect);
       
  1691         axhost->m_spActiveView->SetRect(&rect);
       
  1692 
       
  1693         return;
       
  1694     }
       
  1695 
       
  1696     SIZEL hmSize;
       
  1697     hmSize.cx = MAP_PIX_TO_LOGHIM(width(), logicalDpiX());
       
  1698     hmSize.cy = MAP_PIX_TO_LOGHIM(height(), logicalDpiY());
       
  1699 
       
  1700     if (axhost->m_spOleObject)
       
  1701         axhost->m_spOleObject->SetExtent(DVASPECT_CONTENT, &hmSize);
       
  1702     if (axhost->m_spInPlaceObject) {
       
  1703         RECT rcPos = { x(), y(), x()+width(), y()+height() };
       
  1704         axhost->m_spInPlaceObject->SetObjectRects(&rcPos, &rcPos);
       
  1705     }
       
  1706 }
       
  1707 
       
  1708 void QAxHostWidget::resizeEvent(QResizeEvent *)
       
  1709 {
       
  1710     resizeObject();
       
  1711 }
       
  1712 
       
  1713 void QAxHostWidget::showEvent(QShowEvent *)
       
  1714 {
       
  1715     resizeObject();
       
  1716 }
       
  1717 
       
  1718 bool QAxHostWidget::winEvent(MSG *msg, long *result)
       
  1719 {
       
  1720     if (axhost && axhost->inPlaceObjectWindowless) {
       
  1721         Q_ASSERT(axhost->m_spInPlaceObject);
       
  1722         IOleInPlaceObjectWindowless *windowless = (IOleInPlaceObjectWindowless*)axhost->m_spInPlaceObject;
       
  1723         Q_ASSERT(windowless);
       
  1724         LRESULT lres;
       
  1725         HRESULT hres = windowless->OnWindowMessage(msg->message, msg->wParam, msg->lParam, &lres);
       
  1726         if (hres == S_OK)
       
  1727             return true;
       
  1728     }
       
  1729     return QWidget::winEvent(msg, result);
       
  1730 }
       
  1731 
       
  1732 bool QAxHostWidget::event(QEvent *e)
       
  1733 {
       
  1734     switch (e->type()) {
       
  1735     case QEvent::Timer:
       
  1736         if (axhost && ((QTimerEvent*)e)->timerId() == setFocusTimer) {
       
  1737             killTimer(setFocusTimer);
       
  1738             setFocusTimer = 0;
       
  1739             RECT rcPos = { x(), y(), x()+size().width(), y()+size().height() };
       
  1740             axhost->m_spOleObject->DoVerb(OLEIVERB_UIACTIVATE, 0, (IOleClientSite*)axhost, 0, winId(), &rcPos);
       
  1741             if (axhost->m_spActiveView)
       
  1742                 axhost->m_spActiveView->UIActivate(TRUE);
       
  1743         }
       
  1744         break;
       
  1745     case QEvent::WindowBlocked:
       
  1746         if (IsWindowEnabled(winId())) {
       
  1747             EnableWindow(winId(), false);
       
  1748             if (axhost && axhost->m_spInPlaceActiveObject) {
       
  1749                 axhost->inPlaceModelessEnabled = false;
       
  1750                 axhost->m_spInPlaceActiveObject->EnableModeless(false);
       
  1751             }
       
  1752         }
       
  1753         break;
       
  1754     case QEvent::WindowUnblocked:
       
  1755         if (!IsWindowEnabled(winId())) {
       
  1756             EnableWindow(winId(), true);
       
  1757             if (axhost && axhost->m_spInPlaceActiveObject) {
       
  1758                 axhost->inPlaceModelessEnabled = true;
       
  1759                 axhost->m_spInPlaceActiveObject->EnableModeless(true);
       
  1760             }
       
  1761         }
       
  1762         break;
       
  1763     default:
       
  1764         break;
       
  1765     }
       
  1766 
       
  1767     return QWidget::event(e);
       
  1768 }
       
  1769 
       
  1770 bool QAxHostWidget::eventFilter(QObject *o, QEvent *e)
       
  1771 {
       
  1772     // focus goes to Qt while ActiveX still has it - deactivate
       
  1773     QWidget *newFocus = qobject_cast<QWidget*>(o);
       
  1774     if (e->type() == QEvent::FocusIn && hasFocus
       
  1775         && newFocus && newFocus->window() == window()) {
       
  1776         if (axhost && axhost->m_spInPlaceActiveObject && axhost->m_spInPlaceObject)
       
  1777             axhost->m_spInPlaceObject->UIDeactivate();
       
  1778         qApp->removeEventFilter(this);
       
  1779     }
       
  1780 
       
  1781     return QWidget::eventFilter(o, e);
       
  1782 }
       
  1783 
       
  1784 void QAxHostWidget::focusInEvent(QFocusEvent *e)
       
  1785 {
       
  1786     QWidget::focusInEvent(e);
       
  1787 
       
  1788     if (!axhost || !axhost->m_spOleObject)
       
  1789         return;
       
  1790 
       
  1791     // this is called by QWidget::setFocus which calls ::SetFocus on "this",
       
  1792     // so we have to UIActivate the control after all that had happend.
       
  1793     AX_DEBUG(Setting focus on in-place object);
       
  1794     setFocusTimer = startTimer(0);
       
  1795 }
       
  1796 
       
  1797 void QAxHostWidget::focusOutEvent(QFocusEvent *e)
       
  1798 {
       
  1799     QWidget::focusOutEvent(e);
       
  1800     if (setFocusTimer) {
       
  1801         killTimer(setFocusTimer);
       
  1802         setFocusTimer = 0;
       
  1803     }
       
  1804     if (e->reason() == Qt::PopupFocusReason || e->reason() == Qt::MenuBarFocusReason)
       
  1805         return;
       
  1806 
       
  1807     if (!axhost || !axhost->m_spInPlaceActiveObject || !axhost->m_spInPlaceObject)
       
  1808         return;
       
  1809 
       
  1810     AX_DEBUG(Deactivating in-place object);
       
  1811     axhost->m_spInPlaceObject->UIDeactivate();
       
  1812 }
       
  1813 
       
  1814 
       
  1815 void QAxHostWidget::paintEvent(QPaintEvent*)
       
  1816 {
       
  1817     if (!QPainter::redirected(this))
       
  1818         return;
       
  1819 
       
  1820     IViewObject *view = 0;
       
  1821     if (axhost)
       
  1822         axhost->widget->queryInterface(IID_IViewObject, (void**)&view);
       
  1823     if (!view)
       
  1824         return;
       
  1825 
       
  1826     // somebody tries to grab us!
       
  1827     QPixmap pm(size());
       
  1828     pm.fill();
       
  1829 
       
  1830     HBITMAP hBmp = pm.toWinHBITMAP();
       
  1831     HDC hBmp_hdc = CreateCompatibleDC(qt_win_display_dc());
       
  1832     HGDIOBJ old_hBmp = SelectObject(hBmp_hdc, hBmp);
       
  1833 
       
  1834     RECTL bounds;
       
  1835     bounds.left = 0;
       
  1836     bounds.right = pm.width();
       
  1837     bounds.top = 0;
       
  1838     bounds.bottom = pm.height();
       
  1839 
       
  1840     view->Draw(DVASPECT_CONTENT, -1, 0, 0, 0, hBmp_hdc, &bounds, 0, 0 /*fptr*/, 0);
       
  1841     view->Release();
       
  1842 
       
  1843     QPainter painter(this);
       
  1844     painter.drawPixmap(0, 0, QPixmap::fromWinHBITMAP(hBmp));
       
  1845 
       
  1846     SelectObject(hBmp_hdc, old_hBmp);
       
  1847     DeleteObject(hBmp);
       
  1848     DeleteDC(hBmp_hdc);
       
  1849 }
       
  1850 
       
  1851 /*!
       
  1852     \class QAxWidget
       
  1853     \brief The QAxWidget class is a QWidget that wraps an ActiveX control.
       
  1854 
       
  1855     \inmodule QAxContainer
       
  1856 
       
  1857     A QAxWidget can be instantiated as an empty object, with the name
       
  1858     of the ActiveX control it should wrap, or with an existing
       
  1859     interface pointer to the ActiveX control. The ActiveX control's
       
  1860     properties, methods and events which only use QAxBase
       
  1861     supported data types, become available as Qt properties,
       
  1862     slots and signals. The base class QAxBase provides an API to
       
  1863     access the ActiveX directly through the \c IUnknown pointer.
       
  1864 
       
  1865     QAxWidget is a QWidget and can mostly be used as such, e.g. it can be
       
  1866     organized in a widget hierarchy and layouts or act as an event filter.
       
  1867     Standard widget properties, e.g. \link QWidget::enabled
       
  1868     enabled \endlink are supported, but it depends on the ActiveX
       
  1869     control to implement support for ambient properties like e.g.
       
  1870     palette or font. QAxWidget tries to provide the necessary hints.
       
  1871 
       
  1872     However, you cannot reimplement Qt-specific event handlers like
       
  1873     mousePressEvent or keyPressEvent and expect them to be called reliably.
       
  1874     The embedded control covers the QAxWidget completely, and usually
       
  1875     handles the user interface itself. Use control-specific APIs (i.e. listen
       
  1876     to the signals of the control), or use standard COM techniques like
       
  1877     window procedure subclassing.
       
  1878 
       
  1879     QAxWidget also inherits most of its ActiveX-related functionality
       
  1880     from QAxBase, notably dynamicCall() and querySubObject().
       
  1881 
       
  1882     \warning
       
  1883     You can subclass QAxWidget, but you cannot use the \c Q_OBJECT macro
       
  1884     in the subclass (the generated moc-file will not compile), so you
       
  1885     cannot add further signals, slots or properties. This limitation
       
  1886     is due to the metaobject information generated in runtime. To work
       
  1887     around this problem, aggregate the QAxWidget as a member of the
       
  1888     QObject subclass.
       
  1889 
       
  1890     \sa QAxBase, QAxObject, QAxScript, {ActiveQt Framework}
       
  1891 */
       
  1892 
       
  1893 /*!
       
  1894     Creates an empty QAxWidget widget and propagates \a parent
       
  1895     and \a f to the QWidget constructor. To initialize a control,
       
  1896     call setControl().
       
  1897 */
       
  1898 QAxWidget::QAxWidget(QWidget *parent, Qt::WindowFlags f)
       
  1899 : QWidget(parent, f), container(0)
       
  1900 {
       
  1901 }
       
  1902 
       
  1903 /*!
       
  1904     Creates an QAxWidget widget and initializes the ActiveX control \a c.
       
  1905     \a parent and \a f are propagated to the QWidget contructor.
       
  1906 
       
  1907     \sa setControl()
       
  1908 */
       
  1909 QAxWidget::QAxWidget(const QString &c, QWidget *parent, Qt::WindowFlags f)
       
  1910 : QWidget(parent, f), container(0)
       
  1911 {
       
  1912     setControl(c);
       
  1913 }
       
  1914 
       
  1915 /*!
       
  1916     Creates a QAxWidget that wraps the COM object referenced by \a iface.
       
  1917     \a parent and \a f are propagated to the QWidget contructor.
       
  1918 */
       
  1919 QAxWidget::QAxWidget(IUnknown *iface, QWidget *parent, Qt::WindowFlags f)
       
  1920 : QWidget(parent, f), QAxBase(iface), container(0)
       
  1921 {
       
  1922 }
       
  1923 
       
  1924 /*!
       
  1925     Shuts down the ActiveX control and destroys the QAxWidget widget,
       
  1926     cleaning up all allocated resources.
       
  1927 
       
  1928     \sa clear()
       
  1929 */
       
  1930 QAxWidget::~QAxWidget()
       
  1931 {
       
  1932     if (container)
       
  1933         container->reset(this);
       
  1934     clear();
       
  1935 }
       
  1936 
       
  1937 /*!
       
  1938     \since 4.2
       
  1939 
       
  1940     Calls QAxBase::initialize(\a ptr), and embeds the control in this
       
  1941     widget by calling createHostWindow(false) if successful.
       
  1942 
       
  1943     To initialize the control before it is activated, reimplement this
       
  1944     function and add your initialization code before you call
       
  1945     createHostWindow(true).
       
  1946 */
       
  1947 bool QAxWidget::initialize(IUnknown **ptr)
       
  1948 {
       
  1949     if (!QAxBase::initialize(ptr))
       
  1950         return false;
       
  1951 
       
  1952     return createHostWindow(false); // assume that control is not initialized
       
  1953 }
       
  1954 
       
  1955 /*!
       
  1956     Creates the client site for the ActiveX control, and returns true if
       
  1957     the control could be embedded successfully, otherwise returns false.
       
  1958     If \a initialized is true the control has already been initialized.
       
  1959 
       
  1960     This function is called by initialize(). If you reimplement initialize
       
  1961     to customize the actual control instantiation, call this function in your
       
  1962     reimplementation to have the control embedded by the default client side.
       
  1963     Creates the client site for the ActiveX control, and returns true if
       
  1964     the control could be embedded successfully, otherwise returns false.
       
  1965 */
       
  1966 bool QAxWidget::createHostWindow(bool initialized)
       
  1967 {
       
  1968     return createHostWindow(initialized, QByteArray());
       
  1969 }
       
  1970 
       
  1971 /*!
       
  1972     \since 4.4
       
  1973 
       
  1974     Creates the client site for the ActiveX control, and returns true if
       
  1975     the control could be embedded successfully, otherwise returns false.
       
  1976     If \a initialized is false the control will be initialized using the
       
  1977     \a data. The control will be initialized through either IPersistStreamInit
       
  1978     or IPersistStorage interface.
       
  1979 
       
  1980     If the control needs to be initialized using custom data, call this function
       
  1981     in your reimplementation of initialize(). This function is not called by
       
  1982     the  default implementation of initialize().
       
  1983 */
       
  1984 bool QAxWidget::createHostWindow(bool initialized, const QByteArray &data)
       
  1985 {
       
  1986 #ifdef QT3_SUPPORT
       
  1987     QApplication::sendPostedEvents(0, QEvent::ChildInserted);
       
  1988 #endif
       
  1989 
       
  1990     container = new QAxClientSite(this);
       
  1991     container->activateObject(initialized, data);
       
  1992 
       
  1993 #if !defined(Q_OS_WINCE)
       
  1994     ATOM filter_ref = FindAtom(qaxatom);
       
  1995 #endif
       
  1996     if (!filter_ref)
       
  1997         previous_filter = QAbstractEventDispatcher::instance()->setEventFilter(axc_FilterProc);
       
  1998 #if !defined(Q_OS_WINCE)
       
  1999     AddAtom(qaxatom);
       
  2000 #else
       
  2001     ++filter_ref;
       
  2002 #endif
       
  2003 
       
  2004     if (parentWidget())
       
  2005         QApplication::postEvent(parentWidget(), new QEvent(QEvent::LayoutRequest));
       
  2006 
       
  2007     return true;
       
  2008 }
       
  2009 
       
  2010 /*!
       
  2011     Reimplement this function when you want to implement additional
       
  2012     COM interfaces for the client site of the ActiveX control, or when
       
  2013     you want to provide alternative implementations of COM interfaces.
       
  2014     Return a new object of a QAxAggregated subclass.
       
  2015 
       
  2016     The default implementation returns the null pointer.
       
  2017 */
       
  2018 QAxAggregated *QAxWidget::createAggregate()
       
  2019 {
       
  2020     return 0;
       
  2021 }
       
  2022 
       
  2023 /*!
       
  2024     \reimp
       
  2025 
       
  2026     Shuts down the ActiveX control.
       
  2027 */
       
  2028 void QAxWidget::clear()
       
  2029 {
       
  2030     if (isNull())
       
  2031         return;
       
  2032     if (!control().isEmpty()) {
       
  2033 #if !defined(Q_OS_WINCE)
       
  2034         ATOM filter_ref = FindAtom(qaxatom);
       
  2035         if (filter_ref)
       
  2036             DeleteAtom(filter_ref);
       
  2037         filter_ref = FindAtom(qaxatom);
       
  2038         if (!filter_ref) {
       
  2039 #else
       
  2040         if (!filter_ref && !--filter_ref) {
       
  2041 #endif
       
  2042             QAbstractEventDispatcher::instance()->setEventFilter(previous_filter);
       
  2043             previous_filter = 0;
       
  2044         }
       
  2045     }
       
  2046 
       
  2047     if (container)
       
  2048         container->deactivate();
       
  2049 
       
  2050     QAxBase::clear();
       
  2051     setFocusPolicy(Qt::NoFocus);
       
  2052 
       
  2053     if (container) {
       
  2054         container->releaseAll();
       
  2055         container->Release();
       
  2056     }
       
  2057     container = 0;
       
  2058 }
       
  2059 
       
  2060 /*!
       
  2061     \since 4.1
       
  2062 
       
  2063     Requests the ActiveX control to perform the action \a verb. The
       
  2064     possible verbs are returned by verbs().
       
  2065 
       
  2066     The function returns true if the object could perform the action, otherwise returns false.
       
  2067 */
       
  2068 bool QAxWidget::doVerb(const QString &verb)
       
  2069 {
       
  2070     if (!verbs().contains(verb))
       
  2071         return false;
       
  2072 
       
  2073     HRESULT hres = container->doVerb(indexOfVerb(verb));
       
  2074 
       
  2075     return hres == S_OK;
       
  2076 }
       
  2077 
       
  2078  /*!
       
  2079     \fn QObject *QAxWidget::qObject() const
       
  2080     \internal
       
  2081 */
       
  2082 
       
  2083 /*!
       
  2084     \internal
       
  2085 */
       
  2086 const QMetaObject *QAxWidget::metaObject() const
       
  2087 {
       
  2088     return QAxBase::metaObject();
       
  2089 }
       
  2090 
       
  2091 /*!
       
  2092     \internal
       
  2093 */
       
  2094 const QMetaObject *QAxWidget::parentMetaObject() const
       
  2095 {
       
  2096     return &QWidget::staticMetaObject;
       
  2097 }
       
  2098 
       
  2099 /*!
       
  2100     \internal
       
  2101 */
       
  2102 void *QAxWidget::qt_metacast(const char *cname)
       
  2103 {
       
  2104     if (!qstrcmp(cname, "QAxWidget")) return (void*)this;
       
  2105     if (!qstrcmp(cname, "QAxBase")) return (QAxBase*)this;
       
  2106     return QWidget::qt_metacast(cname);
       
  2107 }
       
  2108 
       
  2109 /*!
       
  2110     \internal
       
  2111 */
       
  2112 const char *QAxWidget::className() const
       
  2113 {
       
  2114     return "QAxWidget";
       
  2115 }
       
  2116 
       
  2117 /*!
       
  2118     \internal
       
  2119 */
       
  2120 int QAxWidget::qt_metacall(QMetaObject::Call call, int id, void **v)
       
  2121 {
       
  2122     id = QWidget::qt_metacall(call, id, v);
       
  2123     if (id < 0)
       
  2124         return id;
       
  2125     return QAxBase::qt_metacall(call, id, v);
       
  2126 }
       
  2127 
       
  2128 /*!
       
  2129     \reimp
       
  2130 */
       
  2131 QSize QAxWidget::sizeHint() const
       
  2132 {
       
  2133     if (container) {
       
  2134         QSize sh = container->sizeHint();
       
  2135         if (sh.isValid())
       
  2136             return sh;
       
  2137     }
       
  2138 
       
  2139     return QWidget::sizeHint();
       
  2140 }
       
  2141 
       
  2142 /*!
       
  2143     \reimp
       
  2144 */
       
  2145 QSize QAxWidget::minimumSizeHint() const
       
  2146 {
       
  2147     if (container) {
       
  2148         QSize sh = container->minimumSizeHint();
       
  2149         if (sh.isValid())
       
  2150             return sh;
       
  2151     }
       
  2152 
       
  2153     return QWidget::minimumSizeHint();
       
  2154 }
       
  2155 
       
  2156 /*!
       
  2157     \reimp
       
  2158 */
       
  2159 void QAxWidget::changeEvent(QEvent *e)
       
  2160 {
       
  2161     if (isNull())
       
  2162         return;
       
  2163 
       
  2164     switch (e->type()) {
       
  2165     case QEvent::EnabledChange:
       
  2166         container->emitAmbientPropertyChange(DISPID_AMBIENT_UIDEAD);
       
  2167         break;
       
  2168     case QEvent::FontChange:
       
  2169         container->emitAmbientPropertyChange(DISPID_AMBIENT_FONT);
       
  2170         break;
       
  2171     case QEvent::PaletteChange:
       
  2172         container->emitAmbientPropertyChange(DISPID_AMBIENT_BACKCOLOR);
       
  2173         container->emitAmbientPropertyChange(DISPID_AMBIENT_FORECOLOR);
       
  2174         break;
       
  2175     case QEvent::ActivationChange:
       
  2176         container->windowActivationChange();
       
  2177         break;
       
  2178     default:
       
  2179         break;
       
  2180     }
       
  2181 }
       
  2182 
       
  2183 /*!
       
  2184     \reimp
       
  2185 */
       
  2186 void QAxWidget::resizeEvent(QResizeEvent *)
       
  2187 {
       
  2188     if (container)
       
  2189         container->resize(size());
       
  2190 }
       
  2191 
       
  2192 /*!
       
  2193     \reimp
       
  2194 */
       
  2195 void QAxWidget::connectNotify(const char *)
       
  2196 {
       
  2197     QAxBase::connectNotify();
       
  2198 }
       
  2199 
       
  2200 
       
  2201 /*!
       
  2202     Reimplement this function to pass certain key events to the
       
  2203     ActiveX control. \a message is the Window message identifier
       
  2204     specifying the message type (ie. WM_KEYDOWN), and \a keycode is
       
  2205     the virtual keycode (ie. VK_TAB).
       
  2206 
       
  2207     If the function returns true the key event is passed on to the
       
  2208     ActiveX control, which then either processes the event or passes
       
  2209     the event on to Qt.
       
  2210 
       
  2211     If the function returns false the processing of the key event is
       
  2212     ignored by ActiveQt, ie. the ActiveX control might handle it or
       
  2213     not.
       
  2214 
       
  2215     The default implementation returns true for the following cases:
       
  2216 
       
  2217     \table
       
  2218     \header
       
  2219     \i WM_SYSKEYDOWN
       
  2220     \i WM_SYSKEYUP
       
  2221     \i WM_KEYDOWN
       
  2222     \row
       
  2223     \i All keycodes
       
  2224     \i VK_MENU
       
  2225     \i VK_TAB, VK_DELETE and all non-arrow-keys in combination with VK_SHIFT,
       
  2226        VK_CONTROL or VK_MENU
       
  2227     \endtable
       
  2228 
       
  2229     This table is the result of experimenting with popular ActiveX controls,
       
  2230     ie. Internet Explorer and Microsoft Office applications, but for some
       
  2231     controls it might require modification.
       
  2232 */
       
  2233 bool QAxWidget::translateKeyEvent(int message, int keycode) const
       
  2234 {
       
  2235     bool translate = false;
       
  2236 
       
  2237     switch (message) {
       
  2238     case WM_SYSKEYDOWN:
       
  2239         translate = true;
       
  2240         break;
       
  2241     case WM_KEYDOWN:
       
  2242         translate = keycode == VK_TAB
       
  2243             || keycode == VK_DELETE;
       
  2244         if (!translate) {
       
  2245             int state = 0;
       
  2246             if (GetKeyState(VK_SHIFT) < 0)
       
  2247                 state |= 0x01;
       
  2248             if (GetKeyState(VK_CONTROL) < 0)
       
  2249                 state |= 0x02;
       
  2250             if (GetKeyState(VK_MENU) < 0)
       
  2251                 state |= 0x04;
       
  2252             if (state) {
       
  2253                 state = keycode < VK_LEFT || keycode > VK_DOWN;
       
  2254             }
       
  2255             translate = state;
       
  2256         }
       
  2257         break;
       
  2258     case WM_SYSKEYUP:
       
  2259         translate = keycode == VK_MENU;
       
  2260         break;
       
  2261     }
       
  2262 
       
  2263     return translate;
       
  2264 }
       
  2265 
       
  2266 QT_END_NAMESPACE
       
  2267 #endif // QT_NO_WIN_ACTIVEQT