/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the ActiveQt framework of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#define NOMINMAX

#include <qabstracteventdispatcher.h>
#include <qapplication.h>
#include <qbuffer.h>
#include <qdatastream.h>
#include <qdebug.h>
#include <qevent.h>
#include <qeventloop.h>
#include <qfile.h>
#include <qpointer.h>
#include <qhash.h>
#include <qmap.h>
#include <qmenubar.h>
#include <qmenu.h>
#include <qmetaobject.h>
#include <qpixmap.h>
#include <qregularexpression.h>
#include <qstatusbar.h>
#include <qwhatsthis.h>
#include <ocidl.h>
#include <olectl.h>
#include <private/qcoreapplication_p.h>
#include <qwindow.h>
#include <qpa/qplatformnativeinterface.h>
#include <qabstractnativeeventfilter.h>

#include <qcoreapplication.h>
#include <qvector.h>
#include <private/qthread_p.h>

#include "qaxfactory.h"
#include "qaxbindable.h"
#include "qaxaggregated.h"

#include "../shared/qaxtypes.h"
#include "../shared/qaxutils_p.h"

#include "qclassfactory_p.h"

#if defined Q_CC_GNU
#   include <w32api.h>
#endif

#ifndef Q_OS_WIN64
#define ULONG_PTR DWORD
#endif

// Statusbar messageChanged() signal is connected to a fake slot
// that is custom handled in qt_metacall. Index needs to fit to ushort.
#define STATUSBAR_MESSAGE_CHANGED_SLOT_INDEX 60000

QT_BEGIN_NAMESPACE

extern HHOOK qax_hhook;

// in qaxserver.cpp
extern ITypeLib *qAxTypeLibrary;
extern unsigned long qAxLock();
extern unsigned long qAxUnlock();
extern HANDLE qAxInstance;
extern bool qAxOutProcServer;

static int invokeCount = 0;

#ifdef QT_DEBUG
unsigned long qaxserverbase_instance_count = 0;
#endif

// in qaxserverdll.cpp
extern bool qax_ownQApp;

struct QAxExceptInfo
{
    QAxExceptInfo(int c, const QString &s, const QString &d, const QString &x)
        : code(c), src(s), desc(d), context(x)
    {
    }
    int code;
    QString src;
    QString desc;
    QString context;
};


bool qt_sendSpontaneousEvent(QObject*, QEvent*);

/*
    \class QAxServerBase
    \brief The QAxServerBase class is an ActiveX control hosting a QWidget.

    \internal
*/
class QAxServerBase :
    public QObject,
    public IAxServerBase,
    public IDispatch,
    public IOleObject,
    public IOleControl,
#if defined Q_CC_GNU
#   if (__W32API_MAJOR_VERSION < 2 || (__W32API_MAJOR_VERSION == 2 && __W32API_MINOR_VERSION < 5))
    public IViewObject, // this should not be needed as IViewObject2 is meant to inherit from this,
                        // until the mingw headers are fixed this will need to stay.
#   endif
#endif
    public IViewObject2,
    public IOleInPlaceObject,
    public IOleInPlaceActiveObject,
    public IProvideClassInfo2,
    public IConnectionPointContainer,
    public IPersistStream,
    public IPersistStreamInit,
    public IPersistStorage,
    public IPersistPropertyBag,
    public IPersistFile,
    public IDataObject
{
public:
    using ConnectionPoints = QMap<QUuid,IConnectionPoint*>;

    QAxServerBase(const QString &classname, IUnknown *outerUnknown);
    QAxServerBase(QObject *o);

    void init();

    ~QAxServerBase() override;

// Window creation
    HWND create(HWND hWndParent, RECT& rcPos);
    HMENU createPopup(QMenu *popup, HMENU oldMenu = nullptr);
    void createMenu(QMenuBar *menuBar);
    void removeMenu();

    static LRESULT QT_WIN_CALLBACK ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

// Object registration with OLE
    void registerActiveObject(IUnknown *object);
    void revokeActiveObject();

// IUnknown
    unsigned long WINAPI AddRef() override
    {
        if (m_outerUnknown)
            return m_outerUnknown->AddRef();

        return InterlockedIncrement(&ref);
    }
    unsigned long WINAPI Release() override
    {
        if (m_outerUnknown)
            return m_outerUnknown->Release();

        LONG refCount = InterlockedDecrement(&ref);
        if (!refCount)
            delete this;

        return refCount;
    }
    HRESULT WINAPI QueryInterface(REFIID iid, void **iface) override;
    HRESULT InternalQueryInterface(REFIID iid, void **iface);

// IAxServerBase
    IUnknown *clientSite() const override
    {
        return m_spClientSite;
    }

    void emitPropertyChanged(const char *) override;
    bool emitRequestPropertyChange(const char *) override;
    QObject *qObject() const override
    {
        return theObject;
    }
    void ensureMetaData();
    bool isPropertyExposed(int index);

    void reportError(int code, const QString &src, const QString &desc,
                     const QString &context) override
    {
        delete exception;
        exception = new QAxExceptInfo(code, src, desc, context);
    }

// IDispatch
    STDMETHOD(GetTypeInfoCount)(UINT* pctinfo);
    STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo);
    STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid);
    STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
                LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
                EXCEPINFO* pexcepinfo, UINT* puArgErr);

// IProvideClassInfo
    STDMETHOD(GetClassInfo)(ITypeInfo** pptinfo);

// IProvideClassInfo2
    STDMETHOD(GetGUID)(DWORD dwGuidKind, GUID* pGUID);

// IOleObject
    STDMETHOD(Advise)(IAdviseSink* pAdvSink, DWORD* pdwConnection);
    STDMETHOD(Close)(DWORD dwSaveOption);
    STDMETHOD(DoVerb)(LONG iVerb, LPMSG lpmsg, IOleClientSite* pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect);
    STDMETHOD(EnumAdvise)(IEnumSTATDATA** ppenumAdvise);
    STDMETHOD(EnumVerbs)(IEnumOLEVERB** ppEnumOleVerb);
    STDMETHOD(GetClientSite)(IOleClientSite** ppClientSite);
    STDMETHOD(GetClipboardData)(DWORD dwReserved, IDataObject** ppDataObject);
    STDMETHOD(GetExtent)(DWORD dwDrawAspect, SIZEL* psizel);
    STDMETHOD(GetMiscStatus)(DWORD dwAspect, DWORD *pdwStatus);
    STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk);
    STDMETHOD(GetUserClassID)(CLSID* pClsid);
    STDMETHOD(GetUserType)(DWORD dwFormOfType, LPOLESTR *pszUserType);
    STDMETHOD(InitFromData)(IDataObject* pDataObject, BOOL fCreation, DWORD dwReserved);
    STDMETHOD(IsUpToDate)();
    STDMETHOD(SetClientSite)(IOleClientSite* pClientSite);
    STDMETHOD(SetColorScheme)(LOGPALETTE* pLogPal);
    STDMETHOD(SetExtent)(DWORD dwDrawAspect, SIZEL* psizel);
    STDMETHOD(SetHostNames)(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj);
    STDMETHOD(SetMoniker)(DWORD dwWhichMoniker, IMoniker* ppmk);
    STDMETHOD(Unadvise)(DWORD dwConnection);
    STDMETHOD(Update)();

// IViewObject
    STDMETHOD(Draw)(DWORD dwAspect, LONG lIndex, void *pvAspect, DVTARGETDEVICE *ptd,
                    HDC hicTargetDevice, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds,
                    BOOL(__stdcall*pfnContinue)(ULONG_PTR), ULONG_PTR dwContinue);
    STDMETHOD(GetColorSet)(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
                    HDC hicTargetDev, LOGPALETTE **ppColorSet);
    STDMETHOD(Freeze)(DWORD dwAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze);
    STDMETHOD(Unfreeze)(DWORD dwFreeze);
    STDMETHOD(SetAdvise)(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink);
    STDMETHOD(GetAdvise)(DWORD *aspects, DWORD *advf, IAdviseSink **pAdvSink);

// IViewObject2
    STDMETHOD(GetExtent)(DWORD dwAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel);

// IOleControl
    STDMETHOD(FreezeEvents)(BOOL);
    STDMETHOD(GetControlInfo)(LPCONTROLINFO);
    STDMETHOD(OnAmbientPropertyChange)(DISPID);
    STDMETHOD(OnMnemonic)(LPMSG);

// IOleWindow
    STDMETHOD(GetWindow)(HWND *pHwnd);
    STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode);

// IOleInPlaceObject
    STDMETHOD(InPlaceDeactivate)();
    STDMETHOD(UIDeactivate)();
    STDMETHOD(SetObjectRects)(LPCRECT lprcPosRect, LPCRECT lprcClipRect);
    STDMETHOD(ReactivateAndUndo)();

// IOleInPlaceActiveObject
    STDMETHOD(TranslateAcceleratorW)(MSG *pMsg);
    STDMETHOD(TranslateAcceleratorA)(MSG *pMsg);
    STDMETHOD(OnFrameWindowActivate)(BOOL);
    STDMETHOD(OnDocWindowActivate)(BOOL fActivate);
    STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow);
    STDMETHOD(EnableModeless)(BOOL);

// IConnectionPointContainer
    STDMETHOD(EnumConnectionPoints)(IEnumConnectionPoints**);
    STDMETHOD(FindConnectionPoint)(REFIID, IConnectionPoint**);

// IPersist
    STDMETHOD(GetClassID)(GUID*clsid)
    {
        *clsid = qAxFactory()->classID(class_name);
        return S_OK;
    }

// IPersistStreamInit
    STDMETHOD(InitNew)(VOID);
    STDMETHOD(IsDirty)();
    STDMETHOD(Load)(IStream *pStm);
    STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty);
    STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize);

// IPersistPropertyBag
    STDMETHOD(Load)(IPropertyBag *, IErrorLog *);
    STDMETHOD(Save)(IPropertyBag *, BOOL, BOOL);

// IPersistStorage
    STDMETHOD(InitNew)(IStorage *pStg);
    STDMETHOD(Load)(IStorage *pStg);
    STDMETHOD(Save)(IStorage *pStg, BOOL fSameAsLoad);
    STDMETHOD(SaveCompleted)(IStorage *pStgNew);
    STDMETHOD(HandsOffStorage)();

// IPersistFile
    STDMETHOD(SaveCompleted)(LPCOLESTR fileName);
    STDMETHOD(GetCurFile)(LPOLESTR *currentFile);
    STDMETHOD(Load)(LPCOLESTR fileName, DWORD mode);
    STDMETHOD(Save)(LPCOLESTR fileName, BOOL fRemember);

// IDataObject
    STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
    STDMETHOD(GetDataHere)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */);
    STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */);
    STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */);
    STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */);
    STDMETHOD(EnumFormatEtc)(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */);
    STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
    STDMETHOD(DUnadvise)(DWORD dwConnection);
    STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise);

// QObject
    int qt_metacall(QMetaObject::Call, int index, void **argv) override;

    bool eventFilter(QObject *o, QEvent *e) override;

    RECT rcPosRect() const
    {
        RECT result = {0, 0, 1, 1};
        if (qt.widget)
            result = qaxContentRect(QSize(1, 1) + qaxNativeWidgetSize(qt.widget));
        return result;
    }

private:
    void update();
    void resize(const QSize &newSize);
    void updateGeometry();
    void updateMask();
    bool internalCreate();
    void internalBind();
    void internalConnect();
    HRESULT internalActivate();

    friend class QAxBindable;
    friend class QAxPropertyPage;
    QAxAggregated *aggregatedObject = nullptr;
    ConnectionPoints points;

    union {
        QWidget *widget;
        QObject *object;
    } qt;
    QPointer<QObject> theObject;
    unsigned isWidget           :1;
    unsigned ownObject          :1;
    unsigned initNewCalled      :1;
    unsigned dirtyflag          :1;
    unsigned hasStockEvents     :1;
    unsigned stayTopLevel       :1;
    unsigned isInPlaceActive    :1;
    unsigned isUIActive         :1;
    unsigned wasUIActive        :1;
    unsigned inDesignMode       :1;
    unsigned canTakeFocus       :1;
    short freezeEvents = 0;

    HWND m_hWnd = nullptr;

    HMENU hmenuShared = nullptr;
    HOLEMENU holemenu = nullptr;
    HWND hwndMenuOwner = nullptr;
    QMap<HMENU, QMenu*> menuMap;
    QMap<UINT, QAction*> actionMap;
    QPointer<QMenuBar> menuBar;
    QPointer<QStatusBar> statusBar;
    QPointer<QMenu> currentPopup;
    QAxExceptInfo *exception = nullptr;

    CRITICAL_SECTION refCountSection;
    CRITICAL_SECTION createWindowSection;

    LONG ref = 0;
    unsigned long ole_ref = 0;

    QString class_name;
    QString currentFileName;

    QHash<long, int> indexCache;
    QHash<int,DISPID> signalCache;

    IUnknown *m_outerUnknown = nullptr;
    IAdviseSink *m_spAdviseSink = nullptr;
    QVector<STATDATA> adviseSinks;
    IOleClientSite *m_spClientSite = nullptr;
    IOleInPlaceSite *m_spInPlaceSite = nullptr;
    IOleInPlaceSiteWindowless *m_spInPlaceSiteWindowless = nullptr;
    IOleInPlaceFrame *m_spInPlaceFrame = nullptr;
    ITypeInfo *m_spTypeInfo = nullptr;
    IStorage *m_spStorage = nullptr;
    QSize m_currentExtent; // device independent pixels.
};

static inline QAxServerBase *axServerBaseFromWindow(HWND hWnd)
{
#ifdef GWLP_USERDATA
    return reinterpret_cast<QAxServerBase *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
#else
    return reinterpret_cast<QAxServerBase *>(GetWindowLong(hWnd, GWL_USERDATA));
#endif
}

class QAxServerAggregate : public IUnknown
{
    Q_DISABLE_COPY_MOVE(QAxServerAggregate)
public:
    QAxServerAggregate(const QString &className, IUnknown *outerUnknown)
    {
        object = new QAxServerBase(className, outerUnknown);
        object->registerActiveObject(this);

        InitializeCriticalSection(&refCountSection);
        InitializeCriticalSection(&createWindowSection);
    }
    virtual ~QAxServerAggregate()
    {
        DeleteCriticalSection(&refCountSection);
        DeleteCriticalSection(&createWindowSection);

        delete object;
    }

// IUnknown
    unsigned long WINAPI AddRef() override
    {
        return InterlockedIncrement(&ref);
    }
    unsigned long WINAPI Release() override
    {
        LONG refCount = InterlockedDecrement(&ref);
        if (!refCount)
            delete this;

        return refCount;
    }
    HRESULT WINAPI QueryInterface(REFIID iid, void **iface) override
    {
        *iface = nullptr;

        if (iid == IID_IUnknown) {
            *iface = static_cast<IUnknown *>(this);
            AddRef();
            return S_OK;
        }
        return object->InternalQueryInterface(iid, iface);
    }

private:
    QAxServerBase *object;
    LONG ref = 0;

    CRITICAL_SECTION refCountSection;
    CRITICAL_SECTION createWindowSection;
};

bool QAxFactory::createObjectWrapper(QObject *object, IDispatch **wrapper)
{
    *wrapper = nullptr;
    QAxServerBase *obj = new QAxServerBase(object);
    obj->QueryInterface(IID_IDispatch, reinterpret_cast<void **>(wrapper));
    if (*wrapper)
        return true;

    delete obj;
    return false;
}


/*
    Helper class to enumerate all supported event interfaces.
*/
class QAxSignalVec : public IEnumConnectionPoints
{
public:
    QAxSignalVec &operator=(const QAxSignalVec &) = delete;
    QAxSignalVec &operator=(QAxSignalVec &&) = delete;
    QAxSignalVec(QAxSignalVec &&) = delete;

    QAxSignalVec(const QAxServerBase::ConnectionPoints &points)
        : cpoints(points.values())
    {
        InitializeCriticalSection(&refCountSection);
        const int count = cpoints.count();
        for (int i = 0; i < count; ++i)
            cpoints.at(i)->AddRef();
    }
    QAxSignalVec(const QAxSignalVec &old)
        : cpoints(old.cpoints)
        , current(old.current)
    {
        InitializeCriticalSection(&refCountSection);
        ref = 0;
        const int count = cpoints.count();
        for (int i = 0; i < count; ++i)
            cpoints.at(i)->AddRef();
    }
    virtual ~QAxSignalVec()
    {
        const int count = cpoints.count();
        for (int i = 0; i < count; ++i)
            cpoints.at(i)->Release();

        DeleteCriticalSection(&refCountSection);
    }

    unsigned long __stdcall AddRef() override
    {
        return InterlockedIncrement(&ref);
    }
    unsigned long __stdcall Release() override
    {
        LONG refCount = InterlockedDecrement(&ref);
        if (!refCount)
            delete this;

        return refCount;
    }
    STDMETHOD(QueryInterface)(REFIID iid, void **iface)
    {
        if (!iface)
            return E_POINTER;
        *iface = nullptr;
        if (iid == IID_IUnknown)
            *iface = this;
        else if (iid == IID_IEnumConnectionPoints)
            *iface = this;
        else
            return E_NOINTERFACE;

        AddRef();
        return S_OK;
    }
    STDMETHOD(Next)(ULONG cConnections, IConnectionPoint **cpoint, ULONG *pcFetched)
    {
        if (!cpoint)
            return E_POINTER;

        if (!pcFetched && cConnections > 1)
            return E_POINTER;

        const int count = cpoints.count();
        unsigned long i;
        for (i = 0; i < cConnections; i++) {
            if (current==count)
                break;
            IConnectionPoint *cp = cpoints.at(current);
            cp->AddRef();
            cpoint[i] = cp;
            ++current;
        }
        if (pcFetched)
            *pcFetched = i;
        return i == cConnections ? S_OK : S_FALSE;
    }
    STDMETHOD(Skip)(ULONG cConnections)
    {
        const int count = cpoints.count();
        while (cConnections) {
            if (current == count)
                return S_FALSE;
            ++current;
            --cConnections;
        }
        return S_OK;
    }
    STDMETHOD(Reset)()
    {
        current = 0;
        return S_OK;
    }
    STDMETHOD(Clone)(IEnumConnectionPoints **ppEnum)
    {
        if (!ppEnum)
            return E_POINTER;
        *ppEnum = new QAxSignalVec(*this);
        (*ppEnum)->AddRef();

        return S_OK;
    }

