]> git.saurik.com Git - wxWidgets.git/blame - src/msw/ole/activex.cpp
Fix wxHtmlHelpData::SetTempDir() to behave correctly without trailing slash.
[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 6// Created: 11/07/04
bf354396
VZ
7// Copyright: (c) 2003 Lindsay Mathieson, (c) 2005 Ryan Norton
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
c493691d
WS
11// ============================================================================
12// declarations
13// ============================================================================
bf354396 14
c493691d
WS
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
bf354396 18
c493691d 19#include "wx/wxprec.h"
bf354396 20
c493691d
WS
21#ifdef __BORLANDC__
22 #pragma hdrstop
23#endif
bf354396 24
a1f48575
VZ
25#if wxUSE_ACTIVEX
26
ed4b0fdc
WS
27#ifndef WX_PRECOMP
28 #include "wx/dcclient.h"
18680f86 29 #include "wx/math.h"
ed4b0fdc
WS
30#endif
31
363e2dc0
PC
32#include "wx/msw/dc.h"
33
557002cf 34#include "wx/msw/ole/activex.h"
403dd8db
VZ
35#include "wx/msw/private.h" // for wxCopyRectToRECT
36
557002cf 37// autointerfaces that we only use here
c986b01f
VS
38typedef wxAutoOleInterface<IOleInPlaceSite> wxAutoIOleInPlaceSite;
39typedef wxAutoOleInterface<IOleDocument> wxAutoIOleDocument;
40typedef wxAutoOleInterface<IPersistStreamInit> wxAutoIPersistStreamInit;
41typedef wxAutoOleInterface<IAdviseSink> wxAutoIAdviseSink;
42typedef wxAutoOleInterface<IProvideClassInfo> wxAutoIProvideClassInfo;
43typedef wxAutoOleInterface<ITypeInfo> wxAutoITypeInfo;
44typedef wxAutoOleInterface<IConnectionPoint> wxAutoIConnectionPoint;
45typedef wxAutoOleInterface<IConnectionPointContainer> wxAutoIConnectionPointContainer;
557002cf 46
9b11752c 47wxDEFINE_EVENT( wxEVT_ACTIVEX, wxActiveXEvent );
557002cf
VZ
48
49// Ole class helpers (sort of MFC-like) from wxActiveX
bf354396
VZ
50#define DECLARE_OLE_UNKNOWN(cls)\
51 private:\
52 class TAutoInitInt\
53 {\
54 public:\
55 LONG l;\
648c1af9 56 TAutoInitInt() : l(1) {}\
bf354396
VZ
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;\
f74fd79b 75 }\
bf354396
VZ
76 const char *desc = NULL;\
77 cls::_GetInterface(this, iid, ppvObject, desc);\
78 if (! *ppvObject)\
79 {\
80 return E_NOINTERFACE;\
f74fd79b 81 }\
bf354396
VZ
82 ((IUnknown * )(*ppvObject))->AddRef();\
83 return S_OK;\
f74fd79b 84 }\
bf354396
VZ
85 ULONG STDMETHODCALLTYPE cls::AddRef()\
86 {\
87 InterlockedIncrement(&refCount.l);\
88 return refCount.l;\
f74fd79b 89 }\
bf354396
VZ
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;\
f74fd79b 99 }\
bf354396
VZ
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;\
f74fd79b 109 }\
bf354396
VZ
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
557002cf
VZ
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
161static 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
bf354396 185
557002cf
VZ
186//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
187//
188// FrameSite
189//
190// Handles the actual wxActiveX container implementation
191//
192//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bf354396
VZ
193class 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{
204private:
205 DECLARE_OLE_UNKNOWN(FrameSite);
206
207public:
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 }
227 virtual ~FrameSite(){}
228 //***************************IDispatch*****************************
229 HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, OLECHAR ** ,
230 unsigned int , LCID ,
231 DISPID * )
232 { return E_NOTIMPL; }
233 STDMETHOD(GetTypeInfo)(unsigned int, LCID, ITypeInfo **)
234 { return E_NOTIMPL; }
235 HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *)
236 { return E_NOTIMPL; }
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)= FALSE;
255 return S_OK;
256
257 case DISPID_AMBIENT_DISPLAYASDEFAULT:
258 V_BOOL(pVarResult)= TRUE;
259 return S_OK;
260
261 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
262 V_BOOL(pVarResult) = TRUE;
263 return S_OK;
264
265 case DISPID_AMBIENT_SILENT:
266 V_BOOL(pVarResult)= TRUE;
267 return S_OK;
557002cf 268
bf354396
VZ
269 case DISPID_AMBIENT_APPEARANCE:
270 pVarResult->vt = VT_BOOL;
271 pVarResult->boolVal = m_bAmbientAppearance;
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;
292 break;
293
294 case DISPID_AMBIENT_SHOWGRABHANDLES:
295 pVarResult->vt = VT_BOOL;
296 pVarResult->boolVal = m_bAmbientShowGrabHandles;
297 break;
298
299 case DISPID_AMBIENT_SHOWHATCHING:
300 pVarResult->vt = VT_BOOL;
301 pVarResult->boolVal = m_bAmbientShowHatching;
302 break;
557002cf 303
bf354396
VZ
304 default:
305 return DISP_E_MEMBERNOTFOUND;
306 }
307
308 return S_OK;
309 }
310
311 //**************************IOleWindow***************************
312 HRESULT STDMETHODCALLTYPE GetWindow(HWND * phwnd)
313 {
314 if (phwnd == NULL)
315 return E_INVALIDARG;
316 (*phwnd) = m_hWndParent;
317 return S_OK;
318 }
319 HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL)
320 {return S_OK;}
321 //**************************IOleInPlaceUIWindow*****************
322 HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder)
323 {
324 if (lprectBorder == NULL)
325 return E_INVALIDARG;
326 return INPLACE_E_NOTOOLSPACE;
327 }
328 HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
329 {
330 if (pborderwidths == NULL)
331 return E_INVALIDARG;
332 return INPLACE_E_NOTOOLSPACE;
333 }
334 HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS)
335 {return S_OK;}
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
348 STDMETHOD(InsertMenus)(HMENU, LPOLEMENUGROUPWIDTHS){return S_OK;}
349 STDMETHOD(SetMenu)(HMENU, HOLEMENU, HWND){ return S_OK;}
350 STDMETHOD(RemoveMenus)(HMENU){return S_OK;}
351 STDMETHOD(SetStatusText)(LPCOLESTR){ return S_OK;}
352 HRESULT STDMETHODCALLTYPE EnableModeless(BOOL){return S_OK;}
353 HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD)
354 {
355 // TODO: send an event with this id
a1b806b9 356 if (m_window->m_oleInPlaceActiveObject.IsOk())
bf354396
VZ
357 m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
358 return S_FALSE;
359 }
360
361 //*******************IOleInPlaceSite**************************
362 HRESULT STDMETHODCALLTYPE CanInPlaceActivate(){return S_OK;}
363 HRESULT STDMETHODCALLTYPE OnInPlaceActivate()
364 { m_bInPlaceActive = true; return S_OK; }
365 HRESULT STDMETHODCALLTYPE OnUIActivate()
366 { m_bUIActive = true; return S_OK; }
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;
f74fd79b 387 }
bf354396
VZ
388
389 hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
390 if (! SUCCEEDED(hr))
391 {
392 (*ppFrame)->Release();
393 *ppFrame = NULL;
394 return E_UNEXPECTED;
f74fd79b 395 }
bf354396
VZ
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;
f74fd79b 404 }
bf354396
VZ
405 if (lprcClipRect)
406 {
407 lprcClipRect->left = lprcClipRect->top = 0;
408 lprcClipRect->right = rect.right;
409 lprcClipRect->bottom = rect.bottom;
f74fd79b 410 }
bf354396
VZ
411
412 memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
413 lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
414 lpFrameInfo->hwndFrame = m_hWndParent;
415
416 return S_OK;
417 }
418 HRESULT STDMETHODCALLTYPE Scroll(SIZE){return S_OK;}
419 HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL)
420 { m_bUIActive = false; return S_OK; }
421 HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate()
422 { m_bInPlaceActive = false; return S_OK; }
423 HRESULT STDMETHODCALLTYPE DiscardUndoState(){return S_OK;}
424 HRESULT STDMETHODCALLTYPE DeactivateAndUndo(){return S_OK; }
425 HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect)
426 {
a1b806b9 427 if (m_window->m_oleInPlaceObject.IsOk() && lprcPosRect)
bf354396 428 {
557002cf
VZ
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);
bf354396 439 m_window->m_oleInPlaceObject->SetObjectRects(
557002cf 440 &rcClient, &rcClient);
bf354396
VZ
441 }
442 return S_OK;
443 }
444 //*************************IOleInPlaceSiteEx***********************
445 HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD)
446 {
a5fc9a1c
JS
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
bf354396 456 OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
a5fc9a1c 457#endif
bf354396
VZ
458 if (pfNoRedraw)
459 (*pfNoRedraw) = FALSE;
460 return S_OK;
461 }
462
463 HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL)
464 {
a5fc9a1c
JS
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
bf354396 474 OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
a5fc9a1c 475#endif
bf354396
VZ
476 return S_OK;
477 }
478 STDMETHOD(RequestUIActivate)(){ return S_OK;}
479 //*************************IOleClientSite**************************
480 HRESULT STDMETHODCALLTYPE SaveObject(){return S_OK;}
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";
f74fd79b
VZ
490 }
491 }
bf354396
VZ
492
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";
f74fd79b
VZ
501 }
502 }
bf354396
VZ
503 STDMETHOD(GetMoniker)(DWORD, DWORD, IMoniker **){return E_FAIL;}
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 }
513 HRESULT STDMETHODCALLTYPE ShowObject()
514 {
515 if (m_window->m_oleObjectHWND)
516 ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
517 return S_OK;
518 }
519 STDMETHOD(OnShowWindow)(BOOL){return S_OK;}
520 STDMETHOD(RequestNewObjectLayout)(){return E_NOTIMPL;}
521 //********************IParseDisplayName***************************
522 HRESULT STDMETHODCALLTYPE ParseDisplayName(
523 IBindCtx *, LPOLESTR, ULONG *, IMoniker **){return E_NOTIMPL;}
524 //********************IOleContainer*******************************
525 STDMETHOD(EnumObjects)(DWORD, IEnumUnknown **){return E_NOTIMPL;}
526 HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;}
527 //********************IOleItemContainer***************************
528 HRESULT STDMETHODCALLTYPE
ff759b6a 529 #if 0 // defined(__WXWINCE__) && __VISUALC__ < 1400
7dab17dd
WS
530 GetObject
531 #elif defined(_UNICODE)
bf354396
VZ
532 GetObjectW
533 #else
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 }
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 }
551 HRESULT STDMETHODCALLTYPE IsRunning(LPOLESTR pszItem)
552 {
553 if (pszItem == NULL)
554 return E_INVALIDARG;
555 return MK_E_NOOBJECT;
556 }
557 //***********************IOleControlSite*****************************
558 HRESULT STDMETHODCALLTYPE OnControlInfoChanged()
559 {return S_OK;}
560 HRESULT STDMETHODCALLTYPE LockInPlaceActive(BOOL fLock)
561 {
562 m_bInPlaceLocked = (fLock) ? true : false;
563 return S_OK;
564 }
565 HRESULT STDMETHODCALLTYPE GetExtendedControl(IDispatch **)
566 {return E_NOTIMPL;}
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 }
574 HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG, DWORD)
575 {return E_NOTIMPL;}
576 HRESULT STDMETHODCALLTYPE OnFocus(BOOL){return S_OK;}
577 HRESULT STDMETHODCALLTYPE ShowPropertyFrame(){return E_NOTIMPL;}
578 //**************************IOleCommandTarget***********************
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
591 HRESULT STDMETHODCALLTYPE Exec(const GUID *, DWORD,
592 DWORD, VARIANTARG *, VARIANTARG *)
593 {return OLECMDERR_E_NOTSUPPORTED;}
594
595 //**********************IAdviseSink************************************
596 void STDMETHODCALLTYPE OnDataChange(FORMATETC *, STGMEDIUM *) {}
597 void STDMETHODCALLTYPE OnViewChange(DWORD, LONG) {}
598 void STDMETHODCALLTYPE OnRename(IMoniker *){}
599 void STDMETHODCALLTYPE OnSave(){}
600 void STDMETHODCALLTYPE OnClose(){}
601
602 //**********************IOleDocumentSite***************************
603 HRESULT STDMETHODCALLTYPE ActivateMe(
604 IOleDocumentView __RPC_FAR *pViewToActivate)
605 {
606 wxAutoIOleInPlaceSite inPlaceSite(
607 IID_IOleInPlaceSite, (IDispatch *) this);
a1b806b9 608 if (!inPlaceSite.IsOk())
bf354396
VZ
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);
a1b806b9 620 if (! oleDoc.IsOk())
bf354396
VZ
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);
f74fd79b 629 }
bf354396
VZ
630
631 m_window->m_docView->UIActivate(TRUE);
632 return S_OK;
f74fd79b 633 }
bf354396 634
1f7d05f0
SL
635 friend bool QueryClientSiteInterface(FrameSite *self, REFIID iid, void **_interface, const char *&desc)
636 {
637 return self->m_window->QueryClientSiteInterface(iid,_interface,desc);
638 }
bf354396
VZ
639
640protected:
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
660DEFINE_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)
1f7d05f0 676 OLE_INTERFACE_CUSTOM(QueryClientSiteInterface)
f74fd79b 677END_OLE_TABLE
557002cf
VZ
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//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
688class wxActiveXEvents : public IDispatch
689{
690private:
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
700public:
2ddb8ccf
VZ
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.
da58c4e6 706 static wxVariant ms_invalidEntryMarker;
2ddb8ccf 707
557002cf 708 wxActiveXEvents(wxActiveXContainer *ax) : m_activeX(ax), m_haveCustomId(false) {}
f3a69d1d 709 wxActiveXEvents(wxActiveXContainer *ax, REFIID iid) : m_activeX(ax), m_customId(iid), m_haveCustomId(true) {}
557002cf
VZ
710 virtual ~wxActiveXEvents()
711 {
712 }
713
714 // IDispatch
715 STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*)
716 {
717 return E_NOTIMPL;
718 }
719
720 STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**)
721 {
722 return E_NOTIMPL;
723 }
724
725 STDMETHODIMP GetTypeInfoCount(unsigned int*)
726 {
727 return E_NOTIMPL;
728 }
bf354396
VZ
729
730
2ddb8ccf
VZ
731 STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid,
732 LCID lcid,
557002cf 733 WORD wFlags, DISPPARAMS * pDispParams,
2ddb8ccf
VZ
734 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
735 unsigned int * puArgErr)
557002cf
VZ
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);
2ddb8ccf
VZ
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
557002cf
VZ
750 event.m_params.NullList();
751 event.m_dispid = dispIdMember;
752
2ddb8ccf
VZ
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
557002cf
VZ
763
764 // process the events from the activex method
2ddb8ccf 765 m_activeX->ProcessEvent(event);
557002cf
VZ
766 for (DWORD i = 0; i < pDispParams->cArgs; i++)
767 {
2ddb8ccf
VZ
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
da58c4e6
VZ
772 // i.e. if vx != ms_invalidEntryMarker
773 if (!vx.IsType(wxActiveXEvents::ms_invalidEntryMarker.GetType()) || vx!=ms_invalidEntryMarker) {
2ddb8ccf
VZ
774 VARIANTARG& va = pDispParams->rgvarg[i];
775 wxConvertVariantToOle(vx, va);
776 }
777 }
557002cf
VZ
778 }
779
780 if(event.GetSkipped())
781 return DISP_E_MEMBERNOTFOUND;
782
783 return S_OK;
784 }
785};
786
da58c4e6
VZ
787namespace
788{
789// just a unique global variable
790const int invalid_entry_marker = 0;
791}
792
793wxVariant wxActiveXEvents::ms_invalidEntryMarker((void*)&invalid_entry_marker);
2ddb8ccf
VZ
794
795size_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
807wxVariant &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.
da58c4e6
VZ
814 if (native)
815 {
816 while ( m_params.GetCount()<=idx )
817 {
818 m_params.Append(wxActiveXEvents::ms_invalidEntryMarker);
2ddb8ccf 819 }
da58c4e6
VZ
820
821 wxVariant& vx = m_params[idx];
822 if ( vx.IsType(wxActiveXEvents::ms_invalidEntryMarker.GetType()) &&
823 vx == wxActiveXEvents::ms_invalidEntryMarker)
824 {
2ddb8ccf
VZ
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
557002cf
VZ
838bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc)
839{
840 if (self->m_haveCustomId && IsEqualIID(iid, self->m_customId))
841 {
557002cf
VZ
842 *_interface = (IUnknown *) (IDispatch *) self;
843 desc = "Custom Dispatch Interface";
844 return true;
f74fd79b 845 }
557002cf
VZ
846
847 return false;
848}
849
850DEFINE_OLE_TABLE(wxActiveXEvents)
851 OLE_IINTERFACE(IUnknown)
852 OLE_INTERFACE(IID_IDispatch, IDispatch)
853 OLE_INTERFACE_CUSTOM(wxActiveXEventsInterface)
f74fd79b 854END_OLE_TABLE
557002cf
VZ
855
856//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
857//
858// wxActiveXContainer
859//
860//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
861
862//---------------------------------------------------------------------------
863// wxActiveXContainer Constructor
864//
865// Initializes members and creates the native ActiveX container
866//---------------------------------------------------------------------------
867wxActiveXContainer::wxActiveXContainer(wxWindow * parent,
868 REFIID iid, IUnknown* pUnk)
bf354396
VZ
869 : m_realparent(parent)
870{
871 m_bAmbientUserMode = true;
872 m_docAdviseCookie = 0;
873 CreateActiveX(iid, pUnk);
874}
875
557002cf
VZ
876//---------------------------------------------------------------------------
877// wxActiveXContainer Destructor
878//
879// Destroys members (the FrameSite et al. are destroyed implicitly
880// through COM ref counting)
881//---------------------------------------------------------------------------
bf354396
VZ
882wxActiveXContainer::~wxActiveXContainer()
883{
884 // disconnect connection points
a1b806b9 885 if (m_oleInPlaceObject.IsOk())
bf354396
VZ
886 {
887 m_oleInPlaceObject->InPlaceDeactivate();
888 m_oleInPlaceObject->UIDeactivate();
889 }
890
a1b806b9 891 if (m_oleObject.IsOk())
bf354396
VZ
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 }
9b53796d
VZ
901
902 // m_clientSite uses m_frameSite so destroy it first
903 m_clientSite.Free();
904 delete m_frameSite;
07a971ee
VZ
905
906 // our window doesn't belong to us, don't destroy it
907 m_hWnd = NULL;
bf354396
VZ
908}
909
f1430ac7 910// VZ: we might want to really report an error instead of just asserting here
d2f434e4
VZ
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
f1430ac7 918
557002cf
VZ
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//---------------------------------------------------------------------------
bf354396
VZ
927void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
928{
929 HRESULT hret;
930 hret = m_ActiveX.QueryInterface(iid, pUnk);
f1430ac7 931 CHECK_HR(hret);
bf354396
VZ
932
933 // FrameSite
9b53796d 934 m_frameSite = new FrameSite(m_realparent, this);
bf354396
VZ
935 // oleClientSite
936 hret = m_clientSite.QueryInterface(
9b53796d 937 IID_IOleClientSite, (IDispatch *) m_frameSite);
f1430ac7 938 CHECK_HR(hret);
bf354396 939 // adviseSink
9b53796d 940 wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) m_frameSite);
a1b806b9 941 wxASSERT(adviseSink.IsOk());
bf354396
VZ
942
943 // Get Dispatch interface
944 hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
f1430ac7 945 CHECK_HR(hret);
bf354396 946
557002cf
VZ
947 //
948 // SETUP TYPEINFO AND ACTIVEX EVENTS
949 //
950
951 // get type info via class info
952 wxAutoIProvideClassInfo classInfo(IID_IProvideClassInfo, m_ActiveX);
a1b806b9 953 wxASSERT(classInfo.IsOk());
557002cf
VZ
954
955 // type info
956 wxAutoITypeInfo typeInfo;
957 hret = classInfo->GetClassInfo(typeInfo.GetRef());
f1430ac7 958 CHECK_HR(hret);
a1b806b9 959 wxASSERT(typeInfo.IsOk());
557002cf
VZ
960
961 // TYPEATTR
962 TYPEATTR *ta = NULL;
963 hret = typeInfo->GetTypeAttr(&ta);
f1430ac7 964 CHECK_HR(hret);
557002cf
VZ
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());
a1b806b9 982 if (! ti.IsOk())
557002cf
VZ
983 continue;
984
f1430ac7
VZ
985 CHECK_HR(hret);
986
557002cf 987 // check if default event sink
557002cf
VZ
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 }
557002cf
VZ
1005 }
1006
1007
1008 // wxAutoOleInterface<> assumes a ref has already been added
1009 // TYPEATTR
1010 TYPEATTR *ta = NULL;
1011 hret = ti->GetTypeAttr(&ta);
f1430ac7 1012 CHECK_HR(hret);
557002cf
VZ
1013
1014 if (ta->typekind == TKIND_DISPATCH)
1015 {
1016 // WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
1017 if (defEventSink)
1018 {
1019 wxAutoIConnectionPoint cp;
1020 DWORD adviseCookie = 0;
1021
1022 wxAutoIConnectionPointContainer cpContainer(IID_IConnectionPointContainer, m_ActiveX);
a1b806b9 1023 wxASSERT( cpContainer.IsOk());
557002cf
VZ
1024
1025 HRESULT hret =
1026 cpContainer->FindConnectionPoint(ta->guid, cp.GetRef());
21e5aa16
VZ
1027
1028 // Notice that the return value of CONNECT_E_NOCONNECTION is
1029 // expected if the interface doesn't support connection points.
1030 if ( hret != CONNECT_E_NOCONNECTION )
1031 {
1032 CHECK_HR(hret);
1033 }
557002cf 1034
e5a1bd64
VZ
1035 if ( cp )
1036 {
648c1af9
VZ
1037 wxActiveXEvents * const
1038 events = new wxActiveXEvents(this, ta->guid);
1039 hret = cp->Advise(events, &adviseCookie);
1040
1041 // We don't need this object any more and cp will keep a
1042 // reference to it if it needs it, i.e. if Advise()
1043 // succeeded.
1044 events->Release();
1045
e5a1bd64
VZ
1046 CHECK_HR(hret);
1047 }
557002cf
VZ
1048 }
1049 }
1050
1051 ti->ReleaseTypeAttr(ta);
1052 }
1053
1054 // free
1055 typeInfo->ReleaseTypeAttr(ta);
1056
1057 //
1058 // END
1059 //
1060
bf354396
VZ
1061 // Get IOleObject interface
1062 hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
f1430ac7 1063 CHECK_HR(hret);
bf354396
VZ
1064
1065 // get IViewObject Interface
1066 hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
f1430ac7 1067 CHECK_HR(hret);
bf354396
VZ
1068
1069 // document advise
1070 m_docAdviseCookie = 0;
1071 hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
f1430ac7
VZ
1072 CHECK_HR(hret);
1073
557002cf
VZ
1074 // TODO:Needed?
1075// hret = m_viewObject->SetAdvise(DVASPECT_CONTENT, 0, adviseSink);
bf354396
VZ
1076 m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
1077 OleSetContainedObject(m_oleObject, TRUE);
1078 OleRun(m_oleObject);
1079
1080
1081 // Get IOleInPlaceObject interface
1082 hret = m_oleInPlaceObject.QueryInterface(
1083 IID_IOleInPlaceObject, m_ActiveX);
f1430ac7 1084 CHECK_HR(hret);
bf354396
VZ
1085
1086 // status
1087 DWORD dwMiscStatus;
1088 m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
f1430ac7 1089 CHECK_HR(hret);
bf354396
VZ
1090
1091 // set client site first ?
1092 if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
1093 m_oleObject->SetClientSite(m_clientSite);
1094
1095
1096 // stream init
1097 wxAutoIPersistStreamInit
1098 pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
1099
a1b806b9 1100 if (pPersistStreamInit.IsOk())
bf354396
VZ
1101 {
1102 hret = pPersistStreamInit->InitNew();
f1430ac7 1103 CHECK_HR(hret);
bf354396
VZ
1104 }
1105
1106 if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
1107 m_oleObject->SetClientSite(m_clientSite);
1108
1109
bf354396
VZ
1110 m_oleObjectHWND = 0;
1111
bf354396
VZ
1112
1113 if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
1114 {
6e34a9e4
VZ
1115 RECT posRect;
1116 wxCopyRectToRECT(m_realparent->GetClientSize(), posRect);
1117
d1877f84 1118 hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
6e34a9e4 1119 m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
d1877f84
VZ
1120 CHECK_HR(hret);
1121
1122 if (m_oleInPlaceObject.IsOk())
1123 {
1124 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
1125 CHECK_HR(hret);
1126 ::SetActiveWindow(m_oleObjectHWND);
1127 }
1128
bf354396 1129 if (posRect.right > 0 && posRect.bottom > 0 &&
a1b806b9 1130 m_oleInPlaceObject.IsOk())
0641c712
VZ
1131 {
1132 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
1133 }
bf354396 1134
bf354396
VZ
1135 hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
1136 (HWND)m_realparent->GetHWND(), &posRect);
f1430ac7 1137 CHECK_HR(hret);
bf354396
VZ
1138 }
1139
a1b806b9 1140 if (! m_oleObjectHWND && m_oleInPlaceObject.IsOk())
bf354396
VZ
1141 {
1142 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
f1430ac7 1143 CHECK_HR(hret);
bf354396
VZ
1144 }
1145
1146 if (m_oleObjectHWND)
1147 {
1148 ::SetActiveWindow(m_oleObjectHWND);
1149 ::ShowWindow(m_oleObjectHWND, SW_SHOW);
1150
f36b056b 1151 this->AssociateHandle(m_oleObjectHWND);
bf354396
VZ
1152 this->Reparent(m_realparent);
1153
1154 wxWindow* pWnd = m_realparent;
1155 int id = m_realparent->GetId();
1156
1157 pWnd->Connect(id, wxEVT_SIZE,
1158 wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this);
557002cf
VZ
1159// this->Connect(GetId(), wxEVT_PAINT,
1160// wxPaintEventHandler(wxActiveXContainer::OnPaint), 0, this);
bf354396
VZ
1161 pWnd->Connect(id, wxEVT_SET_FOCUS,
1162 wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this);
1163 pWnd->Connect(id, wxEVT_KILL_FOCUS,
1164 wxFocusEventHandler(wxActiveXContainer::OnKillFocus), 0, this);
1165 }
1166}
1167
557002cf
VZ
1168//---------------------------------------------------------------------------
1169// wxActiveXContainer::OnSize
1170//
1171// Called when the parent is resized - we need to do this to actually
1172// move the ActiveX control to where the parent is
1173//---------------------------------------------------------------------------
bf354396
VZ
1174void wxActiveXContainer::OnSize(wxSizeEvent& event)
1175{
1176 int w, h;
1177 GetParent()->GetClientSize(&w, &h);
1178
1179 RECT posRect;
1180 posRect.left = 0;
1181 posRect.top = 0;
1182 posRect.right = w;
1183 posRect.bottom = h;
1184
1ce077e2 1185 if (w <= 0 || h <= 0)
bf354396
VZ
1186 return;
1187
1188 // extents are in HIMETRIC units
a1b806b9 1189 if (m_oleObject.IsOk())
bf354396 1190 {
557002cf 1191
bf354396
VZ
1192 SIZEL sz = {w, h};
1193 PixelsToHimetric(sz);
1194
1195 SIZEL sz2;
1196
1197 m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
1198 if (sz2.cx != sz.cx || sz.cy != sz2.cy)
1199 m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
557002cf 1200
557002cf 1201 }
bf354396 1202
a1b806b9 1203 if (m_oleInPlaceObject.IsOk())
bf354396
VZ
1204 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
1205
1206 event.Skip();
1207}
1208
557002cf
VZ
1209//---------------------------------------------------------------------------
1210// wxActiveXContainer::OnPaint
1211//
1212// Called when the parent is resized - repaints the ActiveX control
1213//---------------------------------------------------------------------------
bf354396
VZ
1214void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
1215{
1216 wxPaintDC dc(this);
1217 // Draw only when control is windowless or deactivated
1218 if (m_viewObject)
1219 {
bf354396
VZ
1220 int w, h;
1221 GetParent()->GetSize(&w, &h);
1222 RECT posRect;
1223 posRect.left = 0;
1224 posRect.top = 0;
1225 posRect.right = w;
1226 posRect.bottom = h;
1227
5d484919 1228#if !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
bf354396 1229 ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
5d484919
WS
1230#else
1231 ::InvalidateRect(m_oleObjectHWND, NULL, false);
1232#endif
bf354396 1233 RECTL *prcBounds = (RECTL *) &posRect;
0290aeac 1234 wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl );
bf354396 1235 m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
0290aeac 1236 (HDC)msw->GetHDC(), prcBounds, NULL, NULL, 0);
557002cf 1237 }
bf354396
VZ
1238}
1239
557002cf
VZ
1240//---------------------------------------------------------------------------
1241// wxActiveXContainer::OnSetFocus
1242//
1243// Called when the focus is set on the parent - activates the activex control
1244//---------------------------------------------------------------------------
bf354396
VZ
1245void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
1246{
a1b806b9 1247 if (m_oleInPlaceActiveObject.IsOk())
bf354396
VZ
1248 m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
1249
1250 event.Skip();
1251}
1252
557002cf
VZ
1253//---------------------------------------------------------------------------
1254// wxActiveXContainer::OnKillFocus
1255//
1256// Called when the focus is killed on the parent -
1257// deactivates the activex control
1258//---------------------------------------------------------------------------
bf354396
VZ
1259void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
1260{
a1b806b9 1261 if (m_oleInPlaceActiveObject.IsOk())
bf354396
VZ
1262 m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
1263
1264 event.Skip();
1265}
557002cf 1266
8a4e043a
SL
1267//---------------------------------------------------------------------------
1268// wxActiveXContainer::MSWTranslateMessage
1269//
1270// Called for every message that needs to be translated.
070d6391 1271// Some controls might need more keyboard keys to process (CTRL-C, CTRL-A etc),
8a4e043a
SL
1272// In that case TranslateAccelerator should always be called first.
1273//---------------------------------------------------------------------------
1274bool wxActiveXContainer::MSWTranslateMessage(WXMSG* pMsg)
1275{
1276 if(m_oleInPlaceActiveObject.IsOk() && m_oleInPlaceActiveObject->TranslateAccelerator(pMsg) == S_OK)
1277 {
1278 return true;
1279 }
1280 return wxWindow::MSWTranslateMessage(pMsg);
1281}
1282
1f7d05f0
SL
1283//---------------------------------------------------------------------------
1284// wxActiveXContainer::QueryClientSiteInterface
1285//
1286// Called in the host's site's query method for other interfaces.
1287//---------------------------------------------------------------------------
1288bool wxActiveXContainer::QueryClientSiteInterface(REFIID iid, void **_interface, const char *&desc)
1289{
1290 wxUnusedVar(iid);
1291 wxUnusedVar(_interface);
1292 wxUnusedVar(desc);
1293 return false;
1294}
1295
a1f48575 1296#endif // wxUSE_ACTIVEX