1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/msw/ole/activex.cpp
3 // Purpose:     wxActiveXContainer implementation
4 // Author:      Ryan Norton <wxprojects@comcast.net>, Lindsay Mathieson <???>
5 // Modified by:
6 // Created:     11/07/04
7 // RCS-ID:      $Id: activex.cpp 42688 2006-10-29 23:38:37Z VZ $
8 // Copyright:   (c) 2003 Lindsay Mathieson, (c) 2005 Ryan Norton
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 // ============================================================================
13 // declarations
14 // ============================================================================
15 
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19 
20 #include "wx/wxprec.h"
21 
22 #ifdef __BORLANDC__
23     #pragma hdrstop
24 #endif
25 
26 #if wxUSE_ACTIVEX
27 
28 #ifndef WX_PRECOMP
29     #include "wx/dcclient.h"
30     #include "wx/math.h"
31 #endif
32 
33 #include "wx/msw/ole/activex.h"
34 // autointerfaces that we only use here
WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite,IOleInPlaceSite)35 WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite, IOleInPlaceSite)
36 WX_DECLARE_AUTOOLE(wxAutoIOleDocument, IOleDocument)
37 WX_DECLARE_AUTOOLE(wxAutoIPersistStreamInit, IPersistStreamInit)
38 WX_DECLARE_AUTOOLE(wxAutoIAdviseSink, IAdviseSink)
39 WX_DECLARE_AUTOOLE(wxAutoIProvideClassInfo, IProvideClassInfo)
40 WX_DECLARE_AUTOOLE(wxAutoITypeInfo, ITypeInfo)
41 WX_DECLARE_AUTOOLE(wxAutoIConnectionPoint, IConnectionPoint)
42 WX_DECLARE_AUTOOLE(wxAutoIConnectionPointContainer, IConnectionPointContainer)
43 
44 DEFINE_EVENT_TYPE(wxEVT_ACTIVEX)
45 
46 // Ole class helpers (sort of MFC-like) from wxActiveX
47 #define DECLARE_OLE_UNKNOWN(cls)\
48     private:\
49     class TAutoInitInt\
50     {\
51         public:\
52         LONG l;\
53         TAutoInitInt() : l(0) {}\
54     };\
55     TAutoInitInt refCount, lockCount;\
56     static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\
57     public:\
58     LONG GetRefCount();\
59     HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\
60     ULONG STDMETHODCALLTYPE AddRef();\
61     ULONG STDMETHODCALLTYPE Release();\
62     ULONG STDMETHODCALLTYPE AddLock();\
63     ULONG STDMETHODCALLTYPE ReleaseLock()
64 
65 #define DEFINE_OLE_TABLE(cls)\
66     LONG cls::GetRefCount() {return refCount.l;}\
67     HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\
68     {\
69         if (! ppvObject)\
70         {\
71             return E_FAIL;\
72         }\
73         const char *desc = NULL;\
74         cls::_GetInterface(this, iid, ppvObject, desc);\
75         if (! *ppvObject)\
76         {\
77             return E_NOINTERFACE;\
78         }\
79         ((IUnknown * )(*ppvObject))->AddRef();\
80         return S_OK;\
81     }\
82     ULONG STDMETHODCALLTYPE cls::AddRef()\
83     {\
84         InterlockedIncrement(&refCount.l);\
85         return refCount.l;\
86     }\
87     ULONG STDMETHODCALLTYPE cls::Release()\
88     {\
89         if (refCount.l > 0)\
90         {\
91             InterlockedDecrement(&refCount.l);\
92             if (refCount.l == 0)\
93             {\
94                 delete this;\
95                 return 0;\
96             }\
97             return refCount.l;\
98         }\
99         else\
100             return 0;\
101     }\
102     ULONG STDMETHODCALLTYPE cls::AddLock()\
103     {\
104         InterlockedIncrement(&lockCount.l);\
105         return lockCount.l;\
106     }\
107     ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
108     {\
109         if (lockCount.l > 0)\
110         {\
111             InterlockedDecrement(&lockCount.l);\
112             return lockCount.l;\
113         }\
114         else\
115             return 0;\
116     }\
117     DEFINE_OLE_BASE(cls)
118 
119 #define DEFINE_OLE_BASE(cls)\
120     void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\
121     {\
122         *_interface = NULL;\
123         desc = NULL;
124 
125 #define OLE_INTERFACE(_iid, _type)\
126     if (IsEqualIID(iid, _iid))\
127     {\
128         *_interface = (IUnknown *) (_type *) self;\
129         desc = # _iid;\
130         return;\
131     }
132 
133 #define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face)
134 
135 #define OLE_INTERFACE_CUSTOM(func)\
136     if (func(self, iid, _interface, desc))\
137     {\
138         return;\
139     }
140 
141 #define END_OLE_TABLE\
142     }
143 
144 // ============================================================================
145 // implementation
146 // ============================================================================
147 
148 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
149 // PixelsToHimetric
150 //
151 // Utility to convert from pixels to the himetric values in some COM methods
152 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
153 
154 
155 #define HIMETRIC_PER_INCH   2540
156 #define MAP_PIX_TO_LOGHIM(x,ppli)   MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
157 
158 static void PixelsToHimetric(SIZEL &sz)
159 {
160     static int logX = 0;
161     static int logY = 0;
162 
163     if (logY == 0)
164     {
165         // initaliase
166         HDC dc = GetDC(NULL);
167         logX = GetDeviceCaps(dc, LOGPIXELSX);
168         logY = GetDeviceCaps(dc, LOGPIXELSY);
169         ReleaseDC(NULL, dc);
170     };
171 
172 #define HIMETRIC_INCH   2540
173 #define CONVERT(x, logpixels)   wxMulDivInt32(HIMETRIC_INCH, (x), (logpixels))
174 
175     sz.cx = CONVERT(sz.cx, logX);
176     sz.cy = CONVERT(sz.cy, logY);
177 
178 #undef CONVERT
179 #undef HIMETRIC_INCH
180 }
181 
182 
183 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
184 //
185 // FrameSite
186 //
187 // Handles the actual wxActiveX container implementation
188 //
189 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
190 class FrameSite :
191     public IOleClientSite,
192     public IOleInPlaceSiteEx,
193     public IOleInPlaceFrame,
194     public IOleItemContainer,
195     public IDispatch,
196     public IOleCommandTarget,
197     public IOleDocumentSite,
198     public IAdviseSink,
199     public IOleControlSite
200 {
201 private:
202     DECLARE_OLE_UNKNOWN(FrameSite);
203 
204 public:
FrameSite(wxWindow * win,wxActiveXContainer * win2)205     FrameSite(wxWindow * win, wxActiveXContainer * win2)
206     {
207         m_window = win2;
208         m_bSupportsWindowlessActivation = true;
209         m_bInPlaceLocked = false;
210         m_bUIActive = false;
211         m_bInPlaceActive = false;
212         m_bWindowless = false;
213 
214         m_nAmbientLocale = 0;
215         m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT);
216         m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW);
217         m_bAmbientShowHatching = true;
218         m_bAmbientShowGrabHandles = true;
219         m_bAmbientAppearance = true;
220 
221         m_hDCBuffer = NULL;
222         m_hWndParent = (HWND)win->GetHWND();
223     }
~FrameSite()224     virtual ~FrameSite(){}
225     //***************************IDispatch*****************************
GetIDsOfNames(REFIID,OLECHAR **,unsigned int,LCID,DISPID *)226     HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, OLECHAR ** ,
227                                             unsigned int , LCID ,
228                                             DISPID * )
229     {   return E_NOTIMPL;   }
STDMETHOD(GetTypeInfo)230     STDMETHOD(GetTypeInfo)(unsigned int, LCID, ITypeInfo **)
231     {   return E_NOTIMPL;   }
GetTypeInfoCount(unsigned int *)232     HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *)
233     {   return E_NOTIMPL;   }
Invoke(DISPID dispIdMember,REFIID,LCID,WORD wFlags,DISPPARAMS *,VARIANT * pVarResult,EXCEPINFO *,unsigned int *)234     HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID, LCID,
235                             WORD wFlags, DISPPARAMS *,
236                             VARIANT * pVarResult, EXCEPINFO *,
237                             unsigned int *)
238     {
239         if (!(wFlags & DISPATCH_PROPERTYGET))
240             return S_OK;
241 
242         if (pVarResult == NULL)
243             return E_INVALIDARG;
244 
245         //The most common case is boolean, use as an initial type
246         V_VT(pVarResult) = VT_BOOL;
247 
248         switch (dispIdMember)
249         {
250             case DISPID_AMBIENT_MESSAGEREFLECT:
251                 V_BOOL(pVarResult)= FALSE;
252                 return S_OK;
253 
254             case DISPID_AMBIENT_DISPLAYASDEFAULT:
255                 V_BOOL(pVarResult)= TRUE;
256                 return S_OK;
257 
258             case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
259                 V_BOOL(pVarResult) = TRUE;
260                 return S_OK;
261 
262             case DISPID_AMBIENT_SILENT:
263                 V_BOOL(pVarResult)= TRUE;
264                 return S_OK;
265 
266             case DISPID_AMBIENT_APPEARANCE:
267                 pVarResult->vt = VT_BOOL;
268                 pVarResult->boolVal = m_bAmbientAppearance;
269                 break;
270 
271             case DISPID_AMBIENT_FORECOLOR:
272                 pVarResult->vt = VT_I4;
273                 pVarResult->lVal = (long) m_clrAmbientForeColor;
274                 break;
275 
276             case DISPID_AMBIENT_BACKCOLOR:
277                 pVarResult->vt = VT_I4;
278                 pVarResult->lVal = (long) m_clrAmbientBackColor;
279                 break;
280 
281             case DISPID_AMBIENT_LOCALEID:
282                 pVarResult->vt = VT_I4;
283                 pVarResult->lVal = (long) m_nAmbientLocale;
284                 break;
285 
286             case DISPID_AMBIENT_USERMODE:
287                 pVarResult->vt = VT_BOOL;
288                 pVarResult->boolVal = m_window->m_bAmbientUserMode;
289                 break;
290 
291             case DISPID_AMBIENT_SHOWGRABHANDLES:
292                 pVarResult->vt = VT_BOOL;
293                 pVarResult->boolVal = m_bAmbientShowGrabHandles;
294                 break;
295 
296             case DISPID_AMBIENT_SHOWHATCHING:
297                 pVarResult->vt = VT_BOOL;
298                 pVarResult->boolVal = m_bAmbientShowHatching;
299                 break;
300 
301             default:
302                 return DISP_E_MEMBERNOTFOUND;
303         }
304 
305         return S_OK;
306     }
307 
308     //**************************IOleWindow***************************
GetWindow(HWND * phwnd)309     HRESULT STDMETHODCALLTYPE GetWindow(HWND * phwnd)
310     {
311         if (phwnd == NULL)
312             return E_INVALIDARG;
313         (*phwnd) = m_hWndParent;
314         return S_OK;
315     }
ContextSensitiveHelp(BOOL)316     HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL)
317     {return S_OK;}
318     //**************************IOleInPlaceUIWindow*****************
GetBorder(LPRECT lprectBorder)319     HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder)
320     {
321         if (lprectBorder == NULL)
322             return E_INVALIDARG;
323         return INPLACE_E_NOTOOLSPACE;
324     }
RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)325     HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
326     {
327         if (pborderwidths == NULL)
328             return E_INVALIDARG;
329         return INPLACE_E_NOTOOLSPACE;
330     }
SetBorderSpace(LPCBORDERWIDTHS)331     HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS)
332     {return S_OK;}
SetActiveObject(IOleInPlaceActiveObject * pActiveObject,LPCOLESTR)333     HRESULT STDMETHODCALLTYPE SetActiveObject(
334         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR)
335     {
336         if (pActiveObject)
337             pActiveObject->AddRef();
338 
339         m_window->m_oleInPlaceActiveObject = pActiveObject;
340         return S_OK;
341     }
342 
343     //********************IOleInPlaceFrame************************
344 
STDMETHOD(InsertMenus)345     STDMETHOD(InsertMenus)(HMENU, LPOLEMENUGROUPWIDTHS){return S_OK;}
STDMETHOD(SetMenu)346     STDMETHOD(SetMenu)(HMENU, HOLEMENU, HWND){  return S_OK;}
STDMETHOD(RemoveMenus)347     STDMETHOD(RemoveMenus)(HMENU){return S_OK;}
STDMETHOD(SetStatusText)348     STDMETHOD(SetStatusText)(LPCOLESTR){ return S_OK;}
EnableModeless(BOOL)349     HRESULT STDMETHODCALLTYPE EnableModeless(BOOL){return S_OK;}
TranslateAccelerator(LPMSG lpmsg,WORD)350     HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD)
351     {
352         // TODO: send an event with this id
353         if (m_window->m_oleInPlaceActiveObject.Ok())
354             m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
355         return S_FALSE;
356     }
357 
358     //*******************IOleInPlaceSite**************************
CanInPlaceActivate()359     HRESULT STDMETHODCALLTYPE CanInPlaceActivate(){return S_OK;}
OnInPlaceActivate()360     HRESULT STDMETHODCALLTYPE OnInPlaceActivate()
361     {   m_bInPlaceActive = true;    return S_OK;    }
OnUIActivate()362     HRESULT STDMETHODCALLTYPE OnUIActivate()
363     {   m_bUIActive = true;         return S_OK;    }
GetWindowContext(IOleInPlaceFrame ** ppFrame,IOleInPlaceUIWindow ** ppDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo)364     HRESULT STDMETHODCALLTYPE GetWindowContext(IOleInPlaceFrame **ppFrame,
365                                         IOleInPlaceUIWindow **ppDoc,
366                                         LPRECT lprcPosRect,
367                                         LPRECT lprcClipRect,
368                                         LPOLEINPLACEFRAMEINFO lpFrameInfo)
369     {
370         if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL ||
371             lprcClipRect == NULL || lpFrameInfo == NULL)
372         {
373             if (ppFrame != NULL)
374                 (*ppFrame) = NULL;
375             if (ppDoc != NULL)
376                 (*ppDoc) = NULL;
377             return E_INVALIDARG;
378         }
379 
380         HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame);
381         if (! SUCCEEDED(hr))
382         {
383             return E_UNEXPECTED;
384         }
385 
386         hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
387         if (! SUCCEEDED(hr))
388         {
389             (*ppFrame)->Release();
390             *ppFrame = NULL;
391             return E_UNEXPECTED;
392         }
393 
394         RECT rect;
395         ::GetClientRect(m_hWndParent, &rect);
396         if (lprcPosRect)
397         {
398             lprcPosRect->left = lprcPosRect->top = 0;
399             lprcPosRect->right = rect.right;
400             lprcPosRect->bottom = rect.bottom;
401         }
402         if (lprcClipRect)
403         {
404             lprcClipRect->left = lprcClipRect->top = 0;
405             lprcClipRect->right = rect.right;
406             lprcClipRect->bottom = rect.bottom;
407         }
408 
409         memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
410         lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
411         lpFrameInfo->hwndFrame = m_hWndParent;
412 
413         return S_OK;
414     }
Scroll(SIZE)415     HRESULT STDMETHODCALLTYPE Scroll(SIZE){return S_OK;}
OnUIDeactivate(BOOL)416     HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL)
417     {   m_bUIActive = false;         return S_OK;    }
OnInPlaceDeactivate()418     HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate()
419     {   m_bInPlaceActive = false;    return S_OK;    }
DiscardUndoState()420     HRESULT STDMETHODCALLTYPE DiscardUndoState(){return S_OK;}
DeactivateAndUndo()421     HRESULT STDMETHODCALLTYPE DeactivateAndUndo(){return S_OK; }
OnPosRectChange(LPCRECT lprcPosRect)422     HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect)
423     {
424         if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
425         {
426            //
427            // Result of several hours and days of bug hunting -
428            // this is called by an object when it wants to resize
429            // itself to something different then our parent window -
430            // don't let it :)
431            //
432 //            m_window->m_oleInPlaceObject->SetObjectRects(
433 //                lprcPosRect, lprcPosRect);
434            RECT rcClient;
435            ::GetClientRect(m_hWndParent, &rcClient);
436             m_window->m_oleInPlaceObject->SetObjectRects(
437                 &rcClient, &rcClient);
438         }
439         return S_OK;
440     }
441     //*************************IOleInPlaceSiteEx***********************
OnInPlaceActivateEx(BOOL * pfNoRedraw,DWORD)442     HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD)
443     {
444 #ifdef __WXWINCE__
445         IRunnableObject* runnable = NULL;
446         HRESULT hr = QueryInterface(
447             IID_IRunnableObject, (void**)(& runnable));
448         if (SUCCEEDED(hr))
449         {
450             runnable->LockRunning(TRUE, FALSE);
451         }
452 #else
453         OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
454 #endif
455         if (pfNoRedraw)
456             (*pfNoRedraw) = FALSE;
457         return S_OK;
458     }
459 
OnInPlaceDeactivateEx(BOOL)460     HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL)
461     {
462 #ifdef __WXWINCE__
463         IRunnableObject* runnable = NULL;
464         HRESULT hr = QueryInterface(
465             IID_IRunnableObject, (void**)(& runnable));
466         if (SUCCEEDED(hr))
467         {
468             runnable->LockRunning(FALSE, FALSE);
469         }
470 #else
471         OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
472 #endif
473         return S_OK;
474     }
STDMETHOD(RequestUIActivate)475     STDMETHOD(RequestUIActivate)(){ return S_OK;}
476     //*************************IOleClientSite**************************
SaveObject()477     HRESULT STDMETHODCALLTYPE SaveObject(){return S_OK;}
OleGetMonikerToStr(DWORD dwAssign)478     const char *OleGetMonikerToStr(DWORD dwAssign)
479     {
480         switch (dwAssign)
481         {
482         case OLEGETMONIKER_ONLYIFTHERE  : return "OLEGETMONIKER_ONLYIFTHERE";
483         case OLEGETMONIKER_FORCEASSIGN  : return "OLEGETMONIKER_FORCEASSIGN";
484         case OLEGETMONIKER_UNASSIGN     : return "OLEGETMONIKER_UNASSIGN";
485         case OLEGETMONIKER_TEMPFORUSER  : return "OLEGETMONIKER_TEMPFORUSER";
486         default                         : return "Bad Enum";
487         }
488     }
489 
OleGetWhicMonikerStr(DWORD dwWhichMoniker)490     const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
491     {
492         switch(dwWhichMoniker)
493         {
494         case OLEWHICHMK_CONTAINER   : return "OLEWHICHMK_CONTAINER";
495         case OLEWHICHMK_OBJREL      : return "OLEWHICHMK_OBJREL";
496         case OLEWHICHMK_OBJFULL     : return "OLEWHICHMK_OBJFULL";
497         default                     : return "Bad Enum";
498         }
499     }
STDMETHOD(GetMoniker)500     STDMETHOD(GetMoniker)(DWORD, DWORD, IMoniker **){return E_FAIL;}
GetContainer(LPOLECONTAINER * ppContainer)501     HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer)
502     {
503         if (ppContainer == NULL)
504             return E_INVALIDARG;
505         HRESULT hr = QueryInterface(
506             IID_IOleContainer, (void**)(ppContainer));
507         wxASSERT(SUCCEEDED(hr));
508         return hr;
509     }
ShowObject()510     HRESULT STDMETHODCALLTYPE ShowObject()
511     {
512         if (m_window->m_oleObjectHWND)
513             ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
514         return S_OK;
515     }
STDMETHOD(OnShowWindow)516     STDMETHOD(OnShowWindow)(BOOL){return S_OK;}
STDMETHOD(RequestNewObjectLayout)517     STDMETHOD(RequestNewObjectLayout)(){return E_NOTIMPL;}
518     //********************IParseDisplayName***************************
ParseDisplayName(IBindCtx *,LPOLESTR,ULONG *,IMoniker **)519     HRESULT STDMETHODCALLTYPE ParseDisplayName(
520         IBindCtx *, LPOLESTR, ULONG *, IMoniker **){return E_NOTIMPL;}
521     //********************IOleContainer*******************************
STDMETHOD(EnumObjects)522     STDMETHOD(EnumObjects)(DWORD, IEnumUnknown **){return E_NOTIMPL;}
LockContainer(BOOL)523     HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;}
524     //********************IOleItemContainer***************************
525     HRESULT STDMETHODCALLTYPE
526     #if 0 // defined(__WXWINCE__) && __VISUALC__ < 1400
527     GetObject
528     #elif defined(_UNICODE)
529     GetObjectW
530     #else
GetObjectA(LPOLESTR pszItem,DWORD,IBindCtx *,REFIID,void ** ppvObject)531     GetObjectA
532     #endif
533     (LPOLESTR pszItem, DWORD, IBindCtx *, REFIID, void ** ppvObject)
534     {
535         if (pszItem == NULL || ppvObject == NULL)
536             return E_INVALIDARG;
537         *ppvObject = NULL;
538         return MK_E_NOOBJECT;
539     }
GetObjectStorage(LPOLESTR pszItem,IBindCtx *,REFIID,void ** ppvStorage)540     HRESULT STDMETHODCALLTYPE GetObjectStorage(
541         LPOLESTR pszItem, IBindCtx * , REFIID, void ** ppvStorage)
542     {
543         if (pszItem == NULL || ppvStorage == NULL)
544             return E_INVALIDARG;
545         *ppvStorage = NULL;
546         return MK_E_NOOBJECT;
547     }
IsRunning(LPOLESTR pszItem)548     HRESULT STDMETHODCALLTYPE IsRunning(LPOLESTR pszItem)
549     {
550         if (pszItem == NULL)
551             return E_INVALIDARG;
552         return MK_E_NOOBJECT;
553     }
554     //***********************IOleControlSite*****************************
OnControlInfoChanged()555     HRESULT STDMETHODCALLTYPE OnControlInfoChanged()
556     {return S_OK;}
LockInPlaceActive(BOOL fLock)557     HRESULT STDMETHODCALLTYPE LockInPlaceActive(BOOL fLock)
558     {
559         m_bInPlaceLocked = (fLock) ? true : false;
560         return S_OK;
561     }
GetExtendedControl(IDispatch **)562     HRESULT STDMETHODCALLTYPE GetExtendedControl(IDispatch **)
563     {return E_NOTIMPL;}
TransformCoords(POINTL * pPtlHimetric,POINTF * pPtfContainer,DWORD)564     HRESULT STDMETHODCALLTYPE TransformCoords(
565         POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD)
566     {
567         if (pPtlHimetric == NULL || pPtfContainer == NULL)
568             return E_INVALIDARG;
569         return E_NOTIMPL;
570     }
TranslateAccelerator(LPMSG,DWORD)571     HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG, DWORD)
572     {return E_NOTIMPL;}
OnFocus(BOOL)573     HRESULT STDMETHODCALLTYPE OnFocus(BOOL){return S_OK;}
ShowPropertyFrame()574     HRESULT STDMETHODCALLTYPE ShowPropertyFrame(){return E_NOTIMPL;}
575     //**************************IOleCommandTarget***********************
QueryStatus(const GUID *,ULONG cCmds,OLECMD prgCmds[],OLECMDTEXT *)576     HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *, ULONG cCmds,
577                                 OLECMD prgCmds[], OLECMDTEXT *)
578     {
579         if (prgCmds == NULL) return E_INVALIDARG;
580         for (ULONG nCmd = 0; nCmd < cCmds; nCmd++)
581         {
582             // unsupported by default
583             prgCmds[nCmd].cmdf = 0;
584         }
585         return OLECMDERR_E_UNKNOWNGROUP;
586     }
587 
Exec(const GUID *,DWORD,DWORD,VARIANTARG *,VARIANTARG *)588     HRESULT STDMETHODCALLTYPE Exec(const GUID *, DWORD,
589                             DWORD, VARIANTARG *, VARIANTARG *)
590     {return OLECMDERR_E_NOTSUPPORTED;}
591 
592     //**********************IAdviseSink************************************
OnDataChange(FORMATETC *,STGMEDIUM *)593     void STDMETHODCALLTYPE OnDataChange(FORMATETC *, STGMEDIUM *) {}
OnViewChange(DWORD,LONG)594     void STDMETHODCALLTYPE OnViewChange(DWORD, LONG) {}
OnRename(IMoniker *)595     void STDMETHODCALLTYPE OnRename(IMoniker *){}
OnSave()596     void STDMETHODCALLTYPE OnSave(){}
OnClose()597     void STDMETHODCALLTYPE OnClose(){}
598 
599     //**********************IOleDocumentSite***************************
ActivateMe(IOleDocumentView __RPC_FAR * pViewToActivate)600     HRESULT STDMETHODCALLTYPE ActivateMe(
601         IOleDocumentView __RPC_FAR *pViewToActivate)
602     {
603         wxAutoIOleInPlaceSite inPlaceSite(
604             IID_IOleInPlaceSite, (IDispatch *) this);
605         if (!inPlaceSite.Ok())
606             return E_FAIL;
607 
608         if (pViewToActivate)
609         {
610             m_window->m_docView = pViewToActivate;
611             m_window->m_docView->SetInPlaceSite(inPlaceSite);
612         }
613         else
614         {
615             wxAutoIOleDocument oleDoc(
616                 IID_IOleDocument, m_window->m_oleObject);
617             if (! oleDoc.Ok())
618                 return E_FAIL;
619 
620             HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL,
621                                     0, m_window->m_docView.GetRef());
622             if (hr != S_OK)
623                 return E_FAIL;
624 
625             m_window->m_docView->SetInPlaceSite(inPlaceSite);
626         }
627 
628         m_window->m_docView->UIActivate(TRUE);
629         return S_OK;
630     }
631 
632 
633 protected:
634     wxActiveXContainer * m_window;
635 
636     HDC m_hDCBuffer;
637     HWND m_hWndParent;
638 
639     bool m_bSupportsWindowlessActivation;
640     bool m_bInPlaceLocked;
641     bool m_bInPlaceActive;
642     bool m_bUIActive;
643     bool m_bWindowless;
644 
645     LCID m_nAmbientLocale;
646     COLORREF m_clrAmbientForeColor;
647     COLORREF m_clrAmbientBackColor;
648     bool m_bAmbientShowHatching;
649     bool m_bAmbientShowGrabHandles;
650     bool m_bAmbientAppearance;
651 };
652 
653 DEFINE_OLE_TABLE(FrameSite)
654     OLE_INTERFACE(IID_IUnknown, IOleClientSite)
655     OLE_IINTERFACE(IOleClientSite)
656     OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite)
657     OLE_IINTERFACE(IOleInPlaceSite)
658     OLE_IINTERFACE(IOleInPlaceSiteEx)
659     OLE_IINTERFACE(IOleInPlaceUIWindow)
660     OLE_IINTERFACE(IOleInPlaceFrame)
661     OLE_IINTERFACE(IParseDisplayName)
662     OLE_IINTERFACE(IOleContainer)
663     OLE_IINTERFACE(IOleItemContainer)
664     OLE_IINTERFACE(IDispatch)
665     OLE_IINTERFACE(IOleCommandTarget)
666     OLE_IINTERFACE(IOleDocumentSite)
667     OLE_IINTERFACE(IAdviseSink)
668     OLE_IINTERFACE(IOleControlSite)
669 END_OLE_TABLE
670 
671 
672 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
673 //
674 // wxActiveXEvents
675 //
676 // Handles and sends activex events received from the ActiveX control
677 // to the appropriate wxEvtHandler
678 //
679 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
680 class wxActiveXEvents : public IDispatch
681 {
682 private:
683     DECLARE_OLE_UNKNOWN(wxActiveXEvents);
684 
685 
686     wxActiveXContainer *m_activeX;
687     IID m_customId;
688     bool m_haveCustomId;
689 
690     friend bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc);
691 
692 public:
wxActiveXEvents(wxActiveXContainer * ax)693     wxActiveXEvents(wxActiveXContainer *ax) : m_activeX(ax), m_haveCustomId(false) {}
wxActiveXEvents(wxActiveXContainer * ax,REFIID iid)694     wxActiveXEvents(wxActiveXContainer *ax, REFIID iid) : m_activeX(ax), m_customId(iid), m_haveCustomId(true) {}
~wxActiveXEvents()695     virtual ~wxActiveXEvents()
696     {
697     }
698 
699     // IDispatch
GetIDsOfNames(REFIID,OLECHAR **,unsigned int,LCID,DISPID *)700     STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*)
701     {
702         return E_NOTIMPL;
703     }
704 
GetTypeInfo(unsigned int,LCID,ITypeInfo **)705     STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**)
706     {
707         return E_NOTIMPL;
708     }
709 
GetTypeInfoCount(unsigned int *)710     STDMETHODIMP GetTypeInfoCount(unsigned int*)
711     {
712         return E_NOTIMPL;
713     }
714 
715 
Invoke(DISPID dispIdMember,REFIID WXUNUSED (riid),LCID WXUNUSED (lcid),WORD wFlags,DISPPARAMS * pDispParams,VARIANT * WXUNUSED (pVarResult),EXCEPINFO * WXUNUSED (pExcepInfo),unsigned int * WXUNUSED (puArgErr))716     STDMETHODIMP Invoke(DISPID dispIdMember, REFIID WXUNUSED(riid),
717                         LCID WXUNUSED(lcid),
718                           WORD wFlags, DISPPARAMS * pDispParams,
719                           VARIANT * WXUNUSED(pVarResult), EXCEPINFO * WXUNUSED(pExcepInfo),
720                           unsigned int * WXUNUSED(puArgErr))
721     {
722         if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
723             return E_NOTIMPL;
724 
725         wxASSERT(m_activeX);
726 
727         // ActiveX Event
728 
729         // Dispatch Event
730         wxActiveXEvent  event;
731         event.SetEventType(wxEVT_ACTIVEX);
732         event.m_params.NullList();
733         event.m_dispid = dispIdMember;
734 
735         // arguments
736         if (pDispParams)
737         {
738             for (DWORD i = pDispParams->cArgs; i > 0; i--)
739             {
740                 VARIANTARG& va = pDispParams->rgvarg[i-1];
741                 wxVariant vx;
742 
743 //                        vx.SetName(px.name);
744                 wxConvertOleToVariant(va, vx);
745                 event.m_params.Append(vx);
746             }
747         }
748 
749         // process the events from the activex method
750            m_activeX->ProcessEvent(event);
751         for (DWORD i = 0; i < pDispParams->cArgs; i++)
752         {
753             VARIANTARG& va = pDispParams->rgvarg[i];
754             wxVariant& vx =
755                 event.m_params[pDispParams->cArgs - i - 1];
756             wxConvertVariantToOle(vx, va);
757         }
758 
759         if(event.GetSkipped())
760             return DISP_E_MEMBERNOTFOUND;
761 
762         return S_OK;
763     }
764 };
765 
wxActiveXEventsInterface(wxActiveXEvents * self,REFIID iid,void ** _interface,const char * & desc)766 bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc)
767 {
768     if (self->m_haveCustomId && IsEqualIID(iid, self->m_customId))
769     {
770 //        WXOLE_TRACE("Found Custom Dispatch Interface");
771         *_interface = (IUnknown *) (IDispatch *) self;
772         desc = "Custom Dispatch Interface";
773         return true;
774     }
775 
776     return false;
777 }
778 
779 DEFINE_OLE_TABLE(wxActiveXEvents)
OLE_IINTERFACE(IUnknown)780     OLE_IINTERFACE(IUnknown)
781     OLE_INTERFACE(IID_IDispatch, IDispatch)
782     OLE_INTERFACE_CUSTOM(wxActiveXEventsInterface)
783 END_OLE_TABLE
784 
785 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
786 //
787 // wxActiveXContainer
788 //
789 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
790 
791 //---------------------------------------------------------------------------
792 // wxActiveXContainer Constructor
793 //
794 // Initializes members and creates the native ActiveX container
795 //---------------------------------------------------------------------------
796 wxActiveXContainer::wxActiveXContainer(wxWindow * parent,
797                                        REFIID iid, IUnknown* pUnk)
798     : m_realparent(parent)
799 {
800     m_bAmbientUserMode = true;
801     m_docAdviseCookie = 0;
802     CreateActiveX(iid, pUnk);
803 }
804 
805 //---------------------------------------------------------------------------
806 // wxActiveXContainer Destructor
807 //
808 // Destroys members (the FrameSite et al. are destroyed implicitly
809 // through COM ref counting)
810 //---------------------------------------------------------------------------
~wxActiveXContainer()811 wxActiveXContainer::~wxActiveXContainer()
812 {
813     // disconnect connection points
814     if (m_oleInPlaceObject.Ok())
815     {
816         m_oleInPlaceObject->InPlaceDeactivate();
817         m_oleInPlaceObject->UIDeactivate();
818     }
819 
820     if (m_oleObject.Ok())
821     {
822         if (m_docAdviseCookie != 0)
823             m_oleObject->Unadvise(m_docAdviseCookie);
824 
825         m_oleObject->DoVerb(
826             OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL);
827         m_oleObject->Close(OLECLOSE_NOSAVE);
828         m_oleObject->SetClientSite(NULL);
829     }
830 }
831 
832 //---------------------------------------------------------------------------
833 // wxActiveXContainer::CreateActiveX
834 //
835 // Actually creates the ActiveX container through the FrameSite
836 // and sets up ActiveX events
837 //
838 // TODO: Document this more
839 //---------------------------------------------------------------------------
CreateActiveX(REFIID iid,IUnknown * pUnk)840 void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
841 {
842     HRESULT hret;
843     hret = m_ActiveX.QueryInterface(iid, pUnk);
844     wxASSERT(SUCCEEDED(hret));
845 
846     // FrameSite
847     FrameSite *frame = new FrameSite(m_realparent, this);
848     // oleClientSite
849     hret = m_clientSite.QueryInterface(
850         IID_IOleClientSite, (IDispatch *) frame);
851     wxASSERT(SUCCEEDED(hret));
852     // adviseSink
853     wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) frame);
854     wxASSERT(adviseSink.Ok());
855 
856     // Get Dispatch interface
857     hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
858 
859     //
860     // SETUP TYPEINFO AND ACTIVEX EVENTS
861     //
862 
863     // get type info via class info
864     wxAutoIProvideClassInfo classInfo(IID_IProvideClassInfo, m_ActiveX);
865     wxASSERT(classInfo.Ok());
866 
867     // type info
868     wxAutoITypeInfo typeInfo;
869     hret = classInfo->GetClassInfo(typeInfo.GetRef());
870     wxASSERT(typeInfo.Ok());
871 
872     // TYPEATTR
873     TYPEATTR *ta = NULL;
874     hret = typeInfo->GetTypeAttr(&ta);
875     wxASSERT(ta);
876 
877     // this should be a TKIND_COCLASS
878     wxASSERT(ta->typekind == TKIND_COCLASS);
879 
880     // iterate contained interfaces
881     for (int i = 0; i < ta->cImplTypes; i++)
882     {
883         HREFTYPE rt = 0;
884 
885         // get dispatch type info handle
886         hret = typeInfo->GetRefTypeOfImplType(i, &rt);
887         if (! SUCCEEDED(hret))
888             continue;
889 
890         // get dispatch type info interface
891         wxAutoITypeInfo  ti;
892         hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef());
893         if (! ti.Ok())
894             continue;
895 
896         // check if default event sink
897         bool defEventSink = false;
898         int impTypeFlags = 0;
899         typeInfo->GetImplTypeFlags(i, &impTypeFlags);
900 
901         if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT)
902         {
903             if (impTypeFlags & IMPLTYPEFLAG_FSOURCE)
904             {
905                 // WXOLE_TRACEOUT("Default Event Sink");
906                 defEventSink = true;
907                 if (impTypeFlags & IMPLTYPEFLAG_FDEFAULTVTABLE)
908                 {
909                     // WXOLE_TRACEOUT("*ERROR* - Default Event Sink is via vTable");
910                     defEventSink = false;
911                     wxFAIL_MSG(wxT("Default event sink is in vtable!"));
912                 }
913             }
914         }
915 
916 
917         // wxAutoOleInterface<> assumes a ref has already been added
918         // TYPEATTR
919         TYPEATTR *ta = NULL;
920         hret = ti->GetTypeAttr(&ta);
921         wxASSERT(ta);
922 
923         if (ta->typekind == TKIND_DISPATCH)
924         {
925             // WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
926             if (defEventSink)
927             {
928                 wxAutoIConnectionPoint    cp;
929                 DWORD                    adviseCookie = 0;
930 
931                 wxAutoIConnectionPointContainer cpContainer(IID_IConnectionPointContainer, m_ActiveX);
932                 wxASSERT( cpContainer.Ok());
933 
934                 HRESULT hret =
935                     cpContainer->FindConnectionPoint(ta->guid, cp.GetRef());
936                 wxASSERT ( SUCCEEDED(hret));
937 
938                 IDispatch* disp;
939                 frame->QueryInterface(IID_IDispatch, (void**)&disp);
940                 hret = cp->Advise(new wxActiveXEvents(this, ta->guid),
941                                   &adviseCookie);
942                 wxASSERT_MSG( SUCCEEDED(hret),
943                     wxString::Format(wxT("Cannot connect!\nHRESULT:%X"), (unsigned int)hret)
944                             );
945             }
946         }
947 
948         ti->ReleaseTypeAttr(ta);
949     }
950 
951     // free
952     typeInfo->ReleaseTypeAttr(ta);
953 
954     //
955     // END
956     //
957 
958     // Get IOleObject interface
959     hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
960     wxASSERT(SUCCEEDED(hret));
961 
962     // get IViewObject Interface
963     hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
964     wxASSERT(SUCCEEDED(hret));
965 
966     // document advise
967     m_docAdviseCookie = 0;
968     hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
969     // TODO:Needed?
970 //    hret = m_viewObject->SetAdvise(DVASPECT_CONTENT, 0, adviseSink);
971     m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
972     OleSetContainedObject(m_oleObject, TRUE);
973     OleRun(m_oleObject);
974 
975 
976     // Get IOleInPlaceObject interface
977     hret = m_oleInPlaceObject.QueryInterface(
978         IID_IOleInPlaceObject, m_ActiveX);
979     wxASSERT(SUCCEEDED(hret));
980 
981     // status
982     DWORD dwMiscStatus;
983     m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
984     wxASSERT(SUCCEEDED(hret));
985 
986     // set client site first ?
987     if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
988         m_oleObject->SetClientSite(m_clientSite);
989 
990 
991     // stream init
992     wxAutoIPersistStreamInit
993         pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
994 
995     if (pPersistStreamInit.Ok())
996     {
997         hret = pPersistStreamInit->InitNew();
998     }
999 
1000     if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
1001         m_oleObject->SetClientSite(m_clientSite);
1002 
1003 
1004     RECT posRect;
1005     ::GetClientRect((HWND)m_realparent->GetHWND(), &posRect);
1006 
1007     m_oleObjectHWND = 0;
1008 
1009     if (m_oleInPlaceObject.Ok())
1010     {
1011         hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
1012         if (SUCCEEDED(hret))
1013             ::SetActiveWindow(m_oleObjectHWND);
1014     }
1015 
1016 
1017     if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
1018     {
1019         if (posRect.right > 0 && posRect.bottom > 0 &&
1020             m_oleInPlaceObject.Ok())
1021                 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
1022 
1023         hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
1024             m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
1025         hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
1026             (HWND)m_realparent->GetHWND(), &posRect);
1027     }
1028 
1029     if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
1030     {
1031         hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
1032     }
1033 
1034     if (m_oleObjectHWND)
1035     {
1036         ::SetActiveWindow(m_oleObjectHWND);
1037         ::ShowWindow(m_oleObjectHWND, SW_SHOW);
1038 
1039         this->AssociateHandle(m_oleObjectHWND);
1040         this->Reparent(m_realparent);
1041 
1042         wxWindow* pWnd = m_realparent;
1043         int id = m_realparent->GetId();
1044 
1045         pWnd->Connect(id, wxEVT_SIZE,
1046             wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this);
1047 //        this->Connect(GetId(), wxEVT_PAINT,
1048 //            wxPaintEventHandler(wxActiveXContainer::OnPaint), 0, this);
1049         pWnd->Connect(id, wxEVT_SET_FOCUS,
1050             wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this);
1051         pWnd->Connect(id, wxEVT_KILL_FOCUS,
1052             wxFocusEventHandler(wxActiveXContainer::OnKillFocus), 0, this);
1053     }
1054 }
1055 
1056 //---------------------------------------------------------------------------
1057 // wxActiveXContainer::OnSize
1058 //
1059 // Called when the parent is resized - we need to do this to actually
1060 // move the ActiveX control to where the parent is
1061 //---------------------------------------------------------------------------
OnSize(wxSizeEvent & event)1062 void wxActiveXContainer::OnSize(wxSizeEvent& event)
1063 {
1064     int w, h;
1065     GetParent()->GetClientSize(&w, &h);
1066 
1067     RECT posRect;
1068     posRect.left = 0;
1069     posRect.top = 0;
1070     posRect.right = w;
1071     posRect.bottom = h;
1072 
1073     if (w <= 0 && h <= 0)
1074         return;
1075 
1076     // extents are in HIMETRIC units
1077     if (m_oleObject.Ok())
1078     {
1079         m_oleObject->DoVerb(OLEIVERB_HIDE, 0, m_clientSite, 0,
1080             (HWND)m_realparent->GetHWND(), &posRect);
1081 
1082         SIZEL sz = {w, h};
1083         PixelsToHimetric(sz);
1084 
1085         SIZEL sz2;
1086 
1087         m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
1088         if (sz2.cx !=  sz.cx || sz.cy != sz2.cy)
1089             m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
1090 
1091         m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
1092             (HWND)m_realparent->GetHWND(), &posRect);
1093     }
1094 
1095     if (m_oleInPlaceObject.Ok())
1096         m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
1097 
1098     event.Skip();
1099 }
1100 
1101 //---------------------------------------------------------------------------
1102 // wxActiveXContainer::OnPaint
1103 //
1104 // Called when the parent is resized - repaints the ActiveX control
1105 //---------------------------------------------------------------------------
OnPaint(wxPaintEvent & WXUNUSED (event))1106 void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
1107 {
1108     wxPaintDC dc(this);
1109     // Draw only when control is windowless or deactivated
1110     if (m_viewObject)
1111     {
1112         int w, h;
1113         GetParent()->GetSize(&w, &h);
1114         RECT posRect;
1115         posRect.left = 0;
1116         posRect.top = 0;
1117         posRect.right = w;
1118         posRect.bottom = h;
1119 
1120 #if !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
1121         ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
1122 #else
1123         ::InvalidateRect(m_oleObjectHWND, NULL, false);
1124 #endif
1125         RECTL *prcBounds = (RECTL *) &posRect;
1126         m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
1127             (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
1128     }
1129 }
1130 
1131 //---------------------------------------------------------------------------
1132 // wxActiveXContainer::OnSetFocus
1133 //
1134 // Called when the focus is set on the parent - activates the activex control
1135 //---------------------------------------------------------------------------
OnSetFocus(wxFocusEvent & event)1136 void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
1137 {
1138     if (m_oleInPlaceActiveObject.Ok())
1139         m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
1140 
1141     event.Skip();
1142 }
1143 
1144 //---------------------------------------------------------------------------
1145 // wxActiveXContainer::OnKillFocus
1146 //
1147 // Called when the focus is killed on the parent -
1148 // deactivates the activex control
1149 //---------------------------------------------------------------------------
OnKillFocus(wxFocusEvent & event)1150 void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
1151 {
1152     if (m_oleInPlaceActiveObject.Ok())
1153         m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
1154 
1155     event.Skip();
1156 }
1157 
1158 #endif // wxUSE_ACTIVEX
1159