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