    QList<IConnectionPoint*> cpoints;
    int current = 0;

private:
    CRITICAL_SECTION refCountSection;

    LONG ref = 0;
};

/*
    Helper class to store and enumerate all connected event listeners.
*/
class QAxConnection : public IConnectionPoint,
                      public IEnumConnections
{
public:
    QAxConnection &operator=(const QAxConnection &) = delete;
    QAxConnection(QAxConnection &&) = delete;
    QAxConnection &operator=(QAxConnection &&) = delete;

    using Connections = QVector<CONNECTDATA>;

    QAxConnection(QAxServerBase *parent, const QUuid &uuid)
        : that(parent), iid(uuid)
    {
        InitializeCriticalSection(&refCountSection);
    }
    QAxConnection(const QAxConnection &old)
        : current(old.current)
    {
        InitializeCriticalSection(&refCountSection);
        ref = 0;
        connections = old.connections;
        that = old.that;
        iid = old.iid;
        for (const CONNECTDATA &connection : qAsConst(connections))
            connection.pUnk->AddRef();
    }
    virtual ~QAxConnection()
    {
        DeleteCriticalSection(&refCountSection);
    }

    unsigned long __stdcall AddRef() override
    {
        return InterlockedIncrement(&ref);
    }
    unsigned long __stdcall Release() override
    {
        LONG refCount = InterlockedDecrement(&ref);
        if (!refCount)
            delete this;

        return refCount;
    }
    STDMETHOD(QueryInterface)(REFIID iid, void **iface)
    {
        if (!iface)
            return E_POINTER;
        *iface = nullptr;
        if (iid == IID_IUnknown)
            *iface = static_cast<IConnectionPoint *>(this);
        else if (iid == IID_IConnectionPoint)
            *iface = this;
        else if (iid == IID_IEnumConnections)
            *iface = this;
        else
            return E_NOINTERFACE;

        AddRef();
        return S_OK;
    }
    STDMETHOD(GetConnectionInterface)(IID *pIID)
    {
        if (!pIID)
            return E_POINTER;
        *pIID = iid;
        return S_OK;
    }
    STDMETHOD(GetConnectionPointContainer)(IConnectionPointContainer **ppCPC)
    {
        return that->QueryInterface(IID_IConnectionPointContainer, reinterpret_cast<void **>(ppCPC));
    }
    STDMETHOD(Advise)(IUnknown*pUnk, DWORD *pdwCookie)
    {
        if (!pUnk || !pdwCookie)
            return E_POINTER;

        {
            IDispatch *checkImpl = nullptr;
            pUnk->QueryInterface(iid, reinterpret_cast<void **>(&checkImpl));
            if (!checkImpl)
                return CONNECT_E_CANNOTCONNECT;
            checkImpl->Release();
        }

        CONNECTDATA cd;
        cd.dwCookie = connections.count()+1;
        cd.pUnk = pUnk;
        cd.pUnk->AddRef();
        connections.append(cd);
        *pdwCookie = cd.dwCookie;
        return S_OK;
    }
    STDMETHOD(Unadvise)(DWORD dwCookie)
    {
        const int count = connections.count();
        for (int i = 0; i < count; ++i) {
            if (connections.at(i).dwCookie == dwCookie) {
                connections.at(i).pUnk->Release();
                connections.removeAt(i);
                if (current >= i && current != 0)
                    --current;
                return S_OK;
            }
        }
        return CONNECT_E_NOCONNECTION;
    }
    STDMETHOD(EnumConnections)(IEnumConnections **ppEnum)
    {
        if (!ppEnum)
            return E_POINTER;
        *ppEnum = this;
        AddRef();

        return S_OK;
    }
    STDMETHOD(Next)(ULONG cConnections, CONNECTDATA *cd, ULONG *pcFetched)
    {
        if (!cd)
            return E_POINTER;

        if (!pcFetched && cConnections > 1)
            return E_POINTER;

        const int count = connections.count();

        unsigned long i;
        for (i = 0; i < cConnections; i++) {
            if (current == count)
                break;
            cd[i] = connections.at(current);
            cd[i].pUnk->AddRef();
            ++current;
        }
        if (pcFetched)
            *pcFetched = i;
        return i == cConnections ? S_OK : S_FALSE;
    }
    STDMETHOD(Skip)(ULONG cConnections)
    {
        const int count = connections.count();
        while (cConnections) {
            if (current == count)
                return S_FALSE;
            ++current;
            --cConnections;
        }
        return S_OK;
    }
    STDMETHOD(Reset)()
    {
        current = 0;
        return S_OK;
    }
    STDMETHOD(Clone)(IEnumConnections **ppEnum)
    {
        if (!ppEnum)
            return E_POINTER;
        *ppEnum = new QAxConnection(*this);
        (*ppEnum)->AddRef();

        return S_OK;
    }

private:
    QAxServerBase *that;
    QUuid iid;
    Connections connections;
    int current = 0;

    CRITICAL_SECTION refCountSection;
    LONG ref = 1;
};

// callback for DLL server to hook into non-Qt eventloop
LRESULT QT_WIN_CALLBACK axs_FilterProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (qApp && !invokeCount)
        QCoreApplication::sendPostedEvents();

    return CallNextHookEx(qax_hhook, nCode, wParam, lParam);
}

// filter for executable case to hook into Qt eventloop
// for DLLs the client calls TranslateAccelerator
class QAxWinEventFilter : public QAbstractNativeEventFilter
{
public:
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    bool nativeEventFilter(const QByteArray &, void *message, qintptr *) override;
#else
    bool nativeEventFilter(const QByteArray &, void *message, long *) override;
#endif
};

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool QAxWinEventFilter::nativeEventFilter(const QByteArray &, void *message, qintptr *)
#else
bool QAxWinEventFilter::nativeEventFilter(const QByteArray &, void *message, long *)
#endif
{
    MSG *pMsg = static_cast<MSG *>(message);
    if (pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST)
        return false;

    bool ret = false;
    QWidget *aqt = QWidget::find(reinterpret_cast<WId>(pMsg->hwnd));
    if (!aqt)
        return ret;

    // FIXME: 4.10.211: was '::GetParent(hwndForWidget(aqt));'
    HWND baseHwnd = hwndForWidget(aqt);
    QAxServerBase *axbase = nullptr;
    while (!axbase && baseHwnd) {
        axbase = axServerBaseFromWindow(baseHwnd);
        baseHwnd = ::GetParent(baseHwnd);
    }
    if (!axbase)
        return ret;

    HRESULT hres = axbase->TranslateAcceleratorW(pMsg);
    return hres == S_OK;
}

Q_GLOBAL_STATIC(QAxWinEventFilter, qax_winEventFilter);

// COM Factory class, mapping COM requests to ActiveQt requests.
// One instance of this class for each ActiveX the server can provide.
QClassFactory::QClassFactory(CLSID clsid)
{
    InitializeCriticalSection(&refCountSection);

    // COM only knows the CLSID, but QAxFactory is class name based...
    const QStringList keys = qAxFactory()->featureList();
    for (const QString &key : keys) {
        if (qAxFactory()->classID(key) == clsid) {
            className = key;
            break;
        }
    }

    const QMetaObject *mo = qAxFactory()->metaObject(className);
    if (mo) {
        classKey = QLatin1String(mo->classInfo(mo->indexOfClassInfo("LicenseKey")).value());
        licensed = !classKey.isEmpty();
    }
}

QClassFactory::~QClassFactory()
{
    DeleteCriticalSection(&refCountSection);
}

// IUnknown
unsigned long QClassFactory::AddRef()
{
    return InterlockedIncrement(&ref);
}

unsigned long QClassFactory::Release()
{
    LONG refCount = InterlockedDecrement(&ref);
    if (!refCount)
        delete this;

    return refCount;
}

HRESULT QClassFactory::QueryInterface(REFIID iid, LPVOID *iface)
{
    *iface = nullptr;
    if (iid == IID_IUnknown)
        *iface = static_cast<IUnknown *>(this);
    else if (iid == IID_IClassFactory)
        *iface = static_cast<IClassFactory *>(this);
    else if (iid == IID_IClassFactory2 && licensed)
        *iface = static_cast<IClassFactory2 *>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

HRESULT QClassFactory::CreateInstanceHelper(IUnknown *pUnkOuter, REFIID iid, void **ppObject)
{
    if (pUnkOuter) {
        if (iid != IID_IUnknown)
            return CLASS_E_NOAGGREGATION;
        const QMetaObject *mo = qAxFactory()->metaObject(className);
        if (mo && !qstricmp(mo->classInfo(mo->indexOfClassInfo("Aggregatable")).value(), "no"))
            return CLASS_E_NOAGGREGATION;
    }

    // Make sure a QApplication instance is present (inprocess case)
    if (!qApp) {
        qax_ownQApp = true;
        static int argc = 0; // static lifetime, since it's passed as reference to QApplication, which has a lifetime exceeding the stack frame
        new QApplication(argc, nullptr);
    }
    QGuiApplication::setQuitOnLastWindowClosed(false);

    if (qAxOutProcServer)
        QAbstractEventDispatcher::instance()->installNativeEventFilter(qax_winEventFilter());
    else
        QApplication::instance()->d_func()->in_exec = true;

    // hook into eventloop; this allows a server to create his own QApplication object
    if (!qax_hhook && qax_ownQApp) {
        qax_hhook = SetWindowsHookEx(WH_GETMESSAGE, axs_FilterProc, nullptr, GetCurrentThreadId());
    }

    // If we created QApplication instance, ensure native event loop starts properly
    // by calling processEvents.
    if (qax_ownQApp)
        QCoreApplication::processEvents();

    HRESULT res;
    // Create the ActiveX wrapper - aggregate if requested
    if (pUnkOuter) {
        QAxServerAggregate *aggregate = new QAxServerAggregate(className, pUnkOuter);
        res = aggregate->QueryInterface(iid, ppObject);
        if (FAILED(res))
            delete aggregate;
    } else {
        QAxServerBase *activeqt = new QAxServerBase(className, pUnkOuter);
        res = activeqt->QueryInterface(iid, ppObject);
        if (FAILED(res))
            delete activeqt;
        else
            activeqt->registerActiveObject(static_cast<IUnknown*>(static_cast<IDispatch*>(activeqt)));
    }
    return res;
}

// IClassFactory
HRESULT QClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppObject)
{
    // class is licensed
    if (licensed && !qAxFactory()->validateLicenseKey(className, QString()))
        return CLASS_E_NOTLICENSED;

    return CreateInstanceHelper(pUnkOuter, iid, ppObject);
}

HRESULT QClassFactory::LockServer(BOOL fLock)
{
    if (fLock)
        qAxLock();
    else
        qAxUnlock();

    return S_OK;
}

// IClassFactory2
HRESULT QClassFactory::RequestLicKey(DWORD, BSTR *pKey)
{
    if (!pKey)
        return E_POINTER;
    *pKey = nullptr;

    // This of course works only on fully licensed machines
    if (!qAxFactory()->validateLicenseKey(className, QString()))
        return CLASS_E_NOTLICENSED;

    *pKey = QStringToBSTR(classKey);
    return S_OK;
}

HRESULT QClassFactory::GetLicInfo(LICINFO *pLicInfo)
{
    if (!pLicInfo)
        return E_POINTER;
    pLicInfo->cbLicInfo = sizeof(LICINFO);

    // class specific license key?
    const QMetaObject *mo = qAxFactory()->metaObject(className);
    const char *key = mo->classInfo(mo->indexOfClassInfo("LicenseKey")).value();
    pLicInfo->fRuntimeKeyAvail = key && key[0];

    // machine fully licensed?
    pLicInfo->fLicVerified = qAxFactory()->validateLicenseKey(className, QString());

    return S_OK;
}

HRESULT QClassFactory::CreateInstanceLic(IUnknown *pUnkOuter, IUnknown * /* pUnkReserved */, REFIID iid, BSTR bKey, PVOID *ppObject)
{
    QString licenseKey = QString::fromWCharArray(bKey);
    if (!qAxFactory()->validateLicenseKey(className, licenseKey))
        return CLASS_E_NOTLICENSED;
    return CreateInstanceHelper(pUnkOuter, iid, ppObject);
}

void QClassFactory::cleanupCreatedApplication(QCoreApplication &app)
{
    // Cleanup similar to QCoreApplication::exec()
    app.d_func()->execCleanup();
}


// Create a QClassFactory object for class \a iid
HRESULT GetClassObject(REFIID clsid, REFIID iid, void **ppUnk)
{
    QClassFactory *factory = new QClassFactory(clsid);
    if (!factory)
        return E_OUTOFMEMORY;
    if (factory->className.isEmpty()) {
        delete factory;
        return E_NOINTERFACE;
    }
    HRESULT res = factory->QueryInterface(iid, ppUnk);
    if (res != S_OK)
        delete factory;
    return res;
}


/*! \internal
    Constructs a QAxServerBase object wrapping the QWidget \a
    classname into an ActiveX control.

    The constructor is called by the QClassFactory object provided by
    the COM server for the respective CLSID.
*/
QAxServerBase::QAxServerBase(const QString &classname, IUnknown *outerUnknown)
    : class_name(classname), m_outerUnknown(outerUnknown)
{
    init();

    internalCreate();
}

/*! \internal
    Constructs a QAxServerBase object wrapping \a o.
*/
QAxServerBase::QAxServerBase(QObject *o)
{
    init();

    qt.object = o;
    if (o) {
        theObject = o;
        isWidget = false;
        class_name = QLatin1String(o->metaObject()->className());
    }
    internalBind();
    internalConnect();
}

/*! \internal
    Initializes data members.
*/
void QAxServerBase::init()
{
    qt.object = nullptr;
    isWidget            = false;
    ownObject           = false;
    initNewCalled       = false;
    dirtyflag           = false;
    hasStockEvents      = false;
    stayTopLevel        = false;
    isInPlaceActive     = false;
    isUIActive          = false;
    wasUIActive         = false;
    inDesignMode        = false;
    canTakeFocus        = false;

    InitializeCriticalSection(&refCountSection);
    InitializeCriticalSection(&createWindowSection);

#ifdef QT_DEBUG
    EnterCriticalSection(&refCountSection);
    ++qaxserverbase_instance_count;
    LeaveCriticalSection(&refCountSection);
#endif

    qAxLock();

    points[IID_IPropertyNotifySink] = new QAxConnection(this, IID_IPropertyNotifySink);
}

/*! \internal
    Destroys the QAxServerBase object, releasing all allocated
    resources and interfaces.
*/
QAxServerBase::~QAxServerBase()
{
#ifdef QT_DEBUG
    EnterCriticalSection(&refCountSection);
    --qaxserverbase_instance_count;
    LeaveCriticalSection(&refCountSection);
#endif

    revokeActiveObject();
    for (auto it = points.cbegin(), end = points.cend(); it != end; ++it) {
        if (IConnectionPoint *point = it.value())
            point->Release();
    }
    delete aggregatedObject;
    aggregatedObject = nullptr;
    if (theObject) {
        qt.object->disconnect(this);
        QObject *aqt = qt.object;
        qt.object = nullptr;
        if (ownObject)
            delete aqt;
    }

    if (m_spAdviseSink) m_spAdviseSink->Release();
    m_spAdviseSink = nullptr;
    for (int i = 0; i < adviseSinks.count(); ++i) {
        adviseSinks.at(i).pAdvSink->Release();
    }
    if (m_spClientSite) m_spClientSite->Release();
    m_spClientSite = nullptr;
    if (m_spInPlaceFrame) m_spInPlaceFrame->Release();
    m_spInPlaceFrame = nullptr;
    if (m_spInPlaceSiteWindowless)
        m_spInPlaceSiteWindowless->Release();
    m_spInPlaceSiteWindowless = nullptr;
    if (m_spInPlaceSite) m_spInPlaceSite->Release();
    m_spInPlaceSite = nullptr;
    if (m_spTypeInfo) m_spTypeInfo->Release();
    m_spTypeInfo = nullptr;
    if (m_spStorage) m_spStorage->Release();
    m_spStorage = nullptr;

    DeleteCriticalSection(&refCountSection);
    DeleteCriticalSection(&createWindowSection);

    qAxUnlock();
}

/*  \internal
    Registering with OLE
*/
void QAxServerBase::registerActiveObject(IUnknown *object)
{
    if (ole_ref || !qt.object || !qAxOutProcServer)
        return;

    const QMetaObject *mo = qt.object->metaObject();
    if (!qstricmp(mo->classInfo(mo->indexOfClassInfo("RegisterObject")).value(), "yes"))
        RegisterActiveObject(object, qAxFactory()->classID(class_name), ACTIVEOBJECT_WEAK, &ole_ref);
}

void QAxServerBase::revokeActiveObject()
{
    if (!ole_ref)
        return;

    RevokeActiveObject(ole_ref, nullptr);
    ole_ref = 0;
}

/* \internal
    QueryInterface implementation.
*/
HRESULT WINAPI QAxServerBase::QueryInterface(REFIID iid, void **iface)
{
    if (m_outerUnknown)
        return m_outerUnknown->QueryInterface(iid, iface);

    return InternalQueryInterface(iid, iface);
}

