]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/ole/activex.cpp
added a section about Connect(), improve/streamline the one about event tables
[wxWidgets.git] / src / msw / ole / activex.cpp
index 8dea8ef980255b53d70b907d3a885b5e90266325..e8e7647a4850c8cc6ccfc25a1ff095d4455a9dac 100644 (file)
@@ -1,34 +1,51 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        msw/ole/activex.cpp
+// Name:        src/msw/ole/activex.cpp
 // Purpose:     wxActiveXContainer implementation
 // Author:      Ryan Norton <wxprojects@comcast.net>, Lindsay Mathieson <???>
-// Modified by: 
+// Modified by:
 // Created:     11/07/04
 // RCS-ID:      $Id$
 // Copyright:   (c) 2003 Lindsay Mathieson, (c) 2005 Ryan Norton
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-//===========================================================================
-//  DECLARATIONS
-//===========================================================================
+// ============================================================================
+// declarations
+// ============================================================================
 
-//---------------------------------------------------------------------------
-// WX include
-//---------------------------------------------------------------------------
-#include "wx/wxprec.h"
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
 
-#include "wx/msw/ole/activex.h"
+#include "wx/wxprec.h"
 
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
 
+#if wxUSE_ACTIVEX
 
+#ifndef WX_PRECOMP
+    #include "wx/dcclient.h"
+    #include "wx/math.h"
+#endif
 
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-//
-// wxActiveXContainer
-//
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#include "wx/msw/dc.h"
 
+#include "wx/msw/ole/activex.h"
+// autointerfaces that we only use here
+WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite, IOleInPlaceSite)
+WX_DECLARE_AUTOOLE(wxAutoIOleDocument, IOleDocument)
+WX_DECLARE_AUTOOLE(wxAutoIPersistStreamInit, IPersistStreamInit)
+WX_DECLARE_AUTOOLE(wxAutoIAdviseSink, IAdviseSink)
+WX_DECLARE_AUTOOLE(wxAutoIProvideClassInfo, IProvideClassInfo)
+WX_DECLARE_AUTOOLE(wxAutoITypeInfo, ITypeInfo)
+WX_DECLARE_AUTOOLE(wxAutoIConnectionPoint, IConnectionPoint)
+WX_DECLARE_AUTOOLE(wxAutoIConnectionPointContainer, IConnectionPointContainer)
+
+DEFINE_EVENT_TYPE(wxEVT_ACTIVEX)
+
+// Ole class helpers (sort of MFC-like) from wxActiveX
 #define DECLARE_OLE_UNKNOWN(cls)\
     private:\
     class TAutoInitInt\
         if (! ppvObject)\
         {\
             return E_FAIL;\
-        };\
+        }\
         const char *desc = NULL;\
         cls::_GetInterface(this, iid, ppvObject, desc);\
         if (! *ppvObject)\
         {\
             return E_NOINTERFACE;\
-        };\
+        }\
         ((IUnknown * )(*ppvObject))->AddRef();\
         return S_OK;\
-    };\
+    }\
     ULONG STDMETHODCALLTYPE cls::AddRef()\
     {\
         InterlockedIncrement(&refCount.l);\
         return refCount.l;\
-    };\
+    }\
     ULONG STDMETHODCALLTYPE cls::Release()\
     {\
         if (refCount.l > 0)\
@@ -78,7 +95,7 @@
             {\
                 delete this;\
                 return 0;\
-            };\
+            }\
             return refCount.l;\
         }\
         else\
     {\
         InterlockedIncrement(&lockCount.l);\
         return lockCount.l;\
-    };\
+    }\
     ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
     {\
         if (lockCount.l > 0)\
 #define END_OLE_TABLE\
     }
 
+// ============================================================================
+// implementation
+// ============================================================================
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// PixelsToHimetric
+//
+// Utility to convert from pixels to the himetric values in some COM methods
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
+#define HIMETRIC_PER_INCH   2540
+#define MAP_PIX_TO_LOGHIM(x,ppli)   MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
 
+static void PixelsToHimetric(SIZEL &sz)
+{
+    static int logX = 0;
+    static int logY = 0;
+
+    if (logY == 0)
+    {
+        // initaliase
+        HDC dc = GetDC(NULL);
+        logX = GetDeviceCaps(dc, LOGPIXELSX);
+        logY = GetDeviceCaps(dc, LOGPIXELSY);
+        ReleaseDC(NULL, dc);
+    };
+
+#define HIMETRIC_INCH   2540
+#define CONVERT(x, logpixels)   wxMulDivInt32(HIMETRIC_INCH, (x), (logpixels))
+
+    sz.cx = CONVERT(sz.cx, logX);
+    sz.cy = CONVERT(sz.cy, logY);
+
+#undef CONVERT
+#undef HIMETRIC_INCH
+}
+
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+// FrameSite
+//
+// Handles the actual wxActiveX container implementation
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 class FrameSite :
     public IOleClientSite,
     public IOleInPlaceSiteEx,
