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