HRESULT QAxServerBase::InternalQueryInterface(REFIID iid, void **iface)
{
    *iface = nullptr;

    if (iid == IID_IUnknown) {
        *iface = static_cast<IUnknown *>(static_cast<IDispatch *>(this));
    } else {
        HRESULT res = S_OK;
        if (aggregatedObject)
            res = aggregatedObject->queryInterface(iid, iface);
        if (*iface)
            return res;
    }

    if (!(*iface)) {
        if (iid == qAxFactory()->interfaceID(class_name))
            *iface = static_cast<IDispatch *>(this);
        if (iid == IID_IDispatch)
            *iface = static_cast<IDispatch *>(this);
        else if (iid == IID_IAxServerBase)
            *iface = static_cast<IAxServerBase *>(this);
        else if (iid == IID_IOleObject)
            *iface = static_cast<IOleObject *>(this);
        else if (iid == IID_IConnectionPointContainer)
            *iface = static_cast<IConnectionPointContainer *>(this);
        else if (iid == IID_IProvideClassInfo)
            *iface = static_cast<IProvideClassInfo *>(this);
        else if (iid == IID_IProvideClassInfo2)
            *iface = static_cast<IProvideClassInfo2 *>(this);
        else if (iid == IID_IPersist)
            *iface = static_cast<IPersist *>(static_cast<IPersistStream *>(this));
        else if (iid == IID_IPersistStream)
            *iface = static_cast<IPersistStream *>(this);
        else if (iid == IID_IPersistStreamInit)
            *iface = static_cast<IPersistStreamInit *>(this);
        else if (iid == IID_IPersistStorage)
            *iface = static_cast<IPersistStorage *>(this);
        else if (iid == IID_IPersistPropertyBag)
            *iface = static_cast<IPersistPropertyBag *>(this);
        else if (iid == IID_IPersistFile &&
            qAxFactory()->metaObject(class_name)->indexOfClassInfo("MIME") != -1)
            *iface = static_cast<IPersistFile *>(this);
        else if (iid == IID_IViewObject)
            *iface = static_cast<IViewObject *>(this);
        else if (iid == IID_IViewObject2)
            *iface = static_cast<IViewObject2 *>(this);
        else if (isWidget) {
            if (iid == IID_IOleControl)
                *iface = static_cast<IOleControl *>(this);
            else if (iid == IID_IOleWindow)
                *iface = static_cast<IOleWindow *>(static_cast<IOleInPlaceObject *>(this));
            else if (iid == IID_IOleInPlaceObject)
                *iface = static_cast<IOleInPlaceObject *>(this);
            else if (iid == IID_IOleInPlaceActiveObject)
                *iface = static_cast<IOleInPlaceActiveObject *>(this);
            else if (iid == IID_IDataObject)
                *iface = static_cast<IDataObject *>(this);
        }
    }
    if (!*iface)
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

/*! \internal
    Detects and initilaizes implementation of QAxBindable in objects.
*/
void QAxServerBase::internalBind()
{
    QAxBindable *axb = static_cast<QAxBindable *>(qt.object->qt_metacast("QAxBindable"));
    if (axb) {
        // no addref; this is aggregated
        axb->activex = this;
        if (!aggregatedObject)
            aggregatedObject = axb->createAggregate();
        if (aggregatedObject) {
            aggregatedObject->controlling_unknown = static_cast<IUnknown *>(static_cast<IDispatch *>(this));
            aggregatedObject->the_object = qt.object;
        }
    }
}

/*! \internal
    Connects object signals to event dispatcher.
*/
void QAxServerBase::internalConnect()
{
    QUuid eventsID = qAxFactory()->eventsID(class_name);
    if (!eventsID.isNull()) {
        if (!points[eventsID])
            points[eventsID] = new QAxConnection(this, eventsID);

        // connect the generic slot to all signals of qt.object
        const QMetaObject *mo = qt.object->metaObject();
        for (int isignal = mo->methodCount()-1; isignal >= 0; --isignal) {
            if (mo->method(isignal).methodType() == QMetaMethod::Signal)
                QMetaObject::connect(qt.object, isignal, this, isignal);
        }
    }
}

/*! \internal
    Creates the QWidget for the classname passed to the c'tor.

    All signals of the widget class are connected to the internal event mapper.
    If the widget implements QAxBindable, stock events are also connected.
*/
bool QAxServerBase::internalCreate()
{
    if (qt.object)
        return true;

    qt.object = qAxFactory()->createObject(class_name);
    Q_ASSERT(qt.object);
    if (!qt.object)
        return false;

    theObject = qt.object;
    ownObject = true;
    isWidget = qt.object->isWidgetType();
    hasStockEvents = qAxFactory()->hasStockEvents(class_name);
    stayTopLevel = qAxFactory()->stayTopLevel(class_name);

    internalBind();
    if (isWidget) {
        if (!stayTopLevel) {
            QEvent e(QEvent::EmbeddingControl);
            QCoreApplication::sendEvent(qt.widget, &e);
        }
        qt.widget->setAttribute(Qt::WA_QuitOnClose, false);
        qt.widget->move(0, 0);

        // initialize to sizeHint, but don't set resized flag so that container has a chance to override
        bool wasResized = qt.widget->testAttribute(Qt::WA_Resized);
        updateGeometry();
        if (!wasResized && qt.widget->testAttribute(Qt::WA_Resized)
            && qt.widget->sizePolicy() != QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)) {
            qt.widget->setAttribute(Qt::WA_Resized, false);
        }
    }

    internalConnect();
    // install an event filter for stock events
    if (isWidget) {
        qt.object->installEventFilter(this);
        const QWidgetList children = qt.object->findChildren<QWidget*>();
        for (QWidget *child : children)
            child->installEventFilter(this);
    }
    return true;
}

/*
class HackMenuData : public QMenuData
{
    friend class QAxServerBase;
};
*/

class HackWidget : public QWidget
{
    friend class QAxServerBase;
};
/*
    Message handler. \a hWnd is always the ActiveX widget hosting the Qt widget.
    \a uMsg is handled as follows
    \list
    \li WM_CREATE The ActiveX control is created
    \li WM_DESTROY The QWidget is destroyed
    \li WM_SHOWWINDOW The QWidget is parented into the ActiveX window
    \li WM_PAINT The QWidget is updated
    \li WM_SIZE The QWidget is resized to the new size
    \li WM_SETFOCUS and
    \li WM_KILLFOCUS The client site is notified about the focus transfer
    \li WM_MOUSEACTIVATE The ActiveX is activated
    \endlist

    The semantics of \a wParam and \a lParam depend on the value of \a uMsg.
*/
LRESULT QT_WIN_CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_CREATE) {
        CREATESTRUCT *cs = reinterpret_cast<CREATESTRUCT *>(lParam);
        QAxServerBase *that = static_cast<QAxServerBase *>(cs->lpCreateParams);

#ifdef GWLP_USERDATA
        SetWindowLongPtr(hWnd, GWLP_USERDATA, LONG_PTR(that));
#else
        SetWindowLong(hWnd, GWL_USERDATA, LONG(that));
#endif

        that->m_hWnd = hWnd;

        return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
    }

    switch (uMsg) {
    case WM_NCDESTROY:
        if (QAxServerBase *that = axServerBaseFromWindow(hWnd))
            that->m_hWnd = nullptr;
        break;

    case WM_QUERYENDSESSION:
    case WM_DESTROY:
        if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) {
            if (that->qt.widget) {
                that->qt.widget->hide();
                if (QWindow *widgetWindow = that->qt.widget->windowHandle()) {
                    if (HWND h = reinterpret_cast<HWND>(widgetWindow->winId()))
                        ::SetParent(h, nullptr);
                }
            }
        }
        break;

    case WM_SHOWWINDOW:
        if (wParam) {
            if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) {
                that->internalCreate();
                if (!that->stayTopLevel) {
                    // Set this property on window to pass the native handle to platform plugin,
                    // so that it can create the window with proper flags instead of thinking
                    // it is toplevel.
                    that->qt.widget->setProperty("_q_embedded_native_parent_handle", WId(that->m_hWnd));

                    if (QWindow *widgetWindow = that->qt.widget->windowHandle()) {
                        // If embedded widget is native, such as QGLWidget, it may have already created
                        // a window before now, probably as an undesired toplevel. In that case set the
                        // proper parent window and set the window frameless to position it correctly.
                        if (that->qt.widget->testAttribute(Qt::WA_WState_Created)
                            && !that->qt.widget->isVisible()) {
                            HWND h = static_cast<HWND>(QGuiApplication::platformNativeInterface()->
                                                       nativeResourceForWindow("handle", widgetWindow));
                            if (h) {
                                ::SetParent(h, that->m_hWnd);
                                // Since the window is already created, we need to set the
                                // property directly to ensure it does not believe it is
                                // toplevel.
                                widgetWindow->setProperty("_q_embedded_native_parent_handle",
                                                          WId(that->m_hWnd));
                            }
                            Qt::WindowFlags flags = widgetWindow->flags();
                            widgetWindow->setFlags(flags | Qt::FramelessWindowHint);
                        }
                    }
                    that->qt.widget->raise();
                    that->qt.widget->move(0, 0);
                }
                that->qt.widget->show();
            } else if (that->qt.widget) {
                that->qt.widget->hide();
            }
        }
        break;

    case WM_ERASEBKGND:
        if (QAxServerBase *that = axServerBaseFromWindow(hWnd))
            that->updateMask();
        break;

    case WM_SIZE:
        if (QAxServerBase *that = axServerBaseFromWindow(hWnd))
            that->resize(qaxFromNativeSize(that->qt.widget, QSize(LOWORD(lParam), HIWORD(lParam))));
        break;

    case WM_SETFOCUS:
        if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) {
            if (that->isInPlaceActive && that->m_spClientSite && !that->inDesignMode && that->canTakeFocus) {
                RECT rcPos = that->rcPosRect();
                that->DoVerb(OLEIVERB_UIACTIVATE, nullptr, that->m_spClientSite, 0, that->m_hWnd, &rcPos);
                if (that->isUIActive) {
                    IOleControlSite *spSite = nullptr;
                    that->m_spClientSite->QueryInterface(IID_IOleControlSite, reinterpret_cast<void **>(&spSite));
                    if (spSite) {
                        spSite->OnFocus(true);
                        spSite->Release();
                    }
                    QWidget *candidate = that->qt.widget;
                    while (!(candidate->focusPolicy() & Qt::TabFocus)) {
                        candidate = candidate->nextInFocusChain();
                        if (candidate == that->qt.widget) {
                            candidate = nullptr;
                            break;
                        }
                    }
                    if (candidate) {
                        candidate->setFocus();
                        if (::GetKeyState(VK_SHIFT) < 0)
                            static_cast<HackWidget *>(that->qt.widget)->focusNextPrevChild(false);
                    }
                }
            }
        }
        break;

    case WM_KILLFOCUS:
        if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) {
            if (that->isInPlaceActive && that->isUIActive && that->m_spClientSite) {
                IOleControlSite *spSite = nullptr;
                that->m_spClientSite->QueryInterface(IID_IOleControlSite, reinterpret_cast<void **>(&spSite));
                if (spSite) {
                    if (!::IsChild(that->m_hWnd, ::GetFocus()))
                        spSite->OnFocus(false);
                    spSite->Release();
                }
            }
        }
        break;

    case WM_MOUSEACTIVATE:
        if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) {
            RECT rcPos = that->rcPosRect();
            that->DoVerb(OLEIVERB_UIACTIVATE, nullptr, that->m_spClientSite, 0, that->m_hWnd, &rcPos);
        }
        break;

    case WM_INITMENUPOPUP:
        if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) {
            if (that->qt.widget) {
                that->currentPopup = that->menuMap[reinterpret_cast<HMENU>(wParam)];
                if (!that->currentPopup)
                    break;
                const QMetaObject *mo = that->currentPopup->metaObject();
                int index = mo->indexOfSignal("aboutToShow()");
                if (index < 0)
                    break;

                that->currentPopup->qt_metacall(QMetaObject::InvokeMetaMethod, index, nullptr);
                that->createPopup(that->currentPopup, reinterpret_cast<HMENU>(wParam));
                return 0;
            }
        }
        break;

    case WM_MENUSELECT:
    case WM_COMMAND:
        if (QAxServerBase *that = axServerBaseFromWindow(hWnd)) {
            if (that->qt.widget) {
                QMenuBar *menuBar = that->menuBar;
                if (!menuBar)
                    break;

                QObject *menuObject = nullptr;
                bool menuClosed = false;

                if (uMsg == WM_COMMAND) {
                    menuObject = that->actionMap.value(UINT(wParam));
                } else if (!lParam) {
                    menuClosed = true;
                    menuObject = that->currentPopup;
                } else {
                    menuObject = that->actionMap.value(LOWORD(wParam));
                }

                if (menuObject) {
                    const QMetaObject *mo = menuObject->metaObject();
                    int index = -1;

                    if (uMsg == WM_COMMAND)
                        index = mo->indexOfSignal("activated()");
                    else if (menuClosed)
                        index = mo->indexOfSignal("aboutToHide()");
                    else
                        index = mo->indexOfSignal("hovered()");

                    if (index < 0)
                        break;

                    menuObject->qt_metacall(QMetaObject::InvokeMetaMethod, index, nullptr);
                    if (menuClosed || uMsg == WM_COMMAND)
                        that->currentPopup = nullptr;
                    return 0;
                }
            }
        }
        break;

    case WM_DISPLAYCHANGE:
        qaxClearCachedSystemLogicalDpi();
        break;

    default:
        break;
    }

    return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}

/*! \internal
    Creates the window hosting the QWidget.
*/
HWND QAxServerBase::create(HWND hWndParent, RECT& rcPos)
{
    Q_ASSERT(isWidget && qt.widget);

    static ATOM atom = 0;
    HINSTANCE hInst = reinterpret_cast<HINSTANCE>(qAxInstance);
    EnterCriticalSection(&createWindowSection);
    QString cn(QLatin1String("QAxControl"));
    cn += QString::number(quintptr(ActiveXProc));
    if (!atom) {
        WNDCLASS wcTemp;
        wcTemp.style = CS_DBLCLKS;
        wcTemp.cbClsExtra = 0;
        wcTemp.cbWndExtra = 0;
        wcTemp.hbrBackground = nullptr;
        wcTemp.hCursor = nullptr;
        wcTemp.hIcon = nullptr;
        wcTemp.hInstance = hInst;
        wcTemp.lpszClassName = reinterpret_cast<const wchar_t *>(cn.utf16());
        wcTemp.lpszMenuName = nullptr;
        wcTemp.lpfnWndProc = ActiveXProc;

        atom = RegisterClass(&wcTemp);
    }
    LeaveCriticalSection(&createWindowSection);
    if (!atom) {
        const DWORD errorCode = GetLastError();
        if (errorCode != ERROR_CLASS_ALREADY_EXISTS) {
            qErrnoWarning(int(errorCode), "%s: RegisterClass() failed", __FUNCTION__);
            return nullptr;
        }
    }

    Q_ASSERT(!m_hWnd);
    // will fail if parent window belongs to a higher integrity level process
    HWND hWnd = ::CreateWindow(reinterpret_cast<const wchar_t *>(cn.utf16()), nullptr,
                               WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
                               rcPos.left, rcPos.top, rcPos.right - rcPos.left,
                               rcPos.bottom - rcPos.top, hWndParent, nullptr, hInst, this);
    // m_hWnd is assigned in reponse to WM_CREATE
    if (!hWnd) {
        DWORD err = GetLastError();
        if (err == ERROR_ACCESS_DENIED) {
            // retry without parent window
            // the window will now need to be re-parented in the container process
            hWnd = ::CreateWindow(reinterpret_cast<const wchar_t *>(cn.utf16()), nullptr,
                                  WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
                                  rcPos.left, rcPos.top, rcPos.right - rcPos.left,
                                  rcPos.bottom - rcPos.top, nullptr, nullptr, hInst, this);
        }
    }

    if (!hWnd) {
        qErrnoWarning("%s: CreateWindow() failed", __FUNCTION__);
        return nullptr;
    }

    Q_ASSERT(m_hWnd == hWnd);

    updateMask();
    EnableWindow(m_hWnd, qt.widget->isEnabled());

    return hWnd;
}

/* \internal
    Recoursively creates Win32 submenus.
*/
HMENU QAxServerBase::createPopup(QMenu *popup, HMENU oldMenu)
{
    HMENU popupMenu = oldMenu ? oldMenu : CreatePopupMenu();
    menuMap.insert(popupMenu, popup);

    if (oldMenu) while (GetMenuItemCount(oldMenu)) {
        DeleteMenu(oldMenu, 0, MF_BYPOSITION);
    }

    const auto actions = popup->actions();
    for (QAction *action : actions) {
        uint flags = action->isEnabled() ? MF_ENABLED : MF_GRAYED;
        if (action->isSeparator())
            flags |= MF_SEPARATOR;
        else if (action->menu())
            flags |= MF_POPUP;
        else
            flags |= MF_STRING;
        if (action->isChecked())
            flags |= MF_CHECKED;

        ushort itemId;
        if (flags & MF_POPUP) {
            itemId = static_cast<ushort>(
                reinterpret_cast<quintptr>(createPopup(action->menu()))
            );
        } else {
            itemId = static_cast<ushort>(reinterpret_cast<quintptr>(action));
            actionMap.remove(itemId);
            actionMap.insert(itemId, action);
        }
        AppendMenu(popupMenu, flags, itemId, reinterpret_cast<const wchar_t *>(action->text().utf16()));
    }
    if (oldMenu)
        DrawMenuBar(hwndMenuOwner);
    return popupMenu;
}