@@ -321,7 +383,7 @@ public:
         if (! SUCCEEDED(hr))
         {
             return E_UNEXPECTED;
-        };
+        }
 
         hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
         if (! SUCCEEDED(hr))
@@ -329,7 +391,7 @@ public:
             (*ppFrame)->Release();
             *ppFrame = NULL;
             return E_UNEXPECTED;
-        };
+        }
 
         RECT rect;
         ::GetClientRect(m_hWndParent, &rect);
@@ -338,13 +400,13 @@ public:
             lprcPosRect->left = lprcPosRect->top = 0;
             lprcPosRect->right = rect.right;
             lprcPosRect->bottom = rect.bottom;
-        };
+        }
         if (lprcClipRect)
         {
             lprcClipRect->left = lprcClipRect->top = 0;
             lprcClipRect->right = rect.right;
             lprcClipRect->bottom = rect.bottom;
-        };
+        }
 
         memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
         lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
@@ -363,15 +425,35 @@ public:
     {
         if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
         {
+           //
+           // Result of several hours and days of bug hunting -
+           // this is called by an object when it wants to resize
+           // itself to something different then our parent window -
+           // don't let it :)
+           //
+//            m_window->m_oleInPlaceObject->SetObjectRects(
+//                lprcPosRect, lprcPosRect);
+           RECT rcClient;
+           ::GetClientRect(m_hWndParent, &rcClient);
             m_window->m_oleInPlaceObject->SetObjectRects(
-                lprcPosRect, lprcPosRect);
+                &rcClient, &rcClient);
         }
         return S_OK;
     }
     //*************************IOleInPlaceSiteEx***********************
     HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD)
     {
+#ifdef __WXWINCE__
+        IRunnableObject* runnable = NULL;
+        HRESULT hr = QueryInterface(
+            IID_IRunnableObject, (void**)(& runnable));
+        if (SUCCEEDED(hr))
+        {
+            runnable->LockRunning(TRUE, FALSE);
+        }
+#else
         OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
+#endif
         if (pfNoRedraw)
             (*pfNoRedraw) = FALSE;
         return S_OK;
@@ -379,7 +461,17 @@ public:
 
     HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL)
     {
+#ifdef __WXWINCE__
+        IRunnableObject* runnable = NULL;
+        HRESULT hr = QueryInterface(
+            IID_IRunnableObject, (void**)(& runnable));
+        if (SUCCEEDED(hr))
+        {
+            runnable->LockRunning(FALSE, FALSE);
+        }
+#else
         OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
+#endif
         return S_OK;
     }
     STDMETHOD(RequestUIActivate)(){ return S_OK;}
@@ -394,8 +486,8 @@ public:
         case OLEGETMONIKER_UNASSIGN     : return "OLEGETMONIKER_UNASSIGN";
         case OLEGETMONIKER_TEMPFORUSER  : return "OLEGETMONIKER_TEMPFORUSER";
         default                         : return "Bad Enum";
-        };
-    };
+        }
+    }
 
     const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
     {
@@ -405,8 +497,8 @@ public:
         case OLEWHICHMK_OBJREL      : return "OLEWHICHMK_OBJREL";
         case OLEWHICHMK_OBJFULL     : return "OLEWHICHMK_OBJFULL";
         default                     : return "Bad Enum";
-        };
-    };
+        }
+    }
     STDMETHOD(GetMoniker)(DWORD, DWORD, IMoniker **){return E_FAIL;}
     HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer)
     {
@@ -433,7 +525,9 @@ public:
     HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;}
     //********************IOleItemContainer***************************
     HRESULT STDMETHODCALLTYPE
-    #ifdef _UNICODE
+    #if 0 // defined(__WXWINCE__) && __VISUALC__ < 1400
+    GetObject
+    #elif defined(_UNICODE)
     GetObjectW
     #else
     GetObjectA
@@ -531,11 +625,11 @@ public:
                 return E_FAIL;
 
             m_window->m_docView->SetInPlaceSite(inPlaceSite);
-        };
+        }
 
         m_window->m_docView->UIActivate(TRUE);
         return S_OK;
-    };
+    }
 
 
 protected:
