]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/contrib/iewin/wxactivex.cpp
Added wxRTTI for the new wxVScrolledWindow, wxVListBox, and
[wxWidgets.git] / wxPython / contrib / iewin / wxactivex.cpp
index 575d2fae2bb40f228a02e05ecd6cd3ec868ab36f..34fd2b1e2f19e647feeefbc71d1a65f9ec6cec9e 100644 (file)
@@ -24,14 +24,16 @@ using namespace std;
 
 //////////////////////////////////////////////////////////////////////
 BEGIN_EVENT_TABLE(wxActiveX, wxWindow)
-       EVT_SIZE(OnSize)
-       EVT_SET_FOCUS(OnSetFocus)
-       EVT_KILL_FOCUS(OnKillFocus)
+    EVT_SIZE(wxActiveX::OnSize)
+    EVT_PAINT(wxActiveX::OnPaint)
+    EVT_MOUSE_EVENTS(wxActiveX::OnMouse)
+       EVT_SET_FOCUS(wxActiveX::OnSetFocus)
+       EVT_KILL_FOCUS(wxActiveX::OnKillFocus)
 END_EVENT_TABLE()
 
 class wxActiveX;
 
-class FrameSite : 
+class FrameSite :
     public IOleClientSite,
     public IOleInPlaceSiteEx,
     public IOleInPlaceFrame,
@@ -47,7 +49,7 @@ private:
 
 public:
        FrameSite(wxActiveX * win);
-       ~FrameSite();
+       virtual ~FrameSite();
 
        //IOleWindow
        STDMETHODIMP GetWindow(HWND*);
@@ -58,7 +60,7 @@ public:
        STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS);
        STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS);
        STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject*, LPCOLESTR);
-       
+
     //IOleInPlaceFrame
        STDMETHODIMP InsertMenus(HMENU, LPOLEMENUGROUPWIDTHS);
        STDMETHODIMP SetMenu(HMENU, HOLEMENU, HWND);
@@ -71,7 +73,7 @@ public:
        STDMETHODIMP CanInPlaceActivate();
        STDMETHODIMP OnInPlaceActivate();
        STDMETHODIMP OnUIActivate();
-       STDMETHODIMP GetWindowContext(IOleInPlaceFrame**, IOleInPlaceUIWindow**, 
+       STDMETHODIMP GetWindowContext(IOleInPlaceFrame**, IOleInPlaceUIWindow**,
                LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO);
        STDMETHODIMP Scroll(SIZE);
        STDMETHODIMP OnUIDeactivate(BOOL);
@@ -117,7 +119,7 @@ public:
        STDMETHODIMP GetObject(LPOLESTR, DWORD, IBindCtx*, REFIID, void**);
        STDMETHODIMP GetObjectStorage(LPOLESTR, IBindCtx*, REFIID, void**);
        STDMETHODIMP IsRunning(LPOLESTR);
-    
+
        //IDispatch
        STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*);
        STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**);
@@ -146,7 +148,7 @@ protected:
        bool m_bInPlaceActive;
        bool m_bUIActive;
        bool m_bWindowless;
-    
+
 
 
        LCID m_nAmbientLocale;
@@ -207,7 +209,7 @@ wxActiveX::wxActiveX(wxWindow * parent, wxString progId, wxWindowID id,
 {
     m_bAmbientUserMode = true;
     m_docAdviseCookie = 0;
-    CreateActiveX((LPOLESTR) wxConvUTF8.cMB2WC(progId).data());
+    CreateActiveX((LPOLESTR) (const wchar_t *) progId.wc_str(wxConvUTF8));
 }
 
 wxActiveX::~wxActiveX()
@@ -223,14 +225,14 @@ wxActiveX::~wxActiveX()
        };
        m_connections.clear();
 
-    if (m_oleInPlaceObject.Ok()) 
+    if (m_oleInPlaceObject.Ok())
        {
                m_oleInPlaceObject->InPlaceDeactivate();
                m_oleInPlaceObject->UIDeactivate();
        }
 
 
-       if (m_oleObject.Ok()) 
+       if (m_oleObject.Ok())
        {
            if (m_docAdviseCookie != 0)
                m_oleObject->Unadvise(m_docAdviseCookie);
@@ -266,9 +268,23 @@ void wxActiveX::CreateActiveX(REFCLSID clsid)
        GetTypeInfo();
 
        // Get IOleObject interface
-       hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX); 
+       hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
        wxASSERT(SUCCEEDED(hret));