/*! \internal
    Creates a Win32 menubar.
*/
void QAxServerBase::createMenu(QMenuBar *menuBar)
{
    hmenuShared = ::CreateMenu();

    int edit = 0;
    int object = 0;
    int help = 0;

    const auto actions = menuBar->actions();
    for (QAction *action : actions) {
        uint flags = action->isEnabled() ? MF_ENABLED : MF_GRAYED;
        if (action->isSeparator())
            flags |= MF_SEPARATOR;
        else if (action->menu())
            flags |= MF_POPUP;
        else
            flags |= MF_STRING;

        if (action->text() == QCoreApplication::translate(qt.widget->metaObject()->className(), "&Edit"))
            edit++;
        else if (action->text() == QCoreApplication::translate(qt.widget->metaObject()->className(), "&Help"))
            help++;
        else
            object++;

        ushort itemId;
        if (flags & MF_POPUP) {
            itemId = static_cast<ushort>(
                reinterpret_cast<quintptr>(createPopup(action->menu()))
            );
        } else {
            itemId = static_cast<ushort>(reinterpret_cast<quintptr>(action));
            actionMap.insert(itemId, action);
        }
        AppendMenu(hmenuShared, flags, itemId, reinterpret_cast<const wchar_t *>(action->text().utf16()));
    }

    OLEMENUGROUPWIDTHS menuWidths = { { 0,edit,0,object,0,help } };
    HRESULT hres = m_spInPlaceFrame->InsertMenus(hmenuShared, &menuWidths);
    if (FAILED(hres)) {
        ::DestroyMenu(hmenuShared);
        hmenuShared = nullptr;
        return;
    }

    m_spInPlaceFrame->GetWindow(&hwndMenuOwner);

    holemenu = OleCreateMenuDescriptor(hmenuShared, &menuWidths);
    hres = m_spInPlaceFrame->SetMenu(hmenuShared, holemenu, m_hWnd);
    if (FAILED(hres)) {
        ::DestroyMenu(hmenuShared);
        hmenuShared = nullptr;
        OleDestroyMenuDescriptor(holemenu);
    }
}

/*! \internal
    Remove the Win32 menubar.
*/
void QAxServerBase::removeMenu()
{
    if (hmenuShared)
        m_spInPlaceFrame->RemoveMenus(hmenuShared);
    holemenu = nullptr;
    m_spInPlaceFrame->SetMenu(nullptr, nullptr, m_hWnd);
    if (hmenuShared) {
        DestroyMenu(hmenuShared);
        hmenuShared = nullptr;
        menuMap.clear();
    }
    hwndMenuOwner = nullptr;
}

extern bool ignoreSlots(const char *test);
extern bool ignoreProps(const char *test);

/*! \internal
    Makes sure the type info is loaded
*/
void QAxServerBase::ensureMetaData()
{
    if (!m_spTypeInfo) {
        qAxTypeLibrary->GetTypeInfoOfGuid(qAxFactory()->interfaceID(class_name), &m_spTypeInfo);
        m_spTypeInfo->AddRef();
    }
}

/*!
    \internal
    Returns true if the property \a index is exposed to COM and should
    be saved/loaded.
*/
bool QAxServerBase::isPropertyExposed(int index)
{
    if (!theObject)
        return false;

    bool result = false;
    const QMetaObject *mo = theObject->metaObject();

    int qtProps = 0;
    if (theObject->isWidgetType())
        qtProps = QWidget::staticMetaObject.propertyCount();
    QMetaProperty property = mo->property(index);
    if (index <= qtProps && ignoreProps(property.name()))
        return result;

    BSTR bstrNames = QStringToBSTR(QLatin1String(property.name()));
    DISPID dispId;
    GetIDsOfNames(IID_NULL, &bstrNames, 1, LOCALE_USER_DEFAULT, &dispId);
    result = dispId != DISPID_UNKNOWN;
    SysFreeString(bstrNames);

    return result;
}


/*!
    \internal
    Updates the view, or asks the client site to do so.
*/
void QAxServerBase::update()
{
    if (isInPlaceActive) {
        if (m_hWnd)
            ::InvalidateRect(m_hWnd, nullptr, true);
        else if (m_spInPlaceSiteWindowless)
            m_spInPlaceSiteWindowless->InvalidateRect(nullptr, true);
    } else if (m_spAdviseSink) {
        m_spAdviseSink->OnViewChange(DVASPECT_CONTENT, -1);
        for (int i = 0; i < adviseSinks.count(); ++i) {
            adviseSinks.at(i).pAdvSink->OnViewChange(DVASPECT_CONTENT, -1);
        }
    }
}

/*! \internal
    Resizes the control, faking a QResizeEvent if required
*/
void QAxServerBase::resize(const QSize &size)
{
    if (!isWidget || !qt.widget || !size.isValid() || size == QSize(0, 0))
        return;

    QSize oldSize = qt.widget->size();
    qt.widget->resize(size);
    QSize newSize = qt.widget->size();
    // make sure we get a resize event even if not embedded as a control
    if (!m_hWnd && !qt.widget->isVisible() && newSize != oldSize) {
        QResizeEvent resizeEvent(newSize, oldSize);
#ifndef QT_SHARED // import from static library
        extern bool qt_sendSpontaneousEvent(QObject*,QEvent*);
#endif
        qt_sendSpontaneousEvent(qt.widget, &resizeEvent);
    }
    m_currentExtent = qt.widget->size();
}

/*!
    \internal

    Updates the internal size values.
*/
void QAxServerBase::updateGeometry()
{
    if (!isWidget || !qt.widget)
        return;

    const QSize sizeHint = qt.widget->sizeHint();
    const QSize size = qt.widget->size();
    if (sizeHint.isValid()) { // if provided, adjust to sizeHint
        QSize newSize = size;
        if (!qt.widget->testAttribute(Qt::WA_Resized)) {
            newSize = sizeHint;
        } else { // according to sizePolicy rules if already resized
            QSizePolicy sizePolicy = qt.widget->sizePolicy();
            if (sizeHint.width() > size.width() && !(sizePolicy.horizontalPolicy() & QSizePolicy::ShrinkFlag))
                newSize.setWidth(sizeHint.width());
            if (sizeHint.width() < size.width() && !(sizePolicy.horizontalPolicy() & QSizePolicy::GrowFlag))
                newSize.setWidth(sizeHint.width());
            if (sizeHint.height() > size.height() && !(sizePolicy.verticalPolicy() & QSizePolicy::ShrinkFlag))
                newSize.setHeight(sizeHint.height());
            if (sizeHint.height() < size.height() && !(sizePolicy.verticalPolicy() & QSizePolicy::GrowFlag))
                newSize.setHeight(sizeHint.height());
        }
        resize(newSize);

    // set an initial size suitable for embedded controls
    } else if (!qt.widget->testAttribute(Qt::WA_Resized)) {
        resize(QSize(100, 100));
        qt.widget->setAttribute(Qt::WA_Resized, false);
    }
}

/*!
    \internal

    Updates the mask of the widget parent.
*/
void QAxServerBase::updateMask()
{
    if (!isWidget || !qt.widget || qt.widget->mask().isEmpty())
        return;

    QRegion rgn = qt.widget->mask();
    HRGN hrgn = qaxHrgnFromQRegion(rgn, qt.widget);

    // Since SetWindowRegion takes ownership
    HRGN wr = CreateRectRgn(0,0,0,0);
    CombineRgn(wr, hrgn, nullptr, RGN_COPY);
    SetWindowRgn(m_hWnd, wr, true);
    DeleteObject(hrgn);
}

static inline QByteArray paramType(const QByteArray &ptype, bool *out)
{
    *out = ptype.endsWith('&') || ptype.endsWith("**");
    if (*out) {
        QByteArray res(ptype);
        res.truncate(res.length() - 1);
        return res;
    }

    return ptype;
}

/*! \internal
    Catches all signals emitted by the Qt widget and fires the respective COM event.

    \a isignal is the Qt Meta Object index of the received signal, and \a _o the
    signal parameters.
*/
int QAxServerBase::qt_metacall(QMetaObject::Call call, int index, void **argv)
{
    Q_UNUSED(call);
    Q_ASSERT(call == QMetaObject::InvokeMetaMethod);

    if (index == STATUSBAR_MESSAGE_CHANGED_SLOT_INDEX) {
        if (sender() && m_spInPlaceFrame) {
            if (qobject_cast<QStatusBar*>(sender()) != statusBar)
                return true;

            if (statusBar->isHidden()) {
                QString message = *static_cast<const QString *>(argv[1]);
                m_spInPlaceFrame->SetStatusText(QStringToBSTR(message));
            }
        }
        return true;
    }

    if (freezeEvents || inDesignMode)
        return true;

    ensureMetaData();

    // get the signal information.
    const QMetaObject *mo = qt.object->metaObject();
    QMetaMethod signal;
    DISPID eventId = index;
    int pcount = 0;
    QByteArray type;
    QByteArrayList ptypes;

    switch(index) {
    case DISPID_KEYDOWN:
    case DISPID_KEYUP:
        pcount = 2;
        ptypes << "int&" << "int";
        break;
    case DISPID_KEYPRESS:
        pcount = 1;
        ptypes << "int&";
        break;
    case DISPID_MOUSEDOWN:
    case DISPID_MOUSEMOVE:
    case DISPID_MOUSEUP:
        pcount = 4;
        ptypes << "int" << "int" << "int" << "int";
        break;
    case DISPID_CLICK:
        pcount = 0;
        break;
    case DISPID_DBLCLICK:
        pcount = 0;
        break;
    default:
        {
            signal = mo->method(index);
            Q_ASSERT(signal.methodType() == QMetaMethod::Signal);
            type = signal.typeName();
            QByteArray signature(signal.methodSignature());
            QByteArray name(signature);
            name.truncate(name.indexOf('('));

            eventId = signalCache.value(index, -1);
            if (eventId == -1) {
                ITypeInfo *eventInfo = nullptr;
                qAxTypeLibrary->GetTypeInfoOfGuid(qAxFactory()->eventsID(class_name), &eventInfo);
                if (eventInfo) {
                    QString uni_name = QLatin1String(name);
                    OLECHAR *olename = reinterpret_cast<OLECHAR *>(const_cast<ushort *>(uni_name.utf16()));
                    eventInfo->GetIDsOfNames(&olename, 1, &eventId);
                    eventInfo->Release();
                }
            }

            signature.remove(0, name.length() + 1);
            signature.truncate(signature.length() - 1);

            if (!signature.isEmpty())
                ptypes = signature.split(',');

            pcount = ptypes.count();
        }
        break;
    }
    if (pcount && !argv) {
        qWarning("QAxServerBase::qt_metacall: Missing %d arguments", pcount);
        return false;
    }
    if (eventId == -1)
        return false;

    // For all connected event sinks...
    IConnectionPoint *cpoint = nullptr;
    GUID IID_QAxEvents = qAxFactory()->eventsID(class_name);
    FindConnectionPoint(IID_QAxEvents, &cpoint);
    if (cpoint) {
        IEnumConnections *clist = nullptr;
        cpoint->EnumConnections(&clist);
        if (clist) {
            clist->Reset();
            ULONG cc = 1;
            CONNECTDATA c[1];
            clist->Next(cc, reinterpret_cast<CONNECTDATA *>(&c), &cc);
            if (cc) {
                // setup parameters
                unsigned int argErr = 0;
                DISPPARAMS dispParams;
                dispParams.cArgs = UINT(pcount);
                dispParams.cNamedArgs = 0;
                dispParams.rgdispidNamedArgs = nullptr;
                dispParams.rgvarg = nullptr;

                if (pcount) // Use malloc/free for eval package compatibility
                    dispParams.rgvarg = static_cast<VARIANTARG *>(malloc(size_t(pcount) * sizeof(VARIANTARG)));
                int p = 0;
                for (p = 0; p < pcount; ++p) {
                    VARIANT *arg = dispParams.rgvarg + (pcount - p - 1);
                    VariantInit(arg);

                    bool out;
                    QByteArray ptype = paramType(ptypes.at(p), &out);
                    QVariant variant;
                    if (mo->indexOfEnumerator(ptype) != -1) {
                        // convert enum values to int
                        variant = QVariant(*reinterpret_cast<int *>(argv[p+1]));
                    } else {
                        QVariant::Type vt = QVariant::nameToType(ptype);
                        if (vt == QVariant::UserType) {
                            if (ptype.endsWith('*')) {
                                variant = QVariant(QMetaType::type(ptype), reinterpret_cast<void **>(argv[p+1]));
                                // variant.setValue(*(void**)(argv[p + 1]), ptype);
                            } else {
                                variant = QVariant(QMetaType::type(ptype), argv[p+1]);
                                // variant.setValue(argv[p + 1], ptype);
                            }
                        } else {
                            variant = QVariant(vt, argv[p + 1]);
                        }
                    }

                    QVariantToVARIANT(variant, *arg, ptype, out);
                }

                VARIANT retval;
                VariantInit(&retval);
                VARIANT *pretval = nullptr;
                if (!type.isEmpty() && type != "void")
                    pretval = &retval;

                // call listeners (through IDispatch)
                while (cc) {
                    if (c->pUnk) {
                        IDispatch *disp = nullptr;
                        c->pUnk->QueryInterface(IID_QAxEvents, reinterpret_cast<void **>(&disp));
                        if (disp) {
                            disp->Invoke(eventId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispParams, pretval, nullptr, &argErr);

                            // update out-parameters and return value
                            if (index > 0) {
                                for (p = 0; p < pcount; ++p) {
                                    bool out;
                                    QByteArray ptype = paramType(ptypes.at(p), &out);
                                    if (out)
                                        QVariantToVoidStar(VARIANTToQVariant(dispParams.rgvarg[pcount - p - 1], ptype), argv[p+1], ptype);
                                }
                                if (pretval)
                                    QVariantToVoidStar(VARIANTToQVariant(retval, type), argv[0], type);
                            }
                            disp->Release();
                        }
                        c->pUnk->Release(); // AddRef'ed by clist->Next implementation
                    }
                    clist->Next(cc, reinterpret_cast<CONNECTDATA *>(&c), &cc);
                }

                // clean up
                for (p = 0; p < pcount; ++p)
                    clearVARIANT(dispParams.rgvarg+p);
                free(dispParams.rgvarg);
            }
            clist->Release();
        }
        cpoint->Release();
    }

    return true;
}

/*! \internal
    Call IPropertyNotifySink of connected clients.
    \a dispId specifies the ID of the property that changed.
*/
bool QAxServerBase::emitRequestPropertyChange(const char *property)
{
    long dispId = -1;

    IConnectionPoint *cpoint = nullptr;
    FindConnectionPoint(IID_IPropertyNotifySink, &cpoint);
    if (cpoint) {
        IEnumConnections *clist = nullptr;
        cpoint->EnumConnections(&clist);
        if (clist) {
            clist->Reset();
            ULONG cc = 1;
            CONNECTDATA c[1];
            clist->Next(cc, reinterpret_cast<CONNECTDATA *>(&c), &cc);
            if (cc) {
                if (dispId == -1) {
                    BSTR bstr = QStringToBSTR(QLatin1String(property));
                    GetIDsOfNames(IID_NULL, &bstr, 1, LOCALE_USER_DEFAULT, &dispId);
                    SysFreeString(bstr);
                }
                if (dispId != -1) while (cc) {
                    if (c->pUnk) {
                        IPropertyNotifySink *sink = nullptr;
                        c->pUnk->QueryInterface(IID_IPropertyNotifySink, reinterpret_cast<void **>(&sink));
                        bool disallows = sink && sink->OnRequestEdit(dispId) == S_FALSE;
                        sink->Release();
                        c->pUnk->Release();
                        if (disallows) { // a client disallows the property to change
                            clist->Release();
                            cpoint->Release();
                            return false;
                        }
                    }
                    clist->Next(cc, reinterpret_cast<CONNECTDATA *>(&c), &cc);
                }
            }
            clist->Release();
        }
        cpoint->Release();
    }
    dirtyflag = true;
    return true;
}

/*! \internal
    Call IPropertyNotifySink of connected clients.
    \a dispId specifies the ID of the property that changed.
*/
void QAxServerBase::emitPropertyChanged(const char *property)
{
    long dispId = -1;

    IConnectionPoint *cpoint = nullptr;
    FindConnectionPoint(IID_IPropertyNotifySink, &cpoint);
    if (cpoint) {
        IEnumConnections *clist = nullptr;
        cpoint->EnumConnections(&clist);
        if (clist) {
            clist->Reset();
            ULONG cc = 1;
            CONNECTDATA c[1];
            clist->Next(cc, reinterpret_cast<CONNECTDATA *>(&c), &cc);
            if (cc) {
                if (dispId == -1) {
                    BSTR bstr = QStringToBSTR(QLatin1String(property));
                    GetIDsOfNames(IID_NULL, &bstr, 1, LOCALE_USER_DEFAULT, &dispId);
                    SysFreeString(bstr);
                }
                if (dispId != -1) while (cc) {
                    if (c->pUnk) {
                        IPropertyNotifySink *sink = nullptr;
                        c->pUnk->QueryInterface(IID_IPropertyNotifySink, reinterpret_cast<void **>(&sink));
                        if (sink) {
                            sink->OnChanged(dispId);
                            sink->Release();
                        }
                        c->pUnk->Release();
                    }
                    clist->Next(cc, reinterpret_cast<CONNECTDATA *>(&c), &cc);
                }
            }
            clist->Release();
        }
        cpoint->Release();
    }
    dirtyflag = true;
}

//**** IProvideClassInfo
/*
    Provide the ITypeInfo implementation for the COM class.
*/
HRESULT WINAPI QAxServerBase::GetClassInfo(ITypeInfo** pptinfo)
{
    if (!pptinfo)
        return E_POINTER;

    *pptinfo = nullptr;
    if (!qAxTypeLibrary)
        return DISP_E_BADINDEX;

    return qAxTypeLibrary->GetTypeInfoOfGuid(qAxFactory()->classID(class_name), pptinfo);
}