@@ -574,10 +668,135 @@ DEFINE_OLE_TABLE(FrameSite)
     OLE_IINTERFACE(IOleDocumentSite)
     OLE_IINTERFACE(IAdviseSink)
     OLE_IINTERFACE(IOleControlSite)
-END_OLE_TABLE;
+END_OLE_TABLE
+
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+// wxActiveXEvents
+//
+// Handles and sends activex events received from the ActiveX control
+// to the appropriate wxEvtHandler
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+class wxActiveXEvents : public IDispatch
+{
+private:
+    DECLARE_OLE_UNKNOWN(wxActiveXEvents);
+
+
+    wxActiveXContainer *m_activeX;
+    IID m_customId;
+    bool m_haveCustomId;
+
+    friend bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc);
+
+public:
+    wxActiveXEvents(wxActiveXContainer *ax) : m_activeX(ax), m_haveCustomId(false) {}
+    wxActiveXEvents(wxActiveXContainer *ax, REFIID iid) : m_activeX(ax), m_customId(iid), m_haveCustomId(true) {}
+    virtual ~wxActiveXEvents()
+    {
+    }
+
+    // IDispatch
+    STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*)
+    {
+        return E_NOTIMPL;
+    }
+
+    STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**)
+    {
+        return E_NOTIMPL;
+    }
+
+    STDMETHODIMP GetTypeInfoCount(unsigned int*)
+    {
+        return E_NOTIMPL;
+    }
+
+
+    STDMETHODIMP Invoke(DISPID dispIdMember, REFIID WXUNUSED(riid),
+                        LCID WXUNUSED(lcid),
+                          WORD wFlags, DISPPARAMS * pDispParams,
+                          VARIANT * WXUNUSED(pVarResult), EXCEPINFO * WXUNUSED(pExcepInfo),
+                          unsigned int * WXUNUSED(puArgErr))
+    {
+        if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
+            return E_NOTIMPL;
 
+        wxASSERT(m_activeX);
 
-wxActiveXContainer::wxActiveXContainer(wxWindow * parent, REFIID iid, IUnknown* pUnk)
+        // ActiveX Event
+
+        // Dispatch Event
+        wxActiveXEvent  event;
+        event.SetEventType(wxEVT_ACTIVEX);
+        event.m_params.NullList();
+        event.m_dispid = dispIdMember;
+
+        // arguments
+        if (pDispParams)
+        {
+            for (DWORD i = pDispParams->cArgs; i > 0; i--)
+            {
+                VARIANTARG& va = pDispParams->rgvarg[i-1];
+                wxVariant vx;
+
+//                        vx.SetName(px.name);
+                wxConvertOleToVariant(va, vx);
+                event.m_params.Append(vx);
+            }
+        }
+
+        // process the events from the activex method
+           m_activeX->ProcessEvent(event);
+        for (DWORD i = 0; i < pDispParams->cArgs; i++)
+        {
+            VARIANTARG& va = pDispParams->rgvarg[i];
+            wxVariant& vx =
+                event.m_params[pDispParams->cArgs - i - 1];
+            wxConvertVariantToOle(vx, va);
+        }
+
+        if(event.GetSkipped())
+            return DISP_E_MEMBERNOTFOUND;
+
+        return S_OK;
+    }
+};
+
+bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc)
+{
+    if (self->m_haveCustomId && IsEqualIID(iid, self->m_customId))
+    {
+//        WXOLE_TRACE("Found Custom Dispatch Interface");
+        *_interface = (IUnknown *) (IDispatch *) self;
+        desc = "Custom Dispatch Interface";
+        return true;
+    }
+
+    return false;
+}
+
+DEFINE_OLE_TABLE(wxActiveXEvents)
+    OLE_IINTERFACE(IUnknown)
+    OLE_INTERFACE(IID_IDispatch, IDispatch)
+    OLE_INTERFACE_CUSTOM(wxActiveXEventsInterface)
+END_OLE_TABLE
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+// wxActiveXContainer
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+//---------------------------------------------------------------------------
+// wxActiveXContainer Constructor
+//
+// Initializes members and creates the native ActiveX container
+//---------------------------------------------------------------------------
+wxActiveXContainer::wxActiveXContainer(wxWindow * parent,
+                                       REFIID iid, IUnknown* pUnk)
     : m_realparent(parent)
 {
     m_bAmbientUserMode = true;
@@ -585,6 +804,12 @@ wxActiveXContainer::wxActiveXContainer(wxWindow * parent, REFIID iid, IUnknown*
     CreateActiveX(iid, pUnk);
 }
 
+//---------------------------------------------------------------------------
+// wxActiveXContainer Destructor
+//
+// Destroys members (the FrameSite et al. are destroyed implicitly
+// through COM ref counting)
+//---------------------------------------------------------------------------
 wxActiveXContainer::~wxActiveXContainer()
 {
     // disconnect connection points
@@ -606,6 +831,14 @@ wxActiveXContainer::~wxActiveXContainer()
     }
 }
 