-       // Get IOleInPlaceObject interface
+
+    // get IViewObject Interface
+    hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
+       wxASSERT(SUCCEEDED(hret));
+
+    // document advise
+    m_docAdviseCookie = 0;
+    hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
+    WXOLE_WARN(hret, "m_oleObject->Advise(adviseSink, &m_docAdviseCookie),\"Advise\")");
+    m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
+       OleSetContainedObject(m_oleObject, TRUE);
+    OleRun(m_oleObject);
+
+
+    // Get IOleInPlaceObject interface
        hret = m_oleInPlaceObject.QueryInterface(IID_IOleInPlaceObject, m_ActiveX);
        wxASSERT(SUCCEEDED(hret));
 
@@ -292,13 +308,6 @@ void wxActiveX::CreateActiveX(REFCLSID clsid)
         WXOLE_WARN(hret, "CreateActiveX::pPersistStreamInit->InitNew()");
     };
 
-    // document advise
-    m_docAdviseCookie = 0;
-    hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
-    WXOLE_WARN(hret, "m_oleObject->Advise(adviseSink, &m_docAdviseCookie),\"Advise\")");
-    m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
-       OleSetContainedObject(m_oleObject, TRUE);
-
     if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
                m_oleObject->SetClientSite(m_clientSite);
 
@@ -312,22 +321,26 @@ void wxActiveX::CreateActiveX(REFCLSID clsid)
        posRect.bottom = h;
 
     m_oleObjectHWND = 0;
-       hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
-       WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)");
-    if (SUCCEEDED(hret))
-           ::SetActiveWindow(m_oleObjectHWND);
+
+    if (m_oleInPlaceObject.Ok())
+    {
+       hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
+           WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)");
+        if (SUCCEEDED(hret))
+               ::SetActiveWindow(m_oleObjectHWND);
+    };
 
 
     if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
     {
-               if (w > 0 && h > 0)
+               if (w > 0 && h > 0 && m_oleInPlaceObject.Ok())
                        m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
 
                hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, m_clientSite, 0, (HWND)GetHWND(), &posRect);
         hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0, (HWND)GetHWND(), &posRect);
     };
 
-       if (! m_oleObjectHWND)
+       if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
        {
                hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
                WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)");
@@ -365,33 +378,43 @@ struct less_wxStringI
     };
 };
 
-typedef map<wxString, wxEventType *, less_wxStringI> ActiveXEventMap;
-static ActiveXEventMap sg_eventMap;
+typedef map<wxString, wxEventType *, less_wxStringI> ActiveXNamedEventMap;
+static ActiveXNamedEventMap sg_NamedEventMap;
 
-// one off class for automatic freeing of activeX eventtypes
-class ActiveXEventMapFlusher
+const wxEventType& RegisterActiveXEvent(const wxChar *eventName)
 {
-public:
-    ~ActiveXEventMapFlusher()
+    wxString ev = eventName;
+    ActiveXNamedEventMap::iterator it = sg_NamedEventMap.find(ev);
+    if (it == sg_NamedEventMap.end())
     {
-        ActiveXEventMap::iterator it = sg_eventMap.end();
-        while (it != sg_eventMap.end())
-        {
-            delete it->second;
-            it++;
-        };
+        wxEventType  *et = new wxEventType(wxNewEventType());
+        sg_NamedEventMap[ev] = et;
+
+        return *et;
     };
+
+    return *(it->second);
 };
 
-static ActiveXEventMapFlusher s_dummyActiveXEventMapFlusher;
 
-const wxEventType& RegisterActiveXEvent(wxString eventName)
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Map of Event DISPID's to eventTypes
+// created dynamically at run time in:
+//      EVT_ACTIVEX(eventName, id, fn)
+// we map the pointer to them so that:
+//      const wxEventType& RegisterActiveXEvent(wxString eventName);
+// can return a const reference, which is neccessary for event tables
+
+typedef map<DISPID, wxEventType *> ActiveXDISPIDEventMap;
+static ActiveXDISPIDEventMap sg_dispIdEventMap;
+
+const wxEventType& RegisterActiveXEvent(DISPID event)
 {
-    ActiveXEventMap::iterator it = sg_eventMap.find(eventName);
-    if (it == sg_eventMap.end())
+    ActiveXDISPIDEventMap::iterator it = sg_dispIdEventMap.find(event);
+    if (it == sg_dispIdEventMap.end())
     {
         wxEventType  *et = new wxEventType(wxNewEventType());
-        sg_eventMap[eventName] = et;
+        sg_dispIdEventMap[event] = et;
 
         return *et;
     };
@@ -399,6 +422,33 @@ const wxEventType& RegisterActiveXEvent(wxString eventName)
     return *(it->second);
 };
 