//**** IProvideClassInfo2
/*
    Provide the ID of the event interface.
*/
HRESULT WINAPI QAxServerBase::GetGUID(DWORD dwGuidKind, GUID* pGUID)
{
    if (!pGUID)
        return E_POINTER;

    if (dwGuidKind == GUIDKIND_DEFAULT_SOURCE_DISP_IID) {
        *pGUID = qAxFactory()->eventsID(class_name);
        return S_OK;
    }
    *pGUID = GUID_NULL;
    return E_FAIL;
}

//**** IDispatch
/*
    Returns the number of class infos for this IDispatch.
*/
HRESULT WINAPI QAxServerBase::GetTypeInfoCount(UINT* pctinfo)
{
    if (!pctinfo)
        return E_POINTER;

    *pctinfo = qAxTypeLibrary ? 1 : 0;
    return S_OK;
}

/*
    Provides the ITypeInfo for this IDispatch implementation.
*/
HRESULT WINAPI QAxServerBase::GetTypeInfo(UINT /* itinfo */, LCID /*lcid*/, ITypeInfo** pptinfo)
{
    if (!pptinfo)
        return E_POINTER;

    if (!qAxTypeLibrary)
        return DISP_E_BADINDEX;

    ensureMetaData();

    *pptinfo = m_spTypeInfo;
    (*pptinfo)->AddRef();

    return S_OK;
}

/*
    Provides the names of the methods implemented in this IDispatch implementation.
*/
HRESULT WINAPI QAxServerBase::GetIDsOfNames(REFIID /* riid */, LPOLESTR* rgszNames, UINT cNames,
                                            LCID /*lcid*/, DISPID* rgdispid)
{
    if (!rgszNames || !rgdispid)
        return E_POINTER;

    if (!qAxTypeLibrary)
        return DISP_E_UNKNOWNNAME;

    ensureMetaData();
    if (!m_spTypeInfo)
        return DISP_E_UNKNOWNNAME;

    return m_spTypeInfo->GetIDsOfNames(rgszNames, cNames, rgdispid);
}