+//---------------------------------------------------------------------------
+// wxActiveXContainer::CreateActiveX
+//
+// Actually creates the ActiveX container through the FrameSite
+// and sets up ActiveX events
+//
+// TODO: Document this more
+//---------------------------------------------------------------------------
 void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
 {
     HRESULT hret;
@@ -625,6 +858,105 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
     // Get Dispatch interface
     hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
 
+    //
+    // SETUP TYPEINFO AND ACTIVEX EVENTS
+    //
+
+    // get type info via class info
+    wxAutoIProvideClassInfo classInfo(IID_IProvideClassInfo, m_ActiveX);
+    wxASSERT(classInfo.Ok());
+
+    // type info
+    wxAutoITypeInfo typeInfo;
+    hret = classInfo->GetClassInfo(typeInfo.GetRef());
+    wxASSERT(typeInfo.Ok());
+
+    // TYPEATTR
+    TYPEATTR *ta = NULL;
+    hret = typeInfo->GetTypeAttr(&ta);
+    wxASSERT(ta);
+
+    // this should be a TKIND_COCLASS
+    wxASSERT(ta->typekind == TKIND_COCLASS);
+
+    // iterate contained interfaces
+    for (int i = 0; i < ta->cImplTypes; i++)
+    {
+        HREFTYPE rt = 0;
+
+        // get dispatch type info handle
+        hret = typeInfo->GetRefTypeOfImplType(i, &rt);
+        if (! SUCCEEDED(hret))
+            continue;
+
+        // get dispatch type info interface
+        wxAutoITypeInfo  ti;
+        hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef());
+        if (! ti.Ok())
+            continue;
+
+        // check if default event sink
+        bool defEventSink = false;
+        int impTypeFlags = 0;
+        typeInfo->GetImplTypeFlags(i, &impTypeFlags);
+
+        if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT)
+        {
+            if (impTypeFlags & IMPLTYPEFLAG_FSOURCE)
+            {
+                // WXOLE_TRACEOUT("Default Event Sink");
+                defEventSink = true;
+                if (impTypeFlags & IMPLTYPEFLAG_FDEFAULTVTABLE)
+                {
+                    // WXOLE_TRACEOUT("*ERROR* - Default Event Sink is via vTable");
+                    defEventSink = false;
+                    wxFAIL_MSG(wxT("Default event sink is in vtable!"));
+                }
+            }
+        }
+
+
+        // wxAutoOleInterface<> assumes a ref has already been added
+        // TYPEATTR
+        TYPEATTR *ta = NULL;
+        hret = ti->GetTypeAttr(&ta);
+        wxASSERT(ta);
+
+        if (ta->typekind == TKIND_DISPATCH)
+        {
+            // WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
+            if (defEventSink)
+            {
+                wxAutoIConnectionPoint    cp;
+                DWORD                    adviseCookie = 0;
+
+                wxAutoIConnectionPointContainer cpContainer(IID_IConnectionPointContainer, m_ActiveX);
+                wxASSERT( cpContainer.Ok());
+
+                HRESULT hret =
+                    cpContainer->FindConnectionPoint(ta->guid, cp.GetRef());
+                wxASSERT ( SUCCEEDED(hret));
+
+                IDispatch* disp;
+                frame->QueryInterface(IID_IDispatch, (void**)&disp);
+                hret = cp->Advise(new wxActiveXEvents(this, ta->guid),
+                                  &adviseCookie);
+                wxASSERT_MSG( SUCCEEDED(hret),
+                    wxString::Format(wxT("Cannot connect!\nHRESULT:%X"), (unsigned int)hret)
+                            );
+            }
+        }
+
+        ti->ReleaseTypeAttr(ta);
+    }
+
+    // free
+    typeInfo->ReleaseTypeAttr(ta);
+
+    //
+    // END
+    //
+
     // Get IOleObject interface
     hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
     wxASSERT(SUCCEEDED(hret));
@@ -636,6 +968,8 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
     // document advise
     m_docAdviseCookie = 0;
     hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
+    // TODO:Needed?
+//    hret = m_viewObject->SetAdvise(DVASPECT_CONTENT, 0, adviseSink);
     m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
     OleSetContainedObject(m_oleObject, TRUE);
     OleRun(m_oleObject);