+// one off class for automatic freeing of activeX eventtypes
+class ActiveXEventMapFlusher
+{
+public:
+    ~ActiveXEventMapFlusher()
+    {
+        // Named events
+        ActiveXNamedEventMap::iterator it = sg_NamedEventMap.end();
+        while (it != sg_NamedEventMap.end())
+        {
+            delete it->second;
+            it++;
+        };
+
+        // DISPID events
+        ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.end();
+        while (dit != sg_dispIdEventMap.end())
+        {
+            delete dit->second;
+            dit++;
+        };
+    };
+};
+
+static ActiveXEventMapFlusher s_dummyActiveXEventMapFlusher;
+
+
 //////////////////////////////////////////////////////
 bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx)
 {
@@ -479,83 +529,69 @@ private:
 
 public:
     wxActiveXEvents(wxActiveX *ax) : m_activeX(ax) {}
-       ~wxActiveXEvents() 
+       virtual ~wxActiveXEvents()
     {
     }
 
        //IDispatch
        STDMETHODIMP GetIDsOfNames(REFIID r, OLECHAR** o, unsigned int i, LCID l, DISPID* d)
-       { 
+       {
         return E_NOTIMPL;
     };
 
        STDMETHODIMP GetTypeInfo(unsigned int i, LCID l, ITypeInfo** t)
-       { 
+       {
         return E_NOTIMPL;
     };
 
        STDMETHODIMP GetTypeInfoCount(unsigned int* i)
-       { 
+       {
         return E_NOTIMPL;
     };
 
 
-
-       STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
-                                                 WORD wFlags, DISPPARAMS * pDispParams,
-                                                 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
-                                                 unsigned int * puArgErr)
-       { 
-           if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
-            return E_NOTIMPL;
-
-        // map dispid to name
-        wxActiveX::MemberIdList::iterator mid = m_activeX->m_eventsIdx.find((MEMBERID) dispIdMember);
-        if (mid == m_activeX->m_eventsIdx.end())
-            return S_OK;
-
-        int idx = mid->second;
-
-        
-        wxActiveX::FuncX &func = m_activeX->m_events[idx];
-
-        ActiveXEventMap::iterator it = sg_eventMap.find(func.name);
-        if (it == sg_eventMap.end())
-            return S_OK;
+    void DispatchEvent(int eventIdx, const wxEventType& eventType, DISPPARAMS * pDispParams)
+    {
+        wxASSERT(eventIdx >= 0 && eventIdx < int(m_activeX->m_events.size()));
+        wxActiveX::FuncX &func = m_activeX->m_events[eventIdx];
 
                wxActiveXEvent  event;
        event.SetId(m_activeX->GetId());
-           event.SetEventType(*(it->second));
+           event.SetEventType(eventType);
         event.m_params.NullList();
+        event.m_params.SetName(func.name);
 
         // arguments
         if (pDispParams)
         {
                        // cdecl call
-            for (int i = pDispParams->cArgs - 1; i >= 0; i--)
+            // sometimes the pDispParams does not match the param info for a activex control
+            int nArg = min(func.params.size(), pDispParams->cArgs);
+            for (int i = nArg - 1; i >= 0; i--)
             {
                 VARIANTARG& va = pDispParams->rgvarg[i];
-                               wxActiveX::ParamX &px = func.params[pDispParams->cArgs - i - 1];
+                               wxActiveX::ParamX &px = func.params[nArg - i - 1];
                 wxVariant vx;
 
-                MSWVariantToVariant(va, vx);
                 vx.SetName(px.name);
+                MSWVariantToVariant(va, vx);
                 event.m_params.Append(vx);
             };
         };
 
                if (func.hasOut)
                {
+            int nArg = min(func.params.size(), pDispParams->cArgs);
                m_activeX->GetParent()->ProcessEvent(event);
-            for (unsigned int i = 0; i < pDispParams->cArgs; i++)
+            for (int i = 0; i < nArg; i++)
             {
                 VARIANTARG& va = pDispParams->rgvarg[i];
-                               wxActiveX::ParamX &px = func.params[pDispParams->cArgs - i - 1];
+                               wxActiveX::ParamX &px = func.params[nArg - i - 1];
 
                                if (px.IsOut())
                                {
-                                       wxVariant& vx = event.m_params[pDispParams->cArgs - i - 1];
-                                       
+                                       wxVariant& vx = event.m_params[nArg - i - 1];
+
                                        VariantToMSWVariant(vx, va);
                                };
                        };
@@ -563,6 +599,43 @@ public:
                else
                m_activeX->GetParent()->AddPendingEvent(event);
 
+    };
+
+       STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
+                                                 WORD wFlags, DISPPARAMS * pDispParams,
+                                                 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
+                                                 unsigned int * puArgErr)
+       {
+           if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
+            return E_NOTIMPL;
+
+        wxASSERT(m_activeX);
+
+        // map dispid to m_eventsIdx
+        wxActiveX::MemberIdList::iterator mid = m_activeX->m_eventsIdx.find((MEMBERID) dispIdMember);
+        if (mid == m_activeX->m_eventsIdx.end())
+            return S_OK;
+
+        int funcIdx = mid->second;
+        wxActiveX::FuncX &func = m_activeX->m_events[funcIdx];
+
+
+        // try to find dispid event
+        ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.find(dispIdMember);
+        if (dit != sg_dispIdEventMap.end())
+        {
+            // Dispatch Event
+            DispatchEvent(funcIdx, *(dit->second), pDispParams);
+               return S_OK;
+        };
+
+        // try named event
+        ActiveXNamedEventMap::iterator nit = sg_NamedEventMap.find(func.name);
+        if (nit == sg_NamedEventMap.end())
+            return S_OK;
+
+        // Dispatch Event
+        DispatchEvent(funcIdx, *(nit->second), pDispParams);
        return S_OK;
     }
 };
@@ -573,12 +646,30 @@ DEFINE_OLE_TABLE(wxActiveXEvents)
        OLE_INTERFACE(IID_IDispatch, IDispatch)
 END_OLE_TABLE;
 
+wxString wxActiveXEvent::EventName()
+{
+    return m_params.GetName();
+};
 
 int wxActiveXEvent::ParamCount() const
 {
     return m_params.GetCount();
 };
 
+wxString wxActiveXEvent::ParamType(int idx)
+{
+    wxASSERT(idx >= 0 && idx < m_params.GetCount());
+
+    return m_params[idx].GetType();
+};
+
+wxString wxActiveXEvent::ParamName(int idx)
+{
+    wxASSERT(idx >= 0 && idx < m_params.GetCount());
+
+    return m_params[idx].GetName();
+};
+
 static wxVariant nullVar;
 
 wxVariant wxActiveXEvent::operator[] (int idx) const
@@ -606,12 +697,12 @@ wxVariant& wxActiveXEvent::operator[] (wxString name)
             return m_params[i];
     };
 
-    wxString err = "wxActiveXEvent::operator[] invalid name <" + name + ">";
-    err += "\r\nValid Names = :\r\n";
+    wxString err = wxT("wxActiveXEvent::operator[] invalid name <") + name + wxT(">");
+    err += wxT("\r\nValid Names = :\r\n");
     for (i = 0; i < m_params.GetCount(); i++)
     {
         err += m_params[i].GetName();
-        err += "\r\n";
+        err += wxT("\r\n");
     };
 
     wxASSERT_MSG(false, err);
@@ -622,15 +713,15 @@ wxVariant& wxActiveXEvent::operator[] (wxString name)
 void wxActiveX::GetTypeInfo()
 {
        /*
-       We are currently only interested in the IDispatch interface 
+       We are currently only interested in the IDispatch interface
        to the control. For dual interfaces (TypeKind = TKIND_INTERFACE)
-       we should drill down through the inheritance 
+       we should drill down through the inheritance
        (using TYPEATTR->cImplTypes) and GetRefTypeOfImplType(n)
-       and retrieve all the func names etc that way, then generate a C++ 
+       and retrieve all the func names etc that way, then generate a C++
        header  file for it.
 
-       But we don't do this and probably never will, so if we have a DUAL 
-       interface then we query for the IDispatch 
+       But we don't do this and probably never will, so if we have a DUAL
+       interface then we query for the IDispatch
        via GetRefTypeOfImplType(-1).
        */
 
@@ -681,12 +772,12 @@ void wxActiveX::GetTypeInfo()
         {
             if (impTypeFlags & IMPLTYPEFLAG_FSOURCE)
             {
-                WXOLE_TRACEOUT("Default Event Sink");
+                WXOLE_TRACEOUT(wxT("Default Event Sink"));
                 defEventSink = true;
             }
             else
             {
-                WXOLE_TRACEOUT("Default Interface");
+                WXOLE_TRACEOUT(wxT("Default Interface"));
             }
         };
 
@@ -713,7 +804,7 @@ void wxActiveX::GetTypeInfo(ITypeInfo *ti, bool defEventSink)
 
        if (ta->typekind == TKIND_DISPATCH)
        {
-        WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
+        WXOLE_TRACEOUT(wxT("GUID = ") << GetIIDName(ta->guid).c_str());
 
         if (defEventSink)
         {
@@ -740,7 +831,7 @@ void wxActiveX::GetTypeInfo(ITypeInfo *ti, bool defEventSink)
                        {
                                wxString name = anames[0];
 
-                               WXOLE_TRACEOUT("Name " << i << " = " << name.c_str());
+                               WXOLE_TRACEOUT(wxT("Name ") << i << wxT(" = ") << name.c_str());
                                SysFreeString(anames[0]);
 
                 if (defEventSink)
@@ -756,18 +847,25 @@ void wxActiveX::GetTypeInfo(ITypeInfo *ti, bool defEventSink)
                     BSTR *pnames = new BSTR[maxPNames];
 
                     hret = typeInfo->GetNames(fd->memid, pnames, maxPNames, &nPNames);
+                    wxASSERT(int(nPNames) >= fd->cParams + 1);
 
                     SysFreeString(pnames[0]);
                                        // params
                                        for (int p = 0; p < fd->cParams; p++)
                                        {
                                                ParamX param;
+
                                                param.flags = fd->lprgelemdescParam[p].idldesc.wIDLFlags;
                                                param.vt = fd->lprgelemdescParam[p].tdesc.vt;
+                        param.isPtr = (param.vt == VT_PTR);
+                        param.isSafeArray = (param.vt == VT_SAFEARRAY);
+                        if (param.isPtr || param.isSafeArray)
+                            param.vt = fd->lprgelemdescParam[p].tdesc.lptdesc->vt;
+
                         param.name = pnames[p + 1];
                         SysFreeString(pnames[p + 1]);
 
-                                               func.hasOut |= param.IsOut();
+                                               func.hasOut |= (param.IsOut() || param.isPtr);
                                                func.params.push_back(param);
                                        };
                     delete [] pnames;
@@ -784,6 +882,17 @@ void wxActiveX::GetTypeInfo(ITypeInfo *ti, bool defEventSink)
        typeInfo->ReleaseTypeAttr(ta);
 };
 
+///////////////////////////////////////////////
+// Type Info exposure
+const wxActiveX::FuncX& wxActiveX::GetEvent(int idx) const
+{
+    wxASSERT(idx >= 0 && idx < GetEventCount());
+
+    return m_events[idx];
+};
+
+///////////////////////////////////////////////
+
 HRESULT wxActiveX::ConnectAdvise(REFIID riid, IUnknown *events)
 {
        wxOleConnectionPoint    cp;
@@ -792,11 +901,11 @@ HRESULT wxActiveX::ConnectAdvise(REFIID riid, IUnknown *events)
        wxAutoOleInterface<IConnectionPointContainer> cpContainer(IID_IConnectionPointContainer, m_ActiveX);
        if (! cpContainer.Ok())
                return E_FAIL;
-       
+
        HRESULT hret = cpContainer->FindConnectionPoint(riid, cp.GetRef());
        if (! SUCCEEDED(hret))
                return hret;
-       
+
        hret = cp->Advise(events, &adviseCookie);
 
        if (SUCCEEDED(hret))
@@ -857,28 +966,153 @@ void wxActiveX::OnSize(wxSizeEvent& event)
        if (w <= 0 && h <= 0)
                return;
 
-       if (m_oleInPlaceObject) 
+       // extents are in HIMETRIC units
+    if (m_oleObject.Ok())
+    {
+        SIZEL sz = {w, h};
+           PixelsToHimetric(sz);
+
+        SIZEL sz2;
+
+        m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
+        if (sz2.cx !=  sz.cx || sz.cy != sz2.cy)
+            m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
+    };
+
+    if (m_oleInPlaceObject.Ok())
                m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
+}
 
-       // extents are in HIMETRIC units
-    SIZEL sz = {w, h};
-       PixelsToHimetric(sz);
+void wxActiveX::OnPaint(wxPaintEvent& event)
+{
+       wxLogTrace(wxT("repainting activex win"));
+       wxPaintDC dc(this);
+       dc.BeginDrawing();
+       int w, h;
+       GetSize(&w, &h);
+       RECT posRect;
+       posRect.left = 0;
+       posRect.top = 0;
+       posRect.right = w;
+       posRect.bottom = h;
 
-    SIZEL sz2;
-    m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
-    if (sz2.cx !=  sz.cx || sz.cy != sz2.cy)
-        m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
+       // Draw only when control is windowless or deactivated
+       if (m_viewObject)
+       {
+               ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
+               {
+                       RECTL *prcBounds = (RECTL *) &posRect;
+                       m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
+                               (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
+               }
+       }
+       else
+       {
+               dc.SetBrush(*wxRED_BRUSH);
+               dc.DrawRectangle(0, 0, w, h);
+               dc.SetBrush(wxNullBrush);
+       }
+       dc.EndDrawing();
 }
 
+
+void wxActiveX::OnMouse(wxMouseEvent& event)
+{
+       if (m_oleObjectHWND == NULL)
+    {
+        wxLogTrace(wxT("no oleInPlaceObject"));
+        event.Skip();
+        return;
+    }
+
+       wxLogTrace(wxT("mouse event"));
+       UINT msg = 0;
+       WPARAM wParam = 0;
+       LPARAM lParam = 0;
+       LRESULT lResult = 0;
+
+       if (event.m_metaDown)
+        wParam |= MK_CONTROL;
+       if (event.m_shiftDown)
+        wParam |= MK_SHIFT;
+       if (event.m_leftDown)
+        wParam |= MK_LBUTTON;
+       if (event.m_middleDown)
+        wParam |= MK_MBUTTON;
+       if (event.m_rightDown)
+        wParam |= MK_RBUTTON;
+       lParam = event.m_x << 16;
+       lParam |= event.m_y;
+
+       if (event.LeftDown())
+        msg = WM_LBUTTONDOWN;
+       else if (event.LeftDClick())
+        msg = WM_LBUTTONDBLCLK;
+       else if (event.LeftUp())
+        msg = WM_LBUTTONUP;
+       else if (event.MiddleDown())
+        msg = WM_MBUTTONDOWN;
+       else if (event.MiddleDClick())
+        msg = WM_MBUTTONDBLCLK;
+       else if (event.MiddleUp())
+        msg = WM_MBUTTONUP;
+       else if (event.RightDown())
+        msg = WM_RBUTTONDOWN;
+       else if (event.RightDClick())
+        msg = WM_RBUTTONDBLCLK;
+       else if (event.RightUp())
+        msg = WM_RBUTTONUP;
+       else if (event.Moving() || event.Dragging())
+        msg = WM_MOUSEMOVE;
+
+       wxString log;
+       if (msg == 0)
+    {
+        wxLogTrace(wxT("no message"));
+        event.Skip(); return;
+    };
+
+       if (!::SendMessage(m_oleObjectHWND, msg, wParam, lParam))
+    {
+        wxLogTrace(wxT("msg not delivered"));
+        event.Skip();
+        return;
+    };
+
+       wxLogTrace(wxT("msg sent"));
+}
+
+long wxActiveX::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+       if (m_oleObjectHWND == NULL)
+        return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
+
+    switch(nMsg)
+    {
+    case WM_CHAR:
+    case WM_DEADCHAR:
+    case WM_KEYDOWN:
+    case WM_KEYUP:
+    case WM_SYSCHAR:
+    case WM_SYSDEADCHAR:
+    case WM_SYSKEYDOWN:
+    case WM_SYSKEYUP:
+        PostMessage(m_oleObjectHWND, nMsg, wParam, lParam);
+
+    default:
+        return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
+    };
+};
+
 void wxActiveX::OnSetFocus(wxFocusEvent& event)
 {
-       if (m_oleInPlaceActiveObject.Ok()) 
+       if (m_oleInPlaceActiveObject.Ok())
         m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
 }
 
 void wxActiveX::OnKillFocus(wxFocusEvent& event)
 {
-       if (m_oleInPlaceActiveObject.Ok()) 
+       if (m_oleInPlaceActiveObject.Ok())
         m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
 }
 
@@ -898,7 +1132,7 @@ FrameSite::FrameSite(wxActiveX * win)
        m_bAmbientShowHatching = true;
        m_bAmbientShowGrabHandles = true;
        m_bAmbientAppearance = true;
+
        m_hDCBuffer = NULL;
        m_hWndParent = (HWND)m_window->GetHWND();
 }
@@ -941,7 +1175,7 @@ HRESULT FrameSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
 
     HRESULT hr;
 
-       if (pVarResult == NULL) 
+       if (pVarResult == NULL)
                return E_INVALIDARG;
 
     //The most common case is boolean, use as an initial type
@@ -1017,7 +1251,7 @@ HRESULT FrameSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
 HRESULT FrameSite::GetWindow(HWND * phwnd)
 {
        WXOLE_TRACE("IOleWindow::GetWindow");
-       if (phwnd == NULL) 
+       if (phwnd == NULL)
         return E_INVALIDARG;
        (*phwnd) = m_hWndParent;
        return S_OK;
@@ -1034,7 +1268,7 @@ HRESULT FrameSite::ContextSensitiveHelp(BOOL fEnterMode)
 HRESULT FrameSite::GetBorder(LPRECT lprectBorder)
 {
        WXOLE_TRACE("IOleInPlaceUIWindow::GetBorder");
-       if (lprectBorder == NULL) 
+       if (lprectBorder == NULL)
         return E_INVALIDARG;
        return INPLACE_E_NOTOOLSPACE;
 }
@@ -1042,7 +1276,7 @@ HRESULT FrameSite::GetBorder(LPRECT lprectBorder)
 HRESULT FrameSite::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
 {
        WXOLE_TRACE("IOleInPlaceUIWindow::RequestBorderSpace");
-       if (pborderwidths == NULL) 
+       if (pborderwidths == NULL)
         return E_INVALIDARG;
        return INPLACE_E_NOTOOLSPACE;
 }
@@ -1139,9 +1373,9 @@ HRESULT FrameSite::GetWindowContext(IOleInPlaceFrame **ppFrame,
        if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL ||
                lprcClipRect == NULL || lpFrameInfo == NULL)
        {
-               if (ppFrame != NULL) 
+               if (ppFrame != NULL)
             (*ppFrame) = NULL;
-               if (ppDoc != NULL) 
+               if (ppDoc != NULL)
             (*ppDoc) = NULL;
                return E_INVALIDARG;
        }
@@ -1231,7 +1465,7 @@ HRESULT FrameSite::OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD dwFlags)
 {
        WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceActivateEx");
        OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
-    if (pfNoRedraw) 
+    if (pfNoRedraw)
         (*pfNoRedraw) = FALSE;
        return S_OK;
 }
@@ -1268,9 +1502,9 @@ HRESULT FrameSite::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,
 HRESULT FrameSite::GetContainer(LPOLECONTAINER * ppContainer)
 {
        WXOLE_TRACE("IOleClientSite::GetContainer");
-       if (ppContainer == NULL) 
+       if (ppContainer == NULL)
         return E_INVALIDARG;
-       
+
     HRESULT hr = QueryInterface(IID_IOleContainer, (void**)(ppContainer));
     wxASSERT(SUCCEEDED(hr));
 
@@ -1323,26 +1557,26 @@ HRESULT FrameSite::LockContainer(BOOL fLock)
 
 //IOleItemContainer
 
-HRESULT FrameSite::GetObject(LPOLESTR pszItem, DWORD dwSpeedNeeded, 
+HRESULT FrameSite::GetObject(LPOLESTR pszItem, DWORD dwSpeedNeeded,
                                                         IBindCtx * pbc, REFIID riid, void ** ppvObject)
 {
        WXOLE_TRACE("IOleItemContainer::GetObject");
-       if (pszItem == NULL) 
+       if (pszItem == NULL)
         return E_INVALIDARG;
-       if (ppvObject == NULL) 
+       if (ppvObject == NULL)
         return E_INVALIDARG;
 
        *ppvObject = NULL;
        return MK_E_NOOBJECT;
 }
 
-HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc, 
+HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc,
                                                                        REFIID riid, void ** ppvStorage)
 {
        WXOLE_TRACE("IOleItemContainer::GetObjectStorage");
-       if (pszItem == NULL) 
+       if (pszItem == NULL)
         return E_INVALIDARG;
-       if (ppvStorage == NULL) 
+       if (ppvStorage == NULL)
         return E_INVALIDARG;
 
        *ppvStorage = NULL;
@@ -1352,7 +1586,7 @@ HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc,
 HRESULT FrameSite::IsRunning(LPOLESTR pszItem)
 {
        WXOLE_TRACE("IOleItemContainer::IsRunning");
-       if (pszItem == NULL) 
+       if (pszItem == NULL)
         return E_INVALIDARG;
 
        return MK_E_NOOBJECT;
@@ -1417,7 +1651,7 @@ HRESULT FrameSite::ShowPropertyFrame()
 
 //IOleCommandTarget
 
-HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds, 
+HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds,
                                                           OLECMD * prgCmds, OLECMDTEXT * pCmdTet)
 {
        WXOLE_TRACE("IOleCommandTarget::QueryStatus");
@@ -1436,8 +1670,8 @@ HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds,
        return S_OK;
 }
 
-HRESULT FrameSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID, 
-                                               DWORD nCmdExecOpt, VARIANTARG * pVaIn, 
+HRESULT FrameSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID,
+                                               DWORD nCmdExecOpt, VARIANTARG * pVaIn,
                                                VARIANTARG * pVaOut)
 {
        WXOLE_TRACE("IOleCommandTarget::Exec");
@@ -1541,49 +1775,49 @@ wxString OLEHResultToString(HRESULT hr)
     switch (hr)
     {
     case S_OK:
-       return "";
+       return wxEmptyString;
 
     case OLECMDERR_E_UNKNOWNGROUP:
-               return "The pguidCmdGroup parameter is not NULL but does not specify a recognized command group.";
+               return wxT("The pguidCmdGroup parameter is not NULL but does not specify a recognized command group.");
 
     case OLECMDERR_E_NOTSUPPORTED:
-               return "The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup.";
+               return wxT("The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup.");
 
     case OLECMDERR_E_DISABLED:
-               return "The command identified by nCmdID is currently disabled and cannot be executed.";
+               return wxT("The command identified by nCmdID is currently disabled and cannot be executed.");
 
     case OLECMDERR_E_NOHELP:
-               return "The caller has asked for help on the command identified by nCmdID, but no help is available.";
+               return wxT("The caller has asked for help on the command identified by nCmdID, but no help is available.");
 
     case OLECMDERR_E_CANCELED:
-               return "The user canceled the execution of the command.";
+               return wxT("The user canceled the execution of the command.");
 
     case E_INVALIDARG:
-        return "E_INVALIDARG";
+        return wxT("E_INVALIDARG");
 
     case E_OUTOFMEMORY:
-        return "E_OUTOFMEMORY";
+        return wxT("E_OUTOFMEMORY");
 
     case E_NOINTERFACE:
-        return "E_NOINTERFACE";
+        return wxT("E_NOINTERFACE");
 
     case E_UNEXPECTED:
-        return "E_UNEXPECTED";
+        return wxT("E_UNEXPECTED");
 
     case STG_E_INVALIDFLAG:
-        return "STG_E_INVALIDFLAG";
+        return wxT("STG_E_INVALIDFLAG");
 
     case E_FAIL:
-        return "E_FAIL";
+        return wxT("E_FAIL");
 
     case E_NOTIMPL:
-        return "E_NOTIMPL";
+        return wxT("E_NOTIMPL");
 
     default:
         {
-            char buf[64];
-            sprintf(buf, "Unknown - 0x%X", hr);
-            return wxString(buf);
+            wxString buf;
+            buf.Printf(wxT("Unknown - 0x%X"), hr);
+            return buf;
         }
     };
 };
@@ -1592,7 +1826,7 @@ wxString OLEHResultToString(HRESULT hr)
 wxString GetIIDName(REFIID riid)
 {
   // an association between symbolic name and numeric value of an IID
-  struct KNOWN_IID 
+  struct KNOWN_IID
   {
     const IID  *pIid;
     const wxChar *szName;
@@ -1602,7 +1836,7 @@ wxString GetIIDName(REFIID riid)
   #define ADD_KNOWN_IID(name) { &IID_I##name, _T(#name) }
   #define ADD_KNOWN_GUID(name) { &name, _T(#name) }
 
-  static const KNOWN_IID aKnownIids[] = 
+  static const KNOWN_IID aKnownIids[] =
   {
     ADD_KNOWN_IID(AdviseSink),
     ADD_KNOWN_IID(AdviseSink2),
@@ -1696,9 +1930,9 @@ wxString GetIIDName(REFIID riid)
   #undef ADD_KNOWN_GUID
 
   // try to find the interface in the table
-  for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ ) 
+  for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ )
   {
-    if ( riid == *aKnownIids[ui].pIid ) 
+    if ( riid == *aKnownIids[ui].pIid )
     {
       return aKnownIids[ui].szName;
     }
@@ -1714,5 +1948,5 @@ wxString GetIIDName(REFIID riid)
       return s;
   }
   else
-      return "StringFromIID() error";
+      return wxT("StringFromIID() error");
 }