/*
    Map the COM call to the Qt slot/property for \a dispidMember.
*/
HRESULT WINAPI QAxServerBase::Invoke(DISPID dispidMember, REFIID riid,
                  LCID /*lcid*/, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult,
                  EXCEPINFO* pexcepinfo, UINT* puArgErr)
{
    if (riid != IID_NULL)
        return DISP_E_UNKNOWNINTERFACE;
    if (!theObject)
        return E_UNEXPECTED;

    HRESULT res = DISP_E_MEMBERNOTFOUND;

    bool uniqueIndex = wFlags == DISPATCH_PROPERTYGET || wFlags == DISPATCH_PROPERTYPUT || wFlags == DISPATCH_METHOD;

    int index = uniqueIndex ? indexCache.value(dispidMember, -1) : -1;
    QByteArray name;
    if (index == -1) {
        ensureMetaData();

        // This property or method is invoked when an ActiveX client specifies
        // the object name without a property or method. We only support property.
        if (dispidMember == DISPID_VALUE && (wFlags == DISPATCH_PROPERTYGET || wFlags == DISPATCH_PROPERTYPUT)) {
            const QMetaObject *mo = qt.object->metaObject();
            index = mo->indexOfClassInfo("DefaultProperty");
            if (index != -1) {
                name  = mo->classInfo(index).value();
                index = mo->indexOfProperty(name);
            }
        } else {
            if (!m_spTypeInfo)
                return res;
            name = qaxTypeInfoName(m_spTypeInfo, dispidMember);
            if (name.isEmpty())
                return res;
        }
    }

    const QMetaObject *mo = qt.object->metaObject();
    QSize oldSizeHint;
    if (isWidget)
        oldSizeHint = qt.widget->sizeHint();

    switch (wFlags) {
    case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
    case DISPATCH_PROPERTYGET:
        {
            if (index == -1) {
                index = mo->indexOfProperty(name);
                if (index == -1 && wFlags == DISPATCH_PROPERTYGET)
                    return res;
            }

            QMetaProperty property;
            if (index < mo->propertyCount())
                property = mo->property(index);

            if (property.isReadable()) {
                if (!pvarResult)
                    return DISP_E_PARAMNOTOPTIONAL;
                if (pDispParams->cArgs ||
                     pDispParams->cNamedArgs)
                    return DISP_E_BADPARAMCOUNT;

                QVariant var = qt.object->property(property.name());
                if (!var.isValid())
                    res =  DISP_E_MEMBERNOTFOUND;
                else if (!QVariantToVARIANT(var, *pvarResult))
                    res = DISP_E_TYPEMISMATCH;
                else
                    res = S_OK;
                break;
            }
            if (wFlags == DISPATCH_PROPERTYGET)
                break;
        }
        Q_FALLTHROUGH(); // Fall through if wFlags == DISPATCH_PROPERTYGET|DISPATCH_METHOD AND not a property.
    case DISPATCH_METHOD:
        {
            int nameLength = 0;
            if (index == -1) {
                nameLength = name.length();
                name += '(';
                // no parameter - shortcut
                if (!pDispParams->cArgs) {
                    const QByteArray slotName = name + ')';
                    index = mo->indexOfSlot(slotName.constData());
                }
                // search
                if (index == -1) {
                    for (int i = 0; i < mo->methodCount(); ++i) {
                        const QMetaMethod slot(mo->method(i));
                        if (slot.methodType() == QMetaMethod::Slot && slot.methodSignature().startsWith(name)) {
                            index = i;
                            break;
                        }
                    }
                    // resolve overloads
                    if (index == -1) {
                        QRegularExpression regexp(QLatin1String("_([0-9])\\("));
                        QRegularExpressionMatch rmatch;
                        QString::fromLatin1(name.constData()).lastIndexOf(regexp, -1, &rmatch);
                        if (rmatch.hasMatch()) {
                            name.chop(rmatch.capturedLength(0));
                            name += '(';
                            int overload = rmatch.capturedRef(1).toInt() + 1;

                            for (int s = 0; s < qt.object->metaObject()->methodCount(); ++s) {
                                QMetaMethod slot = qt.object->metaObject()->method(s);
                                if (slot.methodType() == QMetaMethod::Slot && slot.methodSignature().startsWith(name)) {
                                    if (!--overload) {
                                        index = s;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if (index == -1)
                        return res;
                }
            }

            int lookupIndex = index;

            // get slot info
            QMetaMethod slot(mo->method(index));
             Q_ASSERT(slot.methodType() == QMetaMethod::Slot || slot.methodType() == QMetaMethod::Method);
            QByteArray type = slot.typeName();
            name = slot.methodSignature();
            nameLength = name.indexOf('(');
            QByteArray prototype = name.mid(nameLength + 1);
            prototype.truncate(prototype.length() - 1);
            QByteArrayList ptypes;
            if (!prototype.isEmpty())
                ptypes = prototype.split(',');
            UINT pcount = UINT(ptypes.count());

            // verify parameter count
            if (pcount > pDispParams->cArgs) {
                // count cloned slots immediately following the real thing
                while (index < mo->methodCount()) {
                    ++index;
                    slot = mo->method(index);
                    if (!(slot.attributes() & QMetaMethod::Cloned))
                        break;
                    --pcount;
                    // found a matching overload. ptypes still valid
                    if (pcount <= pDispParams->cArgs)
                        break;
                }
                // still wrong :(
                if (pcount > pDispParams->cArgs)
                    return DISP_E_PARAMNOTOPTIONAL;
            } else if (pcount < pDispParams->cArgs) {
                return DISP_E_BADPARAMCOUNT;
            }

            // setup parameters (pcount + return)
            bool ok = true;
            void *static_argv[QAX_NUM_PARAMS + 1];
            QVariant static_varp[QAX_NUM_PARAMS + 1];
            void *static_argv_pointer[QAX_NUM_PARAMS + 1];

            int totalParam = int(pcount);
            if (!type.isEmpty())
                ++totalParam;

            void **argv = nullptr; // the actual array passed into qt_metacall
            void **argv_pointer = nullptr; // in case we need an additional level of indirection
            QVariant *varp = nullptr; // QVariants to hold the temporary Qt data object for us

            if (totalParam) {
                if (totalParam <= QAX_NUM_PARAMS) {
                    argv = static_argv;
                    argv_pointer = static_argv_pointer;
                    varp = static_varp;
                } else {
                    argv = new void*[pcount + 1];
                    argv_pointer = new void*[pcount + 1];
                    varp = new QVariant[pcount + 1];
                }

                argv_pointer[0] = nullptr;
            }

            for (UINT p = 0; p < pcount; ++p) {
                // map the VARIANT to the void*
                bool out;
                QByteArray ptype = paramType(ptypes.at(int(p)), &out);
                varp[p + 1] = VARIANTToQVariant(pDispParams->rgvarg[pcount - p - 1], ptype);
                argv_pointer[p + 1] = nullptr;
                if (varp[p + 1].isValid()) {
                    if (varp[p + 1].type() == QVariant::UserType) {
                        argv[p + 1] = varp[p + 1].data();
                    } else if (ptype == "QVariant") {
                        argv[p + 1] = varp + p + 1;
                    } else {
                        argv[p + 1] = const_cast<void*>(varp[p + 1].constData());
                        if (ptype.endsWith('*')) {
                            argv_pointer[p + 1] = argv[p + 1];
                            argv[p + 1] = argv_pointer + p + 1;
                        }
                    }
                } else if (ptype == "QVariant") {
                    argv[p + 1] = varp + p + 1;
                } else {
                    if (puArgErr)
                        *puArgErr = pcount-p-1;
                    ok = false;
                }
            }

            // return value
            if (!type.isEmpty() && type != "void") {
                QVariant::Type vt = QVariant::nameToType(type);
                if (vt == int(QMetaType::QVariant)) {
                    argv[0] = varp;
                } else {
                    if (vt == QVariant::UserType)
                        vt = QVariant::Invalid;
                    else if (vt == QVariant::Invalid && mo->indexOfEnumerator(slot.typeName()) != -1)
                        vt = QVariant::Int;
                    varp[0] = QVariant(vt);
                    if (varp[0].type() == QVariant::Invalid)
                        argv[0] = nullptr;
                    else
                        argv[0] = const_cast<void*>(varp[0].constData());
                }
                if (type.endsWith('*')) {
                    argv_pointer[0] = argv[0];
                    argv[0] = argv_pointer;
                }
            }

            // call the slot if everthing went fine.
            if (ok) {
                ++invokeCount;
                qt.object->qt_metacall(QMetaObject::InvokeMetaMethod, index, argv);
                if (--invokeCount < 0)
                    invokeCount = 0;

                // update reference parameters and return value
                for (UINT p = 0; p < pcount; ++p) {
                    bool out;
                    QByteArray ptype = paramType(ptypes.at(int(p)), &out);
                    if (out) {
                        if (!QVariantToVARIANT(varp[p + 1], pDispParams->rgvarg[pcount - p - 1], ptype, out))
                            ok = false;
                    }
                }
                if (!type.isEmpty() && type != "void" && pvarResult) {
                    if (!varp[0].isValid() && type != "QVariant")
                        varp[0] = QVariant(QMetaType::type(type), argv_pointer);
//                        varp[0].setValue(argv_pointer[0], type);
                    ok = QVariantToVARIANT(varp[0], *pvarResult, type);
                }
            }
            if (argv && argv != static_argv) {
                delete []argv;
                delete []argv_pointer;
                delete []varp;
            }

            res = ok ? S_OK : DISP_E_TYPEMISMATCH;

            // reset in case index changed for default-arg handling
            index = lookupIndex;
        }
        break;
    case DISPATCH_PROPERTYPUT:
    case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF:
        {
            if (index == -1) {
                index = mo->indexOfProperty(name);
                if (index == -1)
                    return res;
            }

            QMetaProperty property;
            if (index < mo->propertyCount())
                property = mo->property(index);
            if (!property.isWritable())
                return DISP_E_MEMBERNOTFOUND;
            if (!pDispParams->cArgs)
                return DISP_E_PARAMNOTOPTIONAL;
            if (pDispParams->cArgs != 1 ||
                pDispParams->cNamedArgs != 1 ||
                *pDispParams->rgdispidNamedArgs != DISPID_PROPERTYPUT)
                return DISP_E_BADPARAMCOUNT;

            QVariant var = VARIANTToQVariant(*pDispParams->rgvarg, property.typeName(), property.type());
            if (!var.isValid()) {
                if (puArgErr)
                    *puArgErr = 0;
                return DISP_E_BADVARTYPE;
            }
            if (!qt.object->setProperty(property.name(), var)) {
                if (puArgErr)
                    *puArgErr = 0;
                return DISP_E_TYPEMISMATCH;
            }

            res = S_OK;
        }
        break;

    default:
        break;
    }

    // maybe calling a setter? Notify client about changes
    switch(wFlags) {
    case DISPATCH_METHOD:
    case DISPATCH_PROPERTYPUT:
    case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF:
        if (m_spAdviseSink || adviseSinks.count()) {
            FORMATETC fmt;
            fmt.cfFormat = 0;
            fmt.ptd = nullptr;
            fmt.dwAspect = DVASPECT_CONTENT;
            fmt.lindex = -1;
            fmt.tymed = TYMED_NULL;

            STGMEDIUM stg;
            stg.tymed = TYMED_NULL;
            stg.pUnkForRelease = nullptr;
            stg.hBitmap = nullptr; // initializes the whole union

            if (m_spAdviseSink) {
                m_spAdviseSink->OnViewChange(DVASPECT_CONTENT, -1);
                m_spAdviseSink->OnDataChange(&fmt, &stg);
            }
            for (int i = 0; i < adviseSinks.count(); ++i) {
                adviseSinks.at(i).pAdvSink->OnDataChange(&fmt, &stg);
            }
        }

        dirtyflag = true;
        break;
    default:
        break;
    }

    if (index != -1 && uniqueIndex)
        indexCache.insert(dispidMember, index);

    if (exception) {
        if (pexcepinfo) {
            memset(pexcepinfo, 0, sizeof(EXCEPINFO));

            pexcepinfo->wCode = WORD(exception->code);
            if (!exception->src.isNull())
                pexcepinfo->bstrSource = QStringToBSTR(exception->src);
            if (!exception->desc.isNull())
                pexcepinfo->bstrDescription = QStringToBSTR(exception->desc);
            if (!exception->context.isNull()) {
                QString context = exception->context;
                unsigned contextID = 0;
                const int br = context.indexOf(QLatin1Char('[')); // "error[42]"
                if (br != -1) {
                    contextID = context.midRef(br + 1, context.size() - br - 2).toUInt();
                    context.truncate(br-1);
                }
                pexcepinfo->bstrHelpFile = QStringToBSTR(context);
                pexcepinfo->dwHelpContext = contextID;
            }
        }
        delete exception;
        exception = nullptr;
        return DISP_E_EXCEPTION;
    }
    if (isWidget) {
        if (oldSizeHint != qt.widget->sizeHint()) {
            updateGeometry();
            if (m_spInPlaceSite) {
                RECT rect = qaxContentRect(qaxToNativeSize(qt.widget, qt.widget->sizeHint()));
                m_spInPlaceSite->OnPosRectChange(&rect);
            }
        }
        updateMask();
    }

    return res;
}

//**** IConnectionPointContainer
/*
    Provide the IEnumConnectionPoints implemented in the QAxSignalVec class.
*/
HRESULT WINAPI QAxServerBase::EnumConnectionPoints(IEnumConnectionPoints **epoints)
{
    if (!epoints)
        return E_POINTER;
    *epoints = new QAxSignalVec(points);
    (*epoints)->AddRef();
    return S_OK;
}

/*
    Provide the IConnectionPoint implemented in the QAxConnection for \a iid.
*/
HRESULT WINAPI QAxServerBase::FindConnectionPoint(REFIID iid, IConnectionPoint **cpoint)
{
    if (!cpoint)
        return E_POINTER;

    IConnectionPoint *cp = points[iid];
    *cpoint = cp;
    if (cp) {
        cp->AddRef();
        return S_OK;
    }
    return CONNECT_E_NOCONNECTION;
}

//**** IPersistStream
/*
    \reimp

    See documentation of IPersistStorage::IsDirty.
*/
HRESULT WINAPI QAxServerBase::IsDirty()
{
    return dirtyflag ? S_OK : S_FALSE;
}

HRESULT WINAPI QAxServerBase::Load(IStream *pStm)
{
    STATSTG stat;
    HRESULT hres = pStm->Stat(&stat, STATFLAG_DEFAULT);
    bool openAsText = false;
    QByteArray qtarray;
    if (hres == S_OK) {
        QString streamName = QString::fromWCharArray(stat.pwcsName);
        CoTaskMemFree(stat.pwcsName);
        openAsText = streamName == QLatin1String("SomeStreamName");
        if (stat.cbSize.HighPart) // more than 4GB - too large!
            return S_FALSE;

        qtarray.resize(int(stat.cbSize.LowPart));
        ULONG read;
        pStm->Read(qtarray.data(), stat.cbSize.LowPart, &read);
    } else if (hres == E_NOTIMPL) {
        ULONG read = 0;
        while (hres != S_FALSE) {
            QByteArray arrayRead;
            arrayRead.resize(4098);
            hres = pStm->Read(arrayRead.data(), ULONG(arrayRead.size()), &read);
            if (hres != S_OK && hres != S_FALSE) {
                qtarray.resize(0);
                break;
            } else if (read == 0)
                break;
            qtarray.append(arrayRead);
        }
    }
    const QMetaObject *mo = qt.object->metaObject();

    QBuffer qtbuffer(&qtarray);
    QByteArray mimeType = mo->classInfo(mo->indexOfClassInfo("MIME")).value();
    if (!mimeType.isEmpty()) {
        mimeType.truncate(mimeType.indexOf(':')); // first type
        QAxBindable *axb = static_cast<QAxBindable *>(qt.object->qt_metacast("QAxBindable"));
        if (axb && axb->readData(&qtbuffer, QString::fromLatin1(mimeType)))
            return S_OK;
    }

    qtbuffer.close(); // resets
    qtbuffer.open(openAsText ? (QIODevice::ReadOnly | QIODevice::Text) : QIODevice::ReadOnly);

    QDataStream qtstream(&qtbuffer);
    int version;
    qtstream >> version;
    qtstream.setVersion(version);
    int more = 0;
    qtstream >> more;

    while (!qtbuffer.atEnd() && more) {
        QString propname;
        QVariant value;
        qtstream >> propname;
        if (propname.isEmpty())
            break;
        qtstream >> value;
        qtstream >> more;

        int idx = mo->indexOfProperty(propname.toLatin1());
        QMetaProperty property = mo->property(idx);
        if (property.isWritable())
            qt.object->setProperty(propname.toLatin1(), value);
    }
    return S_OK;
}

HRESULT WINAPI QAxServerBase::Save(IStream *pStm, BOOL clearDirty)
{
    const QMetaObject *mo = qt.object->metaObject();

    QBuffer qtbuffer;
    bool saved = false;
    QByteArray mimeType = mo->classInfo(mo->indexOfClassInfo("MIME")).value();
    if (!mimeType.isEmpty()) {
        QAxBindable *axb = static_cast<QAxBindable *>(qt.object->qt_metacast("QAxBindable"));
        saved = axb && axb->writeData(&qtbuffer);
        qtbuffer.close();
    }

    if (!saved) {
        qtbuffer.open(QIODevice::WriteOnly);
        QDataStream qtstream(&qtbuffer);
        qtstream << qtstream.version();

        for (int prop = 0; prop < mo->propertyCount(); ++prop) {
            if (!isPropertyExposed(prop))
                continue;
            QMetaProperty metaprop = mo->property(prop);
            if (QByteArray(metaprop.typeName()).endsWith('*'))
                continue;
            QString property = QLatin1String(metaprop.name());
            QVariant qvar = qt.object->property(metaprop.name());
            if (qvar.isValid()) {
                qtstream << int(1);
                qtstream << property;
                qtstream << qvar;
            }
        }

        qtstream << int(0);
        qtbuffer.close();
    }

    QByteArray qtarray = qtbuffer.buffer();
    ULONG written = 0;
    const char *data = qtarray.constData();
    ULARGE_INTEGER newsize;
    newsize.HighPart = 0;
    newsize.LowPart = DWORD(qtarray.size());
    pStm->SetSize(newsize);
    pStm->Write(data, ULONG(qtarray.size()), &written);
    pStm->Commit(STGC_ONLYIFCURRENT);

    if (clearDirty)
        dirtyflag = false;
    return S_OK;
}

HRESULT WINAPI QAxServerBase::GetSizeMax(ULARGE_INTEGER *pcbSize)
{
    const QMetaObject *mo = qt.object->metaObject();

    pcbSize->HighPart = 0;
    pcbSize->LowPart = DWORD(mo->propertyCount()) * 50;

    return S_OK;
}

//**** IPersistStorage

HRESULT WINAPI QAxServerBase::InitNew(IStorage *pStg)
{
    if (initNewCalled)
        return CO_E_ALREADYINITIALIZED;

    dirtyflag = false;
    initNewCalled = true;

    m_spStorage = pStg;
    if (m_spStorage)
        m_spStorage->AddRef();
    return S_OK;
}

HRESULT WINAPI QAxServerBase::Load(IStorage *pStg)
{
    if (InitNew(pStg) != S_OK)
        return CO_E_ALREADYINITIALIZED;

    IStream *spStream = nullptr;
    QString streamName = QLatin1String(qt.object->metaObject()->className());
    streamName.replace(QLatin1Char(':'), QLatin1Char('.'));
    /* Also invalid, but not relevant
    streamName.replace(QLatin1Char('/'), QLatin1Char('_'));
    streamName.replace(QLatin1Char('\\'), QLatin1Char('_'));
    */
    streamName += QLatin1String("_Stream4.2");

    pStg->OpenStream(reinterpret_cast<const wchar_t *>(streamName.utf16()), nullptr, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &spStream);
    if (!spStream) // support for streams saved with 4.1 and earlier
        pStg->OpenStream(L"SomeStreamName", nullptr, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &spStream);
    if (!spStream)
        return E_FAIL;

    Load(spStream);
    spStream->Release();

    return S_OK;
}

HRESULT WINAPI QAxServerBase::Save(IStorage *pStg, BOOL /* fSameAsLoad */)
{
    IStream *spStream = nullptr;
    QString streamName = QLatin1String(qt.object->metaObject()->className());
    streamName.replace(QLatin1Char(':'), QLatin1Char('.'));
    /* Also invalid, but not relevant
    streamName.replace(QLatin1Char('/'), QLatin1Char('_'));
    streamName.replace(QLatin1Char('\\'), QLatin1Char('_'));
    */
    streamName += QLatin1String("_Stream4.2");

    pStg->CreateStream(reinterpret_cast<const wchar_t *>(streamName.utf16()), STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &spStream);
    if (!spStream)
        return E_FAIL;

    Save(spStream, true);

    spStream->Release();
    return S_OK;
}

HRESULT WINAPI QAxServerBase::SaveCompleted(IStorage *pStgNew)
{
    if (pStgNew) {
        if (m_spStorage)
            m_spStorage->Release();
        m_spStorage = pStgNew;
        m_spStorage->AddRef();
    }
    return S_OK;
}

HRESULT WINAPI QAxServerBase::HandsOffStorage()
{
    if (m_spStorage) m_spStorage->Release();
    m_spStorage = nullptr;

    return S_OK;
}

//**** IPersistPropertyBag
/*
    Initialize the properties of the Qt widget.
*/
HRESULT WINAPI QAxServerBase::InitNew()
{
    if (initNewCalled)
        return CO_E_ALREADYINITIALIZED;

    dirtyflag = false;
    initNewCalled = true;
    return S_OK;
}

/*
    Set the properties of the Qt widget to the values provided in the \a bag.
*/
HRESULT WINAPI QAxServerBase::Load(IPropertyBag *bag, IErrorLog * /*log*/)
{
    if (!bag)
        return E_POINTER;

    if (InitNew() != S_OK)
        return E_UNEXPECTED;

    bool error = false;
    const QMetaObject *mo = qt.object->metaObject();
    for (int prop = 0; prop < mo->propertyCount(); ++prop) {
        if (!isPropertyExposed(prop))
            continue;
        QMetaProperty property = mo->property(prop);
        const char* pname = property.name();
        BSTR bstr = QStringToBSTR(QLatin1String(pname));
        VARIANT var;
        var.vt = VT_EMPTY;
        HRESULT res = bag->Read(bstr, &var, nullptr);
        if (property.isWritable() && var.vt != VT_EMPTY) {
            if (res != S_OK || !qt.object->setProperty(pname, VARIANTToQVariant(var, property.typeName(), property.type())))
                error = true;
        }
        SysFreeString(bstr);
    }

    updateGeometry();

    Q_UNUSED(error)
    return /*error ? E_FAIL :*/ S_OK;
}

/*
    Save the properties of the Qt widget into the \a bag.
*/
HRESULT WINAPI QAxServerBase::Save(IPropertyBag *bag, BOOL clearDirty, BOOL /*saveAll*/)
{
    if (!bag)
        return E_POINTER;

    if (clearDirty)
        dirtyflag = false;
    bool error = false;
    const QMetaObject *mo = qt.object->metaObject();
    for (int prop = 0; prop < mo->propertyCount(); ++prop) {
        if (!isPropertyExposed(prop))
            continue;
        QMetaProperty property = mo->property(prop);
        if (QByteArray(property.typeName()).endsWith('*'))
            continue;

        BSTR bstr = QStringToBSTR(QLatin1String(property.name()));
        QVariant qvar = qt.object->property(property.name());
        if (!qvar.isValid())
            error = true;
        VARIANT var;
        QVariantToVARIANT(qvar, var);
        bag->Write(bstr, &var);
        SysFreeString(bstr);
    }
    Q_UNUSED(error)
    return /*error ? E_FAIL :*/ S_OK;
}

//**** IPersistFile
/*
*/
HRESULT WINAPI QAxServerBase::SaveCompleted(LPCOLESTR fileName)
{
    if (qt.object->metaObject()->indexOfClassInfo("MIME") == -1)
        return E_NOTIMPL;

    currentFileName = QString::fromWCharArray(fileName);
    return S_OK;
}

HRESULT WINAPI QAxServerBase::GetCurFile(LPOLESTR *currentFile)
{
    if (qt.object->metaObject()->indexOfClassInfo("MIME") == -1)
        return E_NOTIMPL;

    if (currentFileName.isEmpty()) {
        *currentFile = nullptr;
        return S_FALSE;
    }
    IMalloc *malloc = nullptr;
    CoGetMalloc(1, &malloc);
    if (!malloc)
        return E_OUTOFMEMORY;

    *currentFile = static_cast<wchar_t *>(malloc->Alloc(currentFileName.length() * 2));
    malloc->Release();
    memcpy(*currentFile, currentFileName.unicode(), currentFileName.length() * 2);

    return S_OK;
}

HRESULT WINAPI QAxServerBase::Load(LPCOLESTR fileName, DWORD /* mode */)
{
    const QMetaObject *mo = qt.object->metaObject();
    int mimeIndex = mo->indexOfClassInfo("MIME");
    if (mimeIndex == -1)
        return E_NOTIMPL;

    QAxBindable *axb = static_cast<QAxBindable *>(qt.object->qt_metacast("QAxBindable"));
    if (!axb) {
        qWarning() << class_name << ": No QAxBindable implementation for mime-type handling";
        return E_NOTIMPL;
    }

    QString loadFileName = QString::fromWCharArray(fileName);
    QString fileExtension = loadFileName.mid(loadFileName.lastIndexOf(QLatin1Char('.')) + 1);
    QFile file(loadFileName);

    QString mimeType = QLatin1String(mo->classInfo(mimeIndex).value());
    QStringList mimeTypes = mimeType.split(QLatin1Char(';'));
    for (int m = 0; m < mimeTypes.count(); ++m) {
        const QString &mime = mimeTypes.at(m);
        if (mime.count(QLatin1Char(':')) != 2) {
            qWarning() << class_name << ": Invalid syntax in Q_CLASSINFO for MIME";
            continue;
        }

        mimeType.truncate(mimeType.indexOf(QLatin1Char(':'))); // first type
        if (mimeType.isEmpty()) {
            qWarning() << class_name << ": Invalid syntax in Q_CLASSINFO for MIME";
            continue;
        }
        QString mimeExtension = mime.mid(mimeType.length() + 1);
        mimeExtension.truncate(mimeExtension.indexOf(QLatin1Char(':')));
        if (mimeExtension != fileExtension)
            continue;

        if (axb->readData(&file, mimeType)) {
            currentFileName = loadFileName;
            return S_OK;
        }
    }

    return E_FAIL;
}

HRESULT WINAPI QAxServerBase::Save(LPCOLESTR fileName, BOOL fRemember)
{
    const QMetaObject *mo = qt.object->metaObject();
    int mimeIndex = mo->indexOfClassInfo("MIME");
    if (mimeIndex == -1)
        return E_NOTIMPL;

    QAxBindable *axb = static_cast<QAxBindable *>(qt.object->qt_metacast("QAxBindable"));
    if (!axb) {
        qWarning() << class_name << ": No QAxBindable implementation for mime-type handling";
        return E_NOTIMPL;
    }

    QString saveFileName = QString::fromWCharArray(fileName);
    QString fileExtension = saveFileName.mid(saveFileName.lastIndexOf(QLatin1Char('.')) + 1);
    QFile file(saveFileName);

    QString mimeType = QLatin1String(mo->classInfo(mimeIndex).value());
    QStringList mimeTypes = mimeType.split(QLatin1Char(';'));
    for (int m = 0; m < mimeTypes.count(); ++m) {
        const QString &mime = mimeTypes.at(m);
        if (mime.count(QLatin1Char(':')) != 2) {
            qWarning() << class_name << ": Invalid syntax in Q_CLASSINFO for MIME";
            continue;
        }
        mimeType.truncate(mimeType.indexOf(QLatin1Char(':'))); // first type
        if (mimeType.isEmpty()) {
            qWarning() << class_name << ": Invalid syntax in Q_CLASSINFO for MIME";
            continue;
        }
        QString mimeExtension = mime.mid(mimeType.length() + 1);
        mimeExtension.truncate(mimeExtension.indexOf(QLatin1Char(':')));
        if (mimeExtension != fileExtension)
            continue;
        if (axb->writeData(&file)) {
            if (fRemember)
                currentFileName = saveFileName;
            return S_OK;
        }
    }
    return E_FAIL;
}

Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0);

//**** IViewObject
/*
    Draws the widget into the provided device context.
*/
HRESULT WINAPI QAxServerBase::Draw(DWORD dwAspect, LONG /* lindex */, void * /* pvAspect */, DVTARGETDEVICE *ptd,
                HDC hicTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL /*lprcWBounds*/,
                BOOL(__stdcall* /*pfnContinue*/)(ULONG_PTR), ULONG_PTR /*dwContinue*/)
{
    if (!lprcBounds)
        return E_INVALIDARG;

    internalCreate();
    if (!isWidget || !qt.widget)
        return OLE_E_BLANK;

    switch (dwAspect) {
    case DVASPECT_CONTENT:
    case DVASPECT_OPAQUE:
    case DVASPECT_TRANSPARENT:
        break;
    default:
        return DV_E_DVASPECT;
    }
    if (!ptd)
        hicTargetDev = nullptr;

    bool bDeleteDC = false;
    if (!hicTargetDev) {
        hicTargetDev = ::CreateDC(L"DISPLAY", nullptr, nullptr, nullptr);
        bDeleteDC = (hicTargetDev != hdcDraw);
    }

    RECTL rc = *lprcBounds;
    bool bMetaFile = GetDeviceCaps(hdcDraw, TECHNOLOGY) == DT_METAFILE;
    if (!bMetaFile)
        ::LPtoDP(hicTargetDev, reinterpret_cast<LPPOINT>(&rc), 2);

    const QPixmap pm = qt.widget->grab();
    HBITMAP hbm = qt_pixmapToWinHBITMAP(pm);
    HDC hdc = CreateCompatibleDC(nullptr);
    SelectObject(hdc, hbm);
    ::StretchBlt(hdcDraw, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hdc, 0, 0,pm.width(), pm.height(), SRCCOPY);
    DeleteDC(hdc);
    DeleteObject(hbm);

    if (bDeleteDC)
        DeleteDC(hicTargetDev);

    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::GetColorSet(DWORD /* dwDrawAspect */, LONG /* lindex */, void * /* pvAspect */, DVTARGETDEVICE * /* ptd */,
        HDC /* hicTargetDev */, LOGPALETTE ** /* ppColorSet */)
{
    return E_NOTIMPL;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::Freeze(DWORD /* dwAspect */, LONG  /* lindex */, void * /* pvAspect */, DWORD * /* pdwFreeze */)
{
    return E_NOTIMPL;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::Unfreeze(DWORD /* dwFreeze */)
{
    return E_NOTIMPL;
}

/*
    Stores the provided advise sink.
*/
HRESULT WINAPI QAxServerBase::SetAdvise(DWORD /*aspects*/, DWORD /*advf*/, IAdviseSink *pAdvSink)
{
    if (m_spAdviseSink) m_spAdviseSink->Release();

    m_spAdviseSink = pAdvSink;
    if (m_spAdviseSink) m_spAdviseSink->AddRef();
    return S_OK;
}

/*
    Returns the advise sink.
*/
HRESULT WINAPI QAxServerBase::GetAdvise(DWORD* /*aspects*/, DWORD* /*advf*/, IAdviseSink **ppAdvSink)
{
    if (!ppAdvSink)
        return E_POINTER;

    *ppAdvSink = m_spAdviseSink;
    if (*ppAdvSink)
        (*ppAdvSink)->AddRef();
    return S_OK;
}

//**** IViewObject2
/*
    Returns the current size ONLY if the widget has already been sized.
*/
HRESULT WINAPI QAxServerBase::GetExtent(DWORD dwAspect, LONG /*lindex*/, DVTARGETDEVICE* /*ptd*/, LPSIZEL lpsizel)
{
    if (!isWidget || !qt.widget || !qt.widget->testAttribute(Qt::WA_Resized))
        return OLE_E_BLANK;

    return GetExtent(dwAspect, lpsizel);
}

//**** IOleControl
/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::GetControlInfo(LPCONTROLINFO)
{
    return E_NOTIMPL;
}

/*
    Turns event firing on and off.
*/
HRESULT WINAPI QAxServerBase::FreezeEvents(BOOL bFreeze)
{
    // member of CComControl
    if (bFreeze)
        freezeEvents++;
    else
        freezeEvents--;

    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::OnMnemonic(LPMSG)
{
    return E_NOTIMPL;
}

/*
    Update the ambient properties of the Qt widget.
*/
HRESULT WINAPI QAxServerBase::OnAmbientPropertyChange(DISPID dispID)
{
    if (!m_spClientSite || !theObject)
        return S_OK;

    IDispatch *disp = nullptr;
    m_spClientSite->QueryInterface(IID_IDispatch, reinterpret_cast<void **>(&disp));
    if (!disp)
        return S_OK;

    VARIANT var;
    VariantInit(&var);
    DISPPARAMS params = { nullptr, nullptr, 0, 0 };
    disp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &params, &var, nullptr, nullptr);
    disp->Release();
    disp = nullptr;

    switch(dispID) {
    case DISPID_AMBIENT_APPEARANCE:
        break;
    case DISPID_AMBIENT_AUTOCLIP:
        break;
    case DISPID_AMBIENT_BACKCOLOR:
    case DISPID_AMBIENT_FORECOLOR:
        if (isWidget) {
            unsigned rgb;
            if (var.vt == VT_UI4)
                rgb = var.ulVal;
            else if (var.vt == VT_I4)
                rgb = unsigned(var.lVal);
            else
                break;
            QPalette pal = qt.widget->palette();
            pal.setColor(dispID == DISPID_AMBIENT_BACKCOLOR ? QPalette::Window : QPalette::WindowText,
                         OLEColorToQColor(rgb));
            qt.widget->setPalette(pal);
        }
        break;
    case DISPID_AMBIENT_DISPLAYASDEFAULT:
        break;
    case DISPID_AMBIENT_DISPLAYNAME:
        if (var.vt != VT_BSTR || !isWidget)
            break;
        qt.widget->setWindowTitle(QString::fromWCharArray(var.bstrVal));
        break;
    case DISPID_AMBIENT_FONT:
        if (var.vt != VT_DISPATCH || !isWidget)
            break;
        {
            QVariant qvar = VARIANTToQVariant(var, "QFont", QVariant::Font);
            QFont qfont = qvariant_cast<QFont>(qvar);
            qt.widget->setFont(qfont);
        }
        break;
    case DISPID_AMBIENT_LOCALEID:
        break;
    case DISPID_AMBIENT_MESSAGEREFLECT:
        if (var.vt != VT_BOOL)
            break;
        if (var.boolVal)
            qt.widget->installEventFilter(this);
        else
            qt.widget->removeEventFilter(this);
        break;
    case DISPID_AMBIENT_PALETTE:
        break;
    case DISPID_AMBIENT_SCALEUNITS:
        break;
    case DISPID_AMBIENT_SHOWGRABHANDLES:
        break;
    case DISPID_AMBIENT_SHOWHATCHING:
        break;
    case DISPID_AMBIENT_SUPPORTSMNEMONICS:
        break;
    case DISPID_AMBIENT_TEXTALIGN:
        break;
    case DISPID_AMBIENT_UIDEAD:
        if (var.vt != VT_BOOL || !isWidget)
            break;
        qt.widget->setEnabled(!var.boolVal);
        break;
    case DISPID_AMBIENT_USERMODE:
        if (var.vt != VT_BOOL)
            break;
        inDesignMode = !var.boolVal;
        break;
    case DISPID_AMBIENT_RIGHTTOLEFT:
        if (var.vt != VT_BOOL)
            break;
        QGuiApplication::setLayoutDirection(var.boolVal ? Qt::RightToLeft : Qt::LeftToRight);
        break;
    }

    return S_OK;
}

//**** IOleWindow
/*
    Returns the HWND of the control.
*/
HRESULT WINAPI QAxServerBase::GetWindow(HWND *pHwnd)
{
    if (!pHwnd)
        return E_POINTER;
    *pHwnd = m_hWnd;
    return S_OK;
}

/*
    Enters What's This mode.
*/
HRESULT WINAPI QAxServerBase::ContextSensitiveHelp(BOOL fEnterMode)
{
    if (fEnterMode)
        QWhatsThis::enterWhatsThisMode();
    else
        QWhatsThis::leaveWhatsThisMode();
    return S_OK;
}

//**** IOleInPlaceObject
/*
    Deactivates the control in place.
*/
HRESULT WINAPI QAxServerBase::InPlaceDeactivate()
{
    if (!isInPlaceActive)
        return S_OK;
    UIDeactivate();

    isInPlaceActive = false;

    // if we have a window, tell it to go away.
    if (m_hWnd) {
        if (::IsWindow(m_hWnd))
            ::DestroyWindow(m_hWnd);
        m_hWnd = nullptr;
    }

    if (m_spInPlaceSite)
        m_spInPlaceSite->OnInPlaceDeactivate();

    return S_OK;
}

/*
    Deactivates the control's user interface.
*/
HRESULT WINAPI QAxServerBase::UIDeactivate()
{
    // if we're not UIActive, not much to do.
    if (!isUIActive || !m_spInPlaceSite)
        return S_OK;

    isUIActive = false;

    // notify frame windows, if appropriate, that we're no longer ui-active.
    HWND hwndParent;
    if (m_spInPlaceSite->GetWindow(&hwndParent) == S_OK) {
        if (m_spInPlaceFrame) m_spInPlaceFrame->Release();
        m_spInPlaceFrame = nullptr;
        IOleInPlaceUIWindow *spInPlaceUIWindow = nullptr;
        RECT rcPos, rcClip;
        OLEINPLACEFRAMEINFO frameInfo;
        frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);

        m_spInPlaceSite->GetWindowContext(&m_spInPlaceFrame, &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
        if (spInPlaceUIWindow) {
            spInPlaceUIWindow->SetActiveObject(nullptr, nullptr);
            spInPlaceUIWindow->Release();
        }
        if (m_spInPlaceFrame) {
            removeMenu();
            if (menuBar) {
                menuBar->removeEventFilter(this);
                menuBar = nullptr;
            }
            if (statusBar) {
                statusBar->removeEventFilter(this);
                const int index = statusBar->metaObject()->indexOfSignal("messageChanged(QString)");
        QMetaObject::disconnect(statusBar, index, this, STATUSBAR_MESSAGE_CHANGED_SLOT_INDEX);
                statusBar = nullptr;
            }
            m_spInPlaceFrame->SetActiveObject(nullptr, nullptr);
            m_spInPlaceFrame->Release();
            m_spInPlaceFrame = nullptr;
        }
    }
    // we don't need to explicitly release the focus here since somebody
    // else grabbing the focus is usually why we are getting called at all
    m_spInPlaceSite->OnUIDeactivate(false);

    return S_OK;
}

/*
    Positions the control, and applies requested clipping.
*/
HRESULT WINAPI QAxServerBase::SetObjectRects(LPCRECT prcPos, LPCRECT prcClip)
{
    if (prcPos == nullptr || prcClip == nullptr)
        return E_POINTER;

    if (m_hWnd) {
        // the container wants us to clip, so figure out if we really need to
        RECT rcIXect;
        BOOL b = IntersectRect(&rcIXect, prcPos, prcClip);
        HRGN tempRgn = nullptr;
        if (b && !EqualRect(&rcIXect, prcPos)) {
            OffsetRect(&rcIXect, -(prcPos->left), -(prcPos->top));
            tempRgn = CreateRectRgnIndirect(&rcIXect);
        }

        ::SetWindowRgn(m_hWnd, tempRgn, true);
        ::SetWindowPos(m_hWnd, nullptr, prcPos->left, prcPos->top,
            prcPos->right - prcPos->left, prcPos->bottom - prcPos->top,
            SWP_NOZORDER | SWP_NOACTIVATE);
    }

    //Save the new extent.
    const QRect qr = qaxFromNativeRect(*prcPos, qt.widget);
    m_currentExtent.rwidth() = qBound(qt.widget->minimumWidth(), qr.width(), qt.widget->maximumWidth());
    m_currentExtent.rheight() = qBound(qt.widget->minimumHeight(), qr.height(), qt.widget->maximumHeight());

    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::ReactivateAndUndo()
{
    return E_NOTIMPL;
}

//**** IOleInPlaceActiveObject

Q_GUI_EXPORT int qt_translateKeyCode(int);

HRESULT WINAPI QAxServerBase::TranslateAcceleratorW(MSG *pMsg)
{
    if (pMsg->message != WM_KEYDOWN || !isWidget)
        return S_FALSE;

    DWORD dwKeyMod = 0;
    if (::GetKeyState(VK_SHIFT) < 0)
        dwKeyMod |= 1;  // KEYMOD_SHIFT
    if (::GetKeyState(VK_CONTROL) < 0)
        dwKeyMod |= 2;  // KEYMOD_CONTROL
    if (::GetKeyState(VK_MENU) < 0)
        dwKeyMod |= 4;  // KEYMOD_ALT

    switch (LOWORD(pMsg->wParam)) {
    case VK_TAB:
        if (isUIActive) {
            bool shift = ::GetKeyState(VK_SHIFT) < 0;
            bool giveUp = true;
            QWidget *curFocus = qt.widget->focusWidget();
            if (curFocus) {
                if (shift) {
                    if (!curFocus->isWindow()) {
                        QWidget *nextFocus = curFocus->nextInFocusChain();
                        QWidget *topLevel = nullptr;
                        while (nextFocus != curFocus) {
                            if (nextFocus->focusPolicy() & Qt::TabFocus) {
                                topLevel = nullptr;
                            } else if (nextFocus->isWindow()) {
                                topLevel = nextFocus;
                            }
                            nextFocus = nextFocus->nextInFocusChain();
                        }

                        if (!topLevel) {
                            giveUp = false;
                            static_cast<HackWidget *>(curFocus)->focusNextPrevChild(false);
                            curFocus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
                        }
                    }
                } else {
                    QWidget *nextFocus = curFocus;
                    while (true) {
                        nextFocus = nextFocus->nextInFocusChain();
                        if (nextFocus->isWindow())
                            break;
                        if (nextFocus->focusPolicy() & Qt::TabFocus) {
                            giveUp = false;
                            static_cast<HackWidget *>(curFocus)->focusNextPrevChild(true);
                            curFocus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
                            break;
                        }
                    }
                }
            }
            if (giveUp) {
                HWND hwnd = ::GetParent(m_hWnd);
                ::SetFocus(hwnd);
            } else {
                return S_OK;
            }

        }
        break;

    case VK_LEFT:
    case VK_RIGHT:
    case VK_UP:
    case VK_DOWN:
        if (isUIActive)
            return S_FALSE;
        break;

    default:
        if (isUIActive && qt.widget->focusWidget()) {
            int state = Qt::NoButton;
            if (dwKeyMod & 1)
                state |= Qt::ShiftModifier;
            if (dwKeyMod & 2)
                state |= Qt::ControlModifier;
            if (dwKeyMod & 4)
                state |= Qt::AltModifier;

            int key = int(pMsg->wParam);
            // FIXME 4.10.2011: No longer exists in Lighthouse.
            // if (!(key >= 'A' && key <= 'Z') && !(key >= '0' && key <= '9'))
            //    key = qt_translateKeyCode(pMsg->wParam);

            QKeyEvent override(QEvent::ShortcutOverride, key, static_cast<Qt::KeyboardModifiers>(state));
            override.ignore();
            QCoreApplication::sendEvent(qt.widget->focusWidget(), &override);
            if (override.isAccepted())
                return S_FALSE;
        }
        break;
    }

    if (!m_spClientSite)
        return S_FALSE;

    IOleControlSite *controlSite = nullptr;
    m_spClientSite->QueryInterface(IID_IOleControlSite, reinterpret_cast<void **>(&controlSite));
    if (!controlSite)
        return S_FALSE;
    // set server type in the user-data of the window.
#ifdef GWLP_USERDATA
    LONG_PTR serverType = QAX_INPROC_SERVER;
#else
    LONG serverType = QAX_INPROC_SERVER;
#endif
    if (qAxOutProcServer)
        serverType = QAX_OUTPROC_SERVER;
#ifdef GWLP_USERDATA
    LONG_PTR oldData = SetWindowLongPtr(pMsg->hwnd, GWLP_USERDATA, serverType);
#else
    LONG oldData = SetWindowLong(pMsg->hwnd, GWL_USERDATA, serverType);
#endif
    HRESULT hres = controlSite->TranslateAcceleratorW(pMsg, dwKeyMod);
    controlSite->Release();
    // reset the user-data for the window.
#ifdef GWLP_USERDATA
    SetWindowLongPtr(pMsg->hwnd, GWLP_USERDATA, oldData);
#else
    SetWindowLong(pMsg->hwnd, GWL_USERDATA, oldData);
#endif
    return hres;
}

HRESULT WINAPI QAxServerBase::TranslateAcceleratorA(MSG *pMsg)
{
    return TranslateAcceleratorW(pMsg);
}

HRESULT WINAPI QAxServerBase::OnFrameWindowActivate(BOOL fActivate)
{
    if (fActivate) {
        if (wasUIActive)
            ::SetFocus(m_hWnd);
    } else {
        wasUIActive = isUIActive;
    }
    return S_OK;
}

HRESULT WINAPI QAxServerBase::OnDocWindowActivate(BOOL /* fActivate */)
{
    return S_OK;
}

HRESULT WINAPI QAxServerBase::ResizeBorder(LPCRECT /* prcBorder */, IOleInPlaceUIWindow * /* pUIWindow */, BOOL /* fFrameWindow */)
{
    return S_OK;
}

HRESULT WINAPI QAxServerBase::EnableModeless(BOOL fEnable)
{
    if (!isWidget)
        return S_OK;

    // FIXME: 4.10.2011 Does this work with the parent's HWND?
    EnableWindow(hwndForWidget(qt.widget), fEnable);
    return S_OK;
}

//**** IOleObject

static inline LPOLESTR QStringToOLESTR(const QString &qstring)
{
    LPOLESTR olestr = static_cast<wchar_t *>(CoTaskMemAlloc(size_t(qstring.length()) * 2 + 2));
    memcpy(olestr, reinterpret_cast<const ushort *>(qstring.unicode()), size_t(qstring.length() * 2));
    olestr[qstring.length()] = 0;
    return olestr;
}

/*
    \reimp

    See documentation of IOleObject::GetUserType.
*/
HRESULT WINAPI QAxServerBase::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
{
    if (!pszUserType)
        return E_POINTER;

    switch (dwFormOfType) {
    case USERCLASSTYPE_FULL:
        *pszUserType = QStringToOLESTR(class_name);
        break;
    case USERCLASSTYPE_SHORT:
        if (!qt.widget || !isWidget || qt.widget->windowTitle().isEmpty())
            *pszUserType = QStringToOLESTR(class_name);
        else
            *pszUserType = QStringToOLESTR(qt.widget->windowTitle());
        break;
    case USERCLASSTYPE_APPNAME:
        *pszUserType = QStringToOLESTR(qApp->objectName());
        break;
    }

    return S_OK;
}

/*
    Returns the status flags registered for this control.
*/
HRESULT WINAPI QAxServerBase::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
{
    return OleRegGetMiscStatus(qAxFactory()->classID(class_name), dwAspect, pdwStatus);
}

/*
    Stores the provided advise sink.
*/
HRESULT WINAPI QAxServerBase::Advise(IAdviseSink* pAdvSink, DWORD* pdwConnection)
{
    *pdwConnection = DWORD(adviseSinks.count()) + 1;
    STATDATA data = { {0, nullptr, DVASPECT_CONTENT, -1, TYMED_NULL} , 0, pAdvSink, *pdwConnection };
    adviseSinks.append(data);
    pAdvSink->AddRef();
    return S_OK;
}

/*
    Closes the control.
*/
HRESULT WINAPI QAxServerBase::Close(DWORD dwSaveOption)
{
    if (dwSaveOption != OLECLOSE_NOSAVE && m_spClientSite)
        m_spClientSite->SaveObject();
    if (isInPlaceActive) {
        HRESULT hr = InPlaceDeactivate();
        if (FAILED(hr))
            return hr;
    }
    if (m_hWnd) {
        if (IsWindow(m_hWnd))
            DestroyWindow(m_hWnd);
        m_hWnd = nullptr;
        if (m_spClientSite)
            m_spClientSite->OnShowWindow(false);
    }

    if (m_spInPlaceSiteWindowless)
        m_spInPlaceSiteWindowless->Release();
    m_spInPlaceSiteWindowless = nullptr;
    if (m_spInPlaceSite) m_spInPlaceSite->Release();
    m_spInPlaceSite = nullptr;

    if (m_spAdviseSink)
        m_spAdviseSink->OnClose();
    for (int i = 0; i < adviseSinks.count(); ++i) {
        adviseSinks.at(i).pAdvSink->OnClose();
    }

    return S_OK;
}

bool qax_disable_inplaceframe = true;

/*
    Executes the steps to activate the control.
*/
HRESULT QAxServerBase::internalActivate()
{
    if (!m_spClientSite)
        return S_OK;
    if (!m_spInPlaceSite)
        m_spClientSite->QueryInterface(IID_IOleInPlaceSite, reinterpret_cast<void **>(&m_spInPlaceSite));
    if (!m_spInPlaceSite)
        return E_FAIL;

    HRESULT hr = E_FAIL;
    if (!isInPlaceActive) {
        hr = m_spInPlaceSite->CanInPlaceActivate();
        if (FAILED(hr))
            return hr;
        if (hr != S_OK)
            return E_FAIL;
        m_spInPlaceSite->OnInPlaceActivate();
    }

    isInPlaceActive = true;
    OnAmbientPropertyChange(DISPID_AMBIENT_USERMODE);

    if (isWidget) {
        IOleInPlaceUIWindow *spInPlaceUIWindow = nullptr;
        HWND hwndParent;
        if (m_spInPlaceSite->GetWindow(&hwndParent) == S_OK) {
            // get location in the parent window, as well as some information about the parent
            if (m_spInPlaceFrame) m_spInPlaceFrame->Release();
            m_spInPlaceFrame = nullptr;
            RECT rcPos, rcClip;
            OLEINPLACEFRAMEINFO frameInfo;
            frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
            m_spInPlaceSite->GetWindowContext(&m_spInPlaceFrame, &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
            if (m_hWnd) {
                ::ShowWindow(m_hWnd, SW_SHOW);
                if (!::IsChild(m_hWnd, ::GetFocus()) && qt.widget->focusPolicy() != Qt::NoFocus)
                    ::SetFocus(m_hWnd);
            } else {
                if (!create(hwndParent, rcPos)) {
                    qWarning("%s: Window creation failed.", __FUNCTION__);
                    return E_FAIL;
                }
            }
        }

        // Gone active by now, take care of UIACTIVATE
        canTakeFocus = qt.widget->focusPolicy() != Qt::NoFocus && !inDesignMode;
        if (!canTakeFocus && !inDesignMode) {
            const auto widgets = qt.widget->findChildren<QWidget*>();
            for (const QWidget *widget : widgets) {
                canTakeFocus = widget->focusPolicy() != Qt::NoFocus;
                if (canTakeFocus)
                    break;
            }
        }
        if (!isUIActive && canTakeFocus) {
            isUIActive = true;
            hr = m_spInPlaceSite->OnUIActivate();
            if (FAILED(hr)) {
                if (m_spInPlaceFrame) m_spInPlaceFrame->Release();
                    m_spInPlaceFrame = nullptr;
                if (spInPlaceUIWindow) spInPlaceUIWindow->Release();
                    return hr;
            }

            if (isInPlaceActive) {
                if (!::IsChild(m_hWnd, ::GetFocus()))
                    ::SetFocus(m_hWnd);
            }

            if (m_spInPlaceFrame) {
                hr = m_spInPlaceFrame->SetActiveObject(this, reinterpret_cast<const wchar_t *>(class_name.utf16()));
                if (!FAILED(hr)) {
                    menuBar = (qt.widget && !qax_disable_inplaceframe) ? qt.widget->findChild<QMenuBar*>() : nullptr;
                    if (menuBar && !menuBar->isVisible()) {
                        createMenu(menuBar);
                        menuBar->hide();
                        menuBar->installEventFilter(this);
                    }
                    statusBar = qt.widget ? qt.widget->findChild<QStatusBar*>() : nullptr;
                    if (statusBar && !statusBar->isVisible()) {
                        const int index = statusBar->metaObject()->indexOfSignal("messageChanged(QString)");
                        QMetaObject::connect(statusBar, index, this, STATUSBAR_MESSAGE_CHANGED_SLOT_INDEX);
                        statusBar->hide();
                        statusBar->installEventFilter(this);
                    }
                }
            }
            if (spInPlaceUIWindow) {
                spInPlaceUIWindow->SetActiveObject(this, reinterpret_cast<const wchar_t *>(class_name.utf16()));
                spInPlaceUIWindow->SetBorderSpace(nullptr);
            }
        }
        if (spInPlaceUIWindow) spInPlaceUIWindow->Release();
            ShowWindow(m_hWnd, SW_NORMAL);
    }

    m_spClientSite->ShowObject();

    return S_OK;
}

/*
    Executes the "verb" \a iVerb.
*/
HRESULT WINAPI QAxServerBase::DoVerb(LONG iVerb, LPMSG /*lpmsg*/, IOleClientSite* /*pActiveSite*/, LONG /*lindex*/,
                               HWND /*hwndParent*/, LPCRECT /*prcPosRect*/)
{
    HRESULT hr = E_NOTIMPL;
    switch (iVerb)
    {
    case OLEIVERB_SHOW:
        hr = internalActivate();
        if (SUCCEEDED(hr))
            hr = S_OK;
        break;

    case OLEIVERB_PRIMARY:
    case OLEIVERB_INPLACEACTIVATE:
        hr = internalActivate();
        if (SUCCEEDED(hr)) {
            hr = S_OK;
            update();
        }
        break;

    case OLEIVERB_UIACTIVATE:
        if (!isUIActive) {
            hr = internalActivate();
            if (SUCCEEDED(hr))
                hr = S_OK;
        }
        break;

    case OLEIVERB_HIDE:
        UIDeactivate();
        if (m_hWnd)
            ::ShowWindow(m_hWnd, SW_HIDE);
        hr = S_OK;
        return hr;

    default:
        break;
    }
    return hr;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::EnumAdvise(IEnumSTATDATA** /*ppenumAdvise*/)
{
    return E_NOTIMPL;
}

/*
    Returns an enumerator for the verbs registered for this class.
*/
HRESULT WINAPI QAxServerBase::EnumVerbs(IEnumOLEVERB** ppEnumOleVerb)
{
    if (!ppEnumOleVerb)
        return E_POINTER;
    return OleRegEnumVerbs(qAxFactory()->classID(class_name), ppEnumOleVerb);
}

/*
    Returns the current client site..
*/
HRESULT WINAPI QAxServerBase::GetClientSite(IOleClientSite** ppClientSite)
{
    if (!ppClientSite)
        return E_POINTER;
    *ppClientSite = m_spClientSite;
    if (*ppClientSite)
        (*ppClientSite)->AddRef();
    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::GetClipboardData(DWORD, IDataObject**)
{
    return E_NOTIMPL;
}

/*
    Returns the current extent.
*/
HRESULT WINAPI QAxServerBase::GetExtent(DWORD dwDrawAspect, SIZEL* psizel)
{
    if (dwDrawAspect != DVASPECT_CONTENT || !isWidget || !qt.widget)
        return E_FAIL;
    if (!psizel)
        return E_POINTER;

    *psizel = qaxMapPixToLogHiMetrics(m_currentExtent, qt.widget);
    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::GetMoniker(DWORD, DWORD, IMoniker** )
{
    return E_NOTIMPL;
}

/*
    Returns the CLSID of this class.
*/
HRESULT WINAPI QAxServerBase::GetUserClassID(CLSID* pClsid)
{
    if (!pClsid)
        return E_POINTER;
    *pClsid = qAxFactory()->classID(class_name);
    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::InitFromData(IDataObject*, BOOL, DWORD)
{
    return E_NOTIMPL;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::IsUpToDate()
{
    return S_OK;
}

/*
    Stores the client site.
*/
HRESULT WINAPI QAxServerBase::SetClientSite(IOleClientSite* pClientSite)
{
    // release all client site interfaces
    if (m_spClientSite) m_spClientSite->Release();
    if (m_spInPlaceSiteWindowless)
        m_spInPlaceSiteWindowless->Release();
    m_spInPlaceSiteWindowless = nullptr;
    if (m_spInPlaceSite) m_spInPlaceSite->Release();
    m_spInPlaceSite = nullptr;
    if (m_spInPlaceFrame) m_spInPlaceFrame->Release();
    m_spInPlaceFrame = nullptr;

    m_spClientSite = pClientSite;
    if (m_spClientSite) {
        m_spClientSite->AddRef();
        m_spClientSite->QueryInterface(IID_IOleInPlaceSite, reinterpret_cast<void **>(&m_spInPlaceSite));
        m_spClientSite->QueryInterface(IID_IOleInPlaceSiteWindowless,
                                       reinterpret_cast<void **>(&m_spInPlaceSiteWindowless));
    }

    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::SetColorScheme(LOGPALETTE*)
{
    return E_NOTIMPL;
}


#ifdef QT_SHARED // avoid conflict with symbol in static lib
bool qt_sendSpontaneousEvent(QObject *o, QEvent *e)
{
    return QCoreApplication::sendSpontaneousEvent(o, e);
}
#endif

/*
    Tries to set the size of the control.
*/
HRESULT WINAPI QAxServerBase::SetExtent(DWORD dwDrawAspect, SIZEL* psizel)
{
    if (dwDrawAspect != DVASPECT_CONTENT)
        return DV_E_DVASPECT;
    if (!psizel)
        return E_POINTER;

    if (!isWidget || !qt.widget) // nothing to do
        return S_OK;

    QSize proposedSize(qaxMapLogHiMetricsToPix(*psizel, qt.widget));

    // can the widget be resized at all?
    if (qt.widget->minimumSize() == qt.widget->maximumSize() && qt.widget->minimumSize() != proposedSize)
        return E_FAIL;
    //Save the extent, bound to the widget restrictions.
    m_currentExtent.rwidth() = qBound(qt.widget->minimumWidth(), proposedSize.width(), qt.widget->maximumWidth());
    m_currentExtent.rheight() = qBound(qt.widget->minimumHeight(), proposedSize.height(), qt.widget->maximumHeight());

    resize(proposedSize);
    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::SetHostNames(LPCOLESTR /* szContainerApp */, LPCOLESTR /* szContainerObj */)
{
    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::SetMoniker(DWORD, IMoniker*)
{
    return E_NOTIMPL;
}

/*
    Disconnects an advise sink.
*/
HRESULT WINAPI QAxServerBase::Unadvise(DWORD dwConnection)
{
    for (int i = 0; i < adviseSinks.count(); ++i) {
        STATDATA entry = adviseSinks.at(i);
        if (entry.dwConnection == dwConnection) {
            entry.pAdvSink->Release();
            adviseSinks.removeAt(i);
            return S_OK;
        }
    }
    return OLE_E_NOCONNECTION;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::Update()
{
    return S_OK;
}

//**** IDataObject
/*
    Calls IViewObject::Draw after setting up the parameters.
*/
HRESULT WINAPI QAxServerBase::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
    if (!pmedium)
        return E_POINTER;
    if ((pformatetcIn->tymed & TYMED_MFPICT) == 0)
        return DATA_E_FORMATETC;

    internalCreate();
    if (!isWidget || !qt.widget)
        return E_UNEXPECTED;

    // Container wants to draw, but the size is not defined yet - ask container
    if (m_spInPlaceSite && !qt.widget->testAttribute(Qt::WA_Resized)) {
        IOleInPlaceUIWindow *spInPlaceUIWindow = nullptr;
        RECT rcPos, rcClip;
        OLEINPLACEFRAMEINFO frameInfo;
        frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);

        HRESULT hres = m_spInPlaceSite->GetWindowContext(&m_spInPlaceFrame, &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
        if (hres == S_OK) {
            resize(qaxFromNativeSize(qt.widget, qaxSizeOfRect(rcPos)));
        } else {
            qt.widget->adjustSize();
        }
        if (spInPlaceUIWindow) spInPlaceUIWindow->Release(); // no need for it
    }

    int width = qt.widget->width();
    int height = qt.widget->height();
    RECTL rectl = {0, 0, width, height};

    HDC hdc = CreateMetaFile(nullptr);
    SaveDC(hdc);
    SetWindowOrgEx(hdc, 0, 0, nullptr);
    SetWindowExtEx(hdc, rectl.right, rectl.bottom, nullptr);

    Draw(pformatetcIn->dwAspect, pformatetcIn->lindex, nullptr, pformatetcIn->ptd, nullptr, hdc, &rectl, &rectl, nullptr, 0);

    RestoreDC(hdc, -1);
    HMETAFILE hMF = CloseMetaFile(hdc);
    if (!hMF)
        return E_UNEXPECTED;

    HGLOBAL hMem = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(METAFILEPICT));
    if (!hMem) {
        DeleteMetaFile(hMF);
        return ResultFromScode(STG_E_MEDIUMFULL);
    }

    LPMETAFILEPICT pMF = static_cast<LPMETAFILEPICT>(GlobalLock(hMem));
    pMF->hMF = hMF;
    pMF->mm = MM_ANISOTROPIC;
    const SIZEL sizeL = qaxMapPixToLogHiMetrics(QSize(width, height), qt.widget);
    pMF->xExt = sizeL.cx;
    pMF->yExt = sizeL.cy;
    GlobalUnlock(hMem);

    memset(pmedium, 0, sizeof(STGMEDIUM));
    pmedium->tymed = TYMED_MFPICT;
    pmedium->hGlobal = hMem;
    pmedium->pUnkForRelease = nullptr;

    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::DAdvise(FORMATETC *pformatetc, DWORD advf,
                                      IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
    if (pformatetc->dwAspect != DVASPECT_CONTENT)
        return E_FAIL;

    *pdwConnection = adviseSinks.count() + 1;
    STATDATA data = {
        {pformatetc->cfFormat,pformatetc->ptd,pformatetc->dwAspect,pformatetc->lindex,pformatetc->tymed},
        advf, pAdvSink, *pdwConnection
    };
    adviseSinks.append(data);
    pAdvSink->AddRef();
    return S_OK;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::DUnadvise(DWORD dwConnection)
{
    return Unadvise(dwConnection);
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::EnumDAdvise(IEnumSTATDATA ** /*ppenumAdvise*/)
{
    return E_NOTIMPL;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::GetDataHere(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */)
{
    return E_NOTIMPL;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::QueryGetData(FORMATETC* /* pformatetc */)
{
    return E_NOTIMPL;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::GetCanonicalFormatEtc(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */)
{
    return E_NOTIMPL;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::SetData(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */)
{
    return E_NOTIMPL;
}

/*
    Not implemented.
*/
HRESULT WINAPI QAxServerBase::EnumFormatEtc(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */)
{
    return E_NOTIMPL;
}



static int mapModifiers(Qt::KeyboardModifiers state)
{
    int ole = 0;
    if (state & Qt::ShiftModifier)
        ole |= 1;
    if (state & Qt::ControlModifier)
        ole |= 2;
    if (state & Qt::AltModifier)
        ole |= 4;

    return ole;
}

/*
    \reimp
*/
bool QAxServerBase::eventFilter(QObject *o, QEvent *e)
{
    if (!theObject)
        return QObject::eventFilter(o, e);

    if ((e->type() == QEvent::Show || e->type() == QEvent::Hide) && (o == statusBar || o == menuBar)) {
        if (o == menuBar) {
            if (e->type() == QEvent::Hide) {
                createMenu(menuBar);
            } else if (e->type() == QEvent::Show) {
                removeMenu();
            }
        } else if (statusBar) {
            statusBar->setSizeGripEnabled(false);
        }
        updateGeometry();
        if (m_spInPlaceSite && qt.widget->sizeHint().isValid()) {
            RECT rect = qaxContentRect(qaxToNativeSize(qt.widget, qt.widget->sizeHint()));
            m_spInPlaceSite->OnPosRectChange(&rect);
        }
    }
    switch (e->type()) {
    case QEvent::ChildAdded:
        static_cast<QChildEvent*>(e)->child()->installEventFilter(this);
        break;
    case QEvent::ChildRemoved:
        static_cast<QChildEvent*>(e)->child()->removeEventFilter(this);
        break;
    case QEvent::KeyPress:
        if (o == qt.object && hasStockEvents) {
            const QKeyEvent *ke = static_cast<const QKeyEvent *>(e);
            int key = ke->key();
            int state = ke->modifiers();
            void *argv[] = {
                nullptr,
                &key,
                &state
            };
            qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_KEYDOWN, argv);
            if (!ke->text().isEmpty())
                qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_KEYPRESS, argv);
        }
        break;
    case QEvent::KeyRelease:
        if (o == qt.object && hasStockEvents) {
            const QKeyEvent *ke = static_cast<const QKeyEvent *>(e);
            int key = ke->key();
            int state = ke->modifiers();
            void *argv[] = {
                nullptr,
                &key,
                &state
            };
            qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_KEYUP, argv);
        }
        break;
    case QEvent::MouseMove:
        if (o == qt.object && hasStockEvents) {
            const QMouseEvent *me = static_cast<const QMouseEvent *>(e);
            int button = me->buttons() & Qt::MouseButtonMask;
            int state = mapModifiers(me->modifiers());
            int x = me->x();
            int y = me->y();
            void *argv[] = {
                nullptr,
                &button,
                &state,
                &x,
                &y
            };
            qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_MOUSEMOVE, argv);
        }
        break;
    case QEvent::MouseButtonRelease:
        if (o == qt.object && hasStockEvents) {
            const QMouseEvent *me = static_cast<const QMouseEvent *>(e);
            int button = me->button();
            int state = mapModifiers(me->modifiers());
            int x = me->x();
            int y = me->y();
            void *argv[] = {
                nullptr,
                &button,
                &state,
                &x,
                &y
            };
            qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_MOUSEUP, argv);
            qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_CLICK, nullptr);
        }
        break;
    case QEvent::MouseButtonDblClick:
        if (o == qt.object && hasStockEvents) {
            qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_DBLCLICK, nullptr);
        }
        break;
    case QEvent::MouseButtonPress:
        if (m_spInPlaceSite && !isUIActive) {
            internalActivate();
        }
        if (o == qt.widget && hasStockEvents) {
            const QMouseEvent *me = static_cast<const QMouseEvent *>(e);
            int button = me->button();
            int state = mapModifiers(me->modifiers());
            int x = me->x();
            int y = me->y();
            void *argv[] = {
                nullptr,
                &button,
                &state,
                &x,
                &y
            };
            qt_metacall(QMetaObject::InvokeMetaMethod, DISPID_MOUSEDOWN, argv);
        }
        break;
    case QEvent::Show:
        if (m_hWnd && o == qt.widget)
            ShowWindow(m_hWnd, SW_SHOW);
        updateMask();
        break;
    case QEvent::Hide:
        if (m_hWnd && o == qt.widget)
            ShowWindow(m_hWnd, SW_HIDE);
        break;

    case QEvent::EnabledChange:
        if (m_hWnd && o == qt.widget)
            EnableWindow(m_hWnd, qt.widget->isEnabled());
        Q_FALLTHROUGH();
    case QEvent::FontChange:
    case QEvent::ActivationChange:
    case QEvent::StyleChange:
    case QEvent::IconTextChange:
    case QEvent::ModifiedChange:
    case QEvent::Resize:
        updateMask();
        break;
    case QEvent::WindowBlocked: {
        if (!m_spInPlaceFrame)
            break;
        m_spInPlaceFrame->EnableModeless(FALSE);
        MSG msg;
        // Visual Basic 6.0 posts the message WM_USER+3078 from the EnableModeless().
        // While handling this message, VB will disable all current top-levels. After
        // this we have to re-enable the Qt modal widget to receive input events.
        if (PeekMessage(&msg, nullptr, WM_USER+3078, WM_USER+3078, PM_REMOVE)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            // FIXME: 4.10.2011 Does this work with the parent's HWND?
            QWidget *modalWidget = QApplication::activeModalWidget();
            if (modalWidget && modalWidget->isVisible() && modalWidget->isEnabled()
                && !IsWindowEnabled(hwndForWidget(modalWidget)))
                EnableWindow(hwndForWidget(modalWidget), TRUE);
        }
        break;
        }
    case QEvent::WindowUnblocked:
        if (!m_spInPlaceFrame)
            break;
        m_spInPlaceFrame->EnableModeless(TRUE);
        break;
    default:
        break;
    }
    return QObject::eventFilter(o, e);
}

QT_END_NAMESPACE