@@ -712,6 +1046,8 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
 
         pWnd->Connect(id, wxEVT_SIZE,
             wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this);
+//        this->Connect(GetId(), wxEVT_PAINT,
+//            wxPaintEventHandler(wxActiveXContainer::OnPaint), 0, this);
         pWnd->Connect(id, wxEVT_SET_FOCUS,
             wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this);
         pWnd->Connect(id, wxEVT_KILL_FOCUS,
@@ -719,34 +1055,12 @@ void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
     }
 }
 
-#define HIMETRIC_PER_INCH   2540
-#define MAP_PIX_TO_LOGHIM(x,ppli)   MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
-
-static void PixelsToHimetric(SIZEL &sz)
-{
-    static int logX = 0;
-    static int logY = 0;
-
-    if (logY == 0)
-    {
-        // initaliase
-        HDC dc = GetDC(NULL);
-        logX = GetDeviceCaps(dc, LOGPIXELSX);
-        logY = GetDeviceCaps(dc, LOGPIXELSY);
-        ReleaseDC(NULL, dc);
-    };
-
-#define HIMETRIC_INCH   2540
-#define CONVERT(x, logpixels)   MulDiv(HIMETRIC_INCH, (x), (logpixels))
-
-    sz.cx = CONVERT(sz.cx, logX);
-    sz.cy = CONVERT(sz.cy, logY);
-
-#undef CONVERT
-#undef HIMETRIC_INCH
-}
-
-
+//---------------------------------------------------------------------------
+// wxActiveXContainer::OnSize
+//
+// Called when the parent is resized - we need to do this to actually
+// move the ActiveX control to where the parent is
+//---------------------------------------------------------------------------
 void wxActiveXContainer::OnSize(wxSizeEvent& event)
 {
     int w, h;
@@ -764,6 +1078,9 @@ void wxActiveXContainer::OnSize(wxSizeEvent& event)
     // extents are in HIMETRIC units
     if (m_oleObject.Ok())
     {
+        m_oleObject->DoVerb(OLEIVERB_HIDE, 0, m_clientSite, 0,
+            (HWND)m_realparent->GetHWND(), &posRect);
+
         SIZEL sz = {w, h};
         PixelsToHimetric(sz);
 
@@ -772,7 +1089,10 @@ void wxActiveXContainer::OnSize(wxSizeEvent& event)
         m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
         if (sz2.cx !=  sz.cx || sz.cy != sz2.cy)
             m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
-    };
+
+        m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
+            (HWND)m_realparent->GetHWND(), &posRect);
+    }
 
     if (m_oleInPlaceObject.Ok())
         m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
@@ -780,13 +1100,17 @@ void wxActiveXContainer::OnSize(wxSizeEvent& event)
     event.Skip();
 }
 
+//---------------------------------------------------------------------------
+// wxActiveXContainer::OnPaint
+//
+// Called when the parent is resized - repaints the ActiveX control
+//---------------------------------------------------------------------------
 void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
 {
     wxPaintDC dc(this);
     // Draw only when control is windowless or deactivated
     if (m_viewObject)
     {
-        dc.BeginDrawing();
         int w, h;
         GetParent()->GetSize(&w, &h);
         RECT posRect;
@@ -795,18 +1119,23 @@ void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
         posRect.right = w;
         posRect.bottom = h;
 
+#if !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
         ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
+#else
+        ::InvalidateRect(m_oleObjectHWND, NULL, false);
+#endif
         RECTL *prcBounds = (RECTL *) &posRect;
+        wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl );
         m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
-            (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
-
-        dc.EndDrawing();
+            (HDC)msw->GetHDC(), prcBounds, NULL, NULL, 0);
     }
-
-//  We've got this one I think
-//    event.Skip();
 }
 
+//---------------------------------------------------------------------------
+// wxActiveXContainer::OnSetFocus
+//
+// Called when the focus is set on the parent - activates the activex control
+//---------------------------------------------------------------------------
 void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
 {
     if (m_oleInPlaceActiveObject.Ok())
@@ -815,6 +1144,12 @@ void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
     event.Skip();
 }
 
+//---------------------------------------------------------------------------
+// wxActiveXContainer::OnKillFocus
+//
+// Called when the focus is killed on the parent -
+// deactivates the activex control
+//---------------------------------------------------------------------------
 void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
 {
     if (m_oleInPlaceActiveObject.Ok())
@@ -822,3 +1157,5 @@ void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
 
     event.Skip();
 }
+
+#endif // wxUSE_ACTIVEX