]> git.saurik.com Git - wxWidgets.git/blame - src/msw/ole/activex.cpp
use WX_DEFINE_ARRAY_PTR for anarray of pointers (fixes Sun CC warning)
[wxWidgets.git] / src / msw / ole / activex.cpp
CommitLineData
bf354396
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: msw/ole/activex.cpp
3// Purpose: wxActiveXContainer implementation
4// Author: Ryan Norton <wxprojects@comcast.net>, Lindsay Mathieson <???>
5// Modified by:
6// Created: 11/07/04
7// RCS-ID: $Id$
8// Copyright: (c) 2003 Lindsay Mathieson, (c) 2005 Ryan Norton
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12//===========================================================================
13// DECLARATIONS
14//===========================================================================
15
16//---------------------------------------------------------------------------
17// WX include
18//---------------------------------------------------------------------------
19#include "wx/wxprec.h"
20
21#include "wx/msw/ole/activex.h"
22
23
24
25
26//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27//
28// wxActiveXContainer
29//
30//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31
32#define DECLARE_OLE_UNKNOWN(cls)\
33 private:\
34 class TAutoInitInt\
35 {\
36 public:\
37 LONG l;\
38 TAutoInitInt() : l(0) {}\
39 };\
40 TAutoInitInt refCount, lockCount;\
41 static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\
42 public:\
43 LONG GetRefCount();\
44 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\
45 ULONG STDMETHODCALLTYPE AddRef();\
46 ULONG STDMETHODCALLTYPE Release();\
47 ULONG STDMETHODCALLTYPE AddLock();\
48 ULONG STDMETHODCALLTYPE ReleaseLock()
49
50#define DEFINE_OLE_TABLE(cls)\
51 LONG cls::GetRefCount() {return refCount.l;}\
52 HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\
53 {\
54 if (! ppvObject)\
55 {\
56 return E_FAIL;\
57 };\
58 const char *desc = NULL;\
59 cls::_GetInterface(this, iid, ppvObject, desc);\
60 if (! *ppvObject)\
61 {\
62 return E_NOINTERFACE;\
63 };\
64 ((IUnknown * )(*ppvObject))->AddRef();\
65 return S_OK;\
66 };\
67 ULONG STDMETHODCALLTYPE cls::AddRef()\
68 {\
69 InterlockedIncrement(&refCount.l);\
70 return refCount.l;\
71 };\
72 ULONG STDMETHODCALLTYPE cls::Release()\
73 {\
74 if (refCount.l > 0)\
75 {\
76 InterlockedDecrement(&refCount.l);\
77 if (refCount.l == 0)\
78 {\
79 delete this;\
80 return 0;\
81 };\
82 return refCount.l;\
83 }\
84 else\
85 return 0;\
86 }\
87 ULONG STDMETHODCALLTYPE cls::AddLock()\
88 {\
89 InterlockedIncrement(&lockCount.l);\
90 return lockCount.l;\
91 };\
92 ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
93 {\
94 if (lockCount.l > 0)\
95 {\
96 InterlockedDecrement(&lockCount.l);\
97 return lockCount.l;\
98 }\
99 else\
100 return 0;\
101 }\
102 DEFINE_OLE_BASE(cls)
103
104#define DEFINE_OLE_BASE(cls)\
105 void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\
106 {\
107 *_interface = NULL;\
108 desc = NULL;
109
110#define OLE_INTERFACE(_iid, _type)\
111 if (IsEqualIID(iid, _iid))\
112 {\
113 *_interface = (IUnknown *) (_type *) self;\
114 desc = # _iid;\
115 return;\
116 }
117
118#define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face)
119
120#define OLE_INTERFACE_CUSTOM(func)\
121 if (func(self, iid, _interface, desc))\
122 {\
123 return;\
124 }
125
126#define END_OLE_TABLE\
127 }
128
129
130class FrameSite :
131 public IOleClientSite,
132 public IOleInPlaceSiteEx,
133 public IOleInPlaceFrame,
134 public IOleItemContainer,
135 public IDispatch,
136 public IOleCommandTarget,
137 public IOleDocumentSite,
138 public IAdviseSink,
139 public IOleControlSite
140{
141private:
142 DECLARE_OLE_UNKNOWN(FrameSite);
143
144public:
145 FrameSite(wxWindow * win, wxActiveXContainer * win2)
146 {
147 m_window = win2;
148 m_bSupportsWindowlessActivation = true;
149 m_bInPlaceLocked = false;
150 m_bUIActive = false;
151 m_bInPlaceActive = false;
152 m_bWindowless = false;
153
154 m_nAmbientLocale = 0;
155 m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT);
156 m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW);
157 m_bAmbientShowHatching = true;
158 m_bAmbientShowGrabHandles = true;
159 m_bAmbientAppearance = true;
160
161 m_hDCBuffer = NULL;
162 m_hWndParent = (HWND)win->GetHWND();
163 }
164 virtual ~FrameSite(){}
165 //***************************IDispatch*****************************
166 HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, OLECHAR ** ,
167 unsigned int , LCID ,
168 DISPID * )
169 { return E_NOTIMPL; }
170 STDMETHOD(GetTypeInfo)(unsigned int, LCID, ITypeInfo **)
171 { return E_NOTIMPL; }
172 HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *)
173 { return E_NOTIMPL; }
174 HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID, LCID,
175 WORD wFlags, DISPPARAMS *,
176 VARIANT * pVarResult, EXCEPINFO *,
177 unsigned int *)
178 {
179 if (!(wFlags & DISPATCH_PROPERTYGET))
180 return S_OK;
181
182 if (pVarResult == NULL)
183 return E_INVALIDARG;
184
185 //The most common case is boolean, use as an initial type
186 V_VT(pVarResult) = VT_BOOL;
187
188 switch (dispIdMember)
189 {
190 case DISPID_AMBIENT_MESSAGEREFLECT:
191 V_BOOL(pVarResult)= FALSE;
192 return S_OK;
193
194 case DISPID_AMBIENT_DISPLAYASDEFAULT:
195 V_BOOL(pVarResult)= TRUE;
196 return S_OK;
197
198 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
199 V_BOOL(pVarResult) = TRUE;
200 return S_OK;
201
202 case DISPID_AMBIENT_SILENT:
203 V_BOOL(pVarResult)= TRUE;
204 return S_OK;
205
206 case DISPID_AMBIENT_APPEARANCE:
207 pVarResult->vt = VT_BOOL;
208 pVarResult->boolVal = m_bAmbientAppearance;
209 break;
210
211 case DISPID_AMBIENT_FORECOLOR:
212 pVarResult->vt = VT_I4;
213 pVarResult->lVal = (long) m_clrAmbientForeColor;
214 break;
215
216 case DISPID_AMBIENT_BACKCOLOR:
217 pVarResult->vt = VT_I4;
218 pVarResult->lVal = (long) m_clrAmbientBackColor;
219 break;
220
221 case DISPID_AMBIENT_LOCALEID:
222 pVarResult->vt = VT_I4;
223 pVarResult->lVal = (long) m_nAmbientLocale;
224 break;
225
226 case DISPID_AMBIENT_USERMODE:
227 pVarResult->vt = VT_BOOL;
228 pVarResult->boolVal = m_window->m_bAmbientUserMode;
229 break;
230
231 case DISPID_AMBIENT_SHOWGRABHANDLES:
232 pVarResult->vt = VT_BOOL;
233 pVarResult->boolVal = m_bAmbientShowGrabHandles;
234 break;
235
236 case DISPID_AMBIENT_SHOWHATCHING:
237 pVarResult->vt = VT_BOOL;
238 pVarResult->boolVal = m_bAmbientShowHatching;
239 break;
240
241 default:
242 return DISP_E_MEMBERNOTFOUND;
243 }
244
245 return S_OK;
246 }
247
248 //**************************IOleWindow***************************
249 HRESULT STDMETHODCALLTYPE GetWindow(HWND * phwnd)
250 {
251 if (phwnd == NULL)
252 return E_INVALIDARG;
253 (*phwnd) = m_hWndParent;
254 return S_OK;
255 }
256 HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL)
257 {return S_OK;}
258 //**************************IOleInPlaceUIWindow*****************
259 HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder)
260 {
261 if (lprectBorder == NULL)
262 return E_INVALIDARG;
263 return INPLACE_E_NOTOOLSPACE;
264 }
265 HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
266 {
267 if (pborderwidths == NULL)
268 return E_INVALIDARG;
269 return INPLACE_E_NOTOOLSPACE;
270 }
271 HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS)
272 {return S_OK;}
273 HRESULT STDMETHODCALLTYPE SetActiveObject(
274 IOleInPlaceActiveObject *pActiveObject, LPCOLESTR)
275 {
276 if (pActiveObject)
277 pActiveObject->AddRef();
278
279 m_window->m_oleInPlaceActiveObject = pActiveObject;
280 return S_OK;
281 }
282
283 //********************IOleInPlaceFrame************************
284
285 STDMETHOD(InsertMenus)(HMENU, LPOLEMENUGROUPWIDTHS){return S_OK;}
286 STDMETHOD(SetMenu)(HMENU, HOLEMENU, HWND){ return S_OK;}
287 STDMETHOD(RemoveMenus)(HMENU){return S_OK;}
288 STDMETHOD(SetStatusText)(LPCOLESTR){ return S_OK;}
289 HRESULT STDMETHODCALLTYPE EnableModeless(BOOL){return S_OK;}
290 HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD)
291 {
292 // TODO: send an event with this id
293 if (m_window->m_oleInPlaceActiveObject.Ok())
294 m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
295 return S_FALSE;
296 }
297
298 //*******************IOleInPlaceSite**************************
299 HRESULT STDMETHODCALLTYPE CanInPlaceActivate(){return S_OK;}
300 HRESULT STDMETHODCALLTYPE OnInPlaceActivate()
301 { m_bInPlaceActive = true; return S_OK; }
302 HRESULT STDMETHODCALLTYPE OnUIActivate()
303 { m_bUIActive = true; return S_OK; }
304 HRESULT STDMETHODCALLTYPE GetWindowContext(IOleInPlaceFrame **ppFrame,
305 IOleInPlaceUIWindow **ppDoc,
306 LPRECT lprcPosRect,
307 LPRECT lprcClipRect,
308 LPOLEINPLACEFRAMEINFO lpFrameInfo)
309 {
310 if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL ||
311 lprcClipRect == NULL || lpFrameInfo == NULL)
312 {
313 if (ppFrame != NULL)
314 (*ppFrame) = NULL;
315 if (ppDoc != NULL)
316 (*ppDoc) = NULL;
317 return E_INVALIDARG;
318 }
319
320 HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame);
321 if (! SUCCEEDED(hr))
322 {
323 return E_UNEXPECTED;
324 };
325
326 hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
327 if (! SUCCEEDED(hr))
328 {
329 (*ppFrame)->Release();
330 *ppFrame = NULL;
331 return E_UNEXPECTED;
332 };
333
334 RECT rect;
335 ::GetClientRect(m_hWndParent, &rect);
336 if (lprcPosRect)
337 {
338 lprcPosRect->left = lprcPosRect->top = 0;
339 lprcPosRect->right = rect.right;
340 lprcPosRect->bottom = rect.bottom;
341 };
342 if (lprcClipRect)
343 {
344 lprcClipRect->left = lprcClipRect->top = 0;
345 lprcClipRect->right = rect.right;
346 lprcClipRect->bottom = rect.bottom;
347 };
348
349 memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
350 lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
351 lpFrameInfo->hwndFrame = m_hWndParent;
352
353 return S_OK;
354 }
355 HRESULT STDMETHODCALLTYPE Scroll(SIZE){return S_OK;}
356 HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL)
357 { m_bUIActive = false; return S_OK; }
358 HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate()
359 { m_bInPlaceActive = false; return S_OK; }
360 HRESULT STDMETHODCALLTYPE DiscardUndoState(){return S_OK;}
361 HRESULT STDMETHODCALLTYPE DeactivateAndUndo(){return S_OK; }
362 HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect)
363 {
364 if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
365 {
366 m_window->m_oleInPlaceObject->SetObjectRects(
367 lprcPosRect, lprcPosRect);
368 }
369 return S_OK;
370 }
371 //*************************IOleInPlaceSiteEx***********************
372 HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD)
373 {
374 OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
375 if (pfNoRedraw)
376 (*pfNoRedraw) = FALSE;
377 return S_OK;
378 }
379
380 HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL)
381 {
382 OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
383 return S_OK;
384 }
385 STDMETHOD(RequestUIActivate)(){ return S_OK;}
386 //*************************IOleClientSite**************************
387 HRESULT STDMETHODCALLTYPE SaveObject(){return S_OK;}
388 const char *OleGetMonikerToStr(DWORD dwAssign)
389 {
390 switch (dwAssign)
391 {
392 case OLEGETMONIKER_ONLYIFTHERE : return "OLEGETMONIKER_ONLYIFTHERE";
393 case OLEGETMONIKER_FORCEASSIGN : return "OLEGETMONIKER_FORCEASSIGN";
394 case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN";
395 case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER";
396 default : return "Bad Enum";
397 };
398 };
399
400 const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
401 {
402 switch(dwWhichMoniker)
403 {
404 case OLEWHICHMK_CONTAINER : return "OLEWHICHMK_CONTAINER";
405 case OLEWHICHMK_OBJREL : return "OLEWHICHMK_OBJREL";
406 case OLEWHICHMK_OBJFULL : return "OLEWHICHMK_OBJFULL";
407 default : return "Bad Enum";
408 };
409 };
410 STDMETHOD(GetMoniker)(DWORD, DWORD, IMoniker **){return E_FAIL;}
411 HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer)
412 {
413 if (ppContainer == NULL)
414 return E_INVALIDARG;
415 HRESULT hr = QueryInterface(
416 IID_IOleContainer, (void**)(ppContainer));
417 wxASSERT(SUCCEEDED(hr));
418 return hr;
419 }
420 HRESULT STDMETHODCALLTYPE ShowObject()
421 {
422 if (m_window->m_oleObjectHWND)
423 ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
424 return S_OK;
425 }
426 STDMETHOD(OnShowWindow)(BOOL){return S_OK;}
427 STDMETHOD(RequestNewObjectLayout)(){return E_NOTIMPL;}
428 //********************IParseDisplayName***************************
429 HRESULT STDMETHODCALLTYPE ParseDisplayName(
430 IBindCtx *, LPOLESTR, ULONG *, IMoniker **){return E_NOTIMPL;}
431 //********************IOleContainer*******************************
432 STDMETHOD(EnumObjects)(DWORD, IEnumUnknown **){return E_NOTIMPL;}
433 HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;}
434 //********************IOleItemContainer***************************
435 HRESULT STDMETHODCALLTYPE
436 #ifdef _UNICODE
437 GetObjectW
438 #else
439 GetObjectA
440 #endif
441 (LPOLESTR pszItem, DWORD, IBindCtx *, REFIID, void ** ppvObject)
442 {
443 if (pszItem == NULL || ppvObject == NULL)
444 return E_INVALIDARG;
445 *ppvObject = NULL;
446 return MK_E_NOOBJECT;
447 }
448 HRESULT STDMETHODCALLTYPE GetObjectStorage(
449 LPOLESTR pszItem, IBindCtx * , REFIID, void ** ppvStorage)
450 {
451 if (pszItem == NULL || ppvStorage == NULL)
452 return E_INVALIDARG;
453 *ppvStorage = NULL;
454 return MK_E_NOOBJECT;
455 }
456 HRESULT STDMETHODCALLTYPE IsRunning(LPOLESTR pszItem)
457 {
458 if (pszItem == NULL)
459 return E_INVALIDARG;
460 return MK_E_NOOBJECT;
461 }
462 //***********************IOleControlSite*****************************
463 HRESULT STDMETHODCALLTYPE OnControlInfoChanged()
464 {return S_OK;}
465 HRESULT STDMETHODCALLTYPE LockInPlaceActive(BOOL fLock)
466 {
467 m_bInPlaceLocked = (fLock) ? true : false;
468 return S_OK;
469 }
470 HRESULT STDMETHODCALLTYPE GetExtendedControl(IDispatch **)
471 {return E_NOTIMPL;}
472 HRESULT STDMETHODCALLTYPE TransformCoords(
473 POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD)
474 {
475 if (pPtlHimetric == NULL || pPtfContainer == NULL)
476 return E_INVALIDARG;
477 return E_NOTIMPL;
478 }
479 HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG, DWORD)
480 {return E_NOTIMPL;}
481 HRESULT STDMETHODCALLTYPE OnFocus(BOOL){return S_OK;}
482 HRESULT STDMETHODCALLTYPE ShowPropertyFrame(){return E_NOTIMPL;}
483 //**************************IOleCommandTarget***********************
484 HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *, ULONG cCmds,
485 OLECMD prgCmds[], OLECMDTEXT *)
486 {
487 if (prgCmds == NULL) return E_INVALIDARG;
488 for (ULONG nCmd = 0; nCmd < cCmds; nCmd++)
489 {
490 // unsupported by default
491 prgCmds[nCmd].cmdf = 0;
492 }
493 return OLECMDERR_E_UNKNOWNGROUP;
494 }
495
496 HRESULT STDMETHODCALLTYPE Exec(const GUID *, DWORD,
497 DWORD, VARIANTARG *, VARIANTARG *)
498 {return OLECMDERR_E_NOTSUPPORTED;}
499
500 //**********************IAdviseSink************************************
501 void STDMETHODCALLTYPE OnDataChange(FORMATETC *, STGMEDIUM *) {}
502 void STDMETHODCALLTYPE OnViewChange(DWORD, LONG) {}
503 void STDMETHODCALLTYPE OnRename(IMoniker *){}
504 void STDMETHODCALLTYPE OnSave(){}
505 void STDMETHODCALLTYPE OnClose(){}
506
507 //**********************IOleDocumentSite***************************
508 HRESULT STDMETHODCALLTYPE ActivateMe(
509 IOleDocumentView __RPC_FAR *pViewToActivate)
510 {
511 wxAutoIOleInPlaceSite inPlaceSite(
512 IID_IOleInPlaceSite, (IDispatch *) this);
513 if (!inPlaceSite.Ok())
514 return E_FAIL;
515
516 if (pViewToActivate)
517 {
518 m_window->m_docView = pViewToActivate;
519 m_window->m_docView->SetInPlaceSite(inPlaceSite);
520 }
521 else
522 {
523 wxAutoIOleDocument oleDoc(
524 IID_IOleDocument, m_window->m_oleObject);
525 if (! oleDoc.Ok())
526 return E_FAIL;
527
528 HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL,
529 0, m_window->m_docView.GetRef());
530 if (hr != S_OK)
531 return E_FAIL;
532
533 m_window->m_docView->SetInPlaceSite(inPlaceSite);
534 };
535
536 m_window->m_docView->UIActivate(TRUE);
537 return S_OK;
538 };
539
540
541protected:
542 wxActiveXContainer * m_window;
543
544 HDC m_hDCBuffer;
545 HWND m_hWndParent;
546
547 bool m_bSupportsWindowlessActivation;
548 bool m_bInPlaceLocked;
549 bool m_bInPlaceActive;
550 bool m_bUIActive;
551 bool m_bWindowless;
552
553 LCID m_nAmbientLocale;
554 COLORREF m_clrAmbientForeColor;
555 COLORREF m_clrAmbientBackColor;
556 bool m_bAmbientShowHatching;
557 bool m_bAmbientShowGrabHandles;
558 bool m_bAmbientAppearance;
559};
560
561DEFINE_OLE_TABLE(FrameSite)
562 OLE_INTERFACE(IID_IUnknown, IOleClientSite)
563 OLE_IINTERFACE(IOleClientSite)
564 OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite)
565 OLE_IINTERFACE(IOleInPlaceSite)
566 OLE_IINTERFACE(IOleInPlaceSiteEx)
567 OLE_IINTERFACE(IOleInPlaceUIWindow)
568 OLE_IINTERFACE(IOleInPlaceFrame)
569 OLE_IINTERFACE(IParseDisplayName)
570 OLE_IINTERFACE(IOleContainer)
571 OLE_IINTERFACE(IOleItemContainer)
572 OLE_IINTERFACE(IDispatch)
573 OLE_IINTERFACE(IOleCommandTarget)
574 OLE_IINTERFACE(IOleDocumentSite)
575 OLE_IINTERFACE(IAdviseSink)
576 OLE_IINTERFACE(IOleControlSite)
577END_OLE_TABLE;
578
579
580wxActiveXContainer::wxActiveXContainer(wxWindow * parent, REFIID iid, IUnknown* pUnk)
581 : m_realparent(parent)
582{
583 m_bAmbientUserMode = true;
584 m_docAdviseCookie = 0;
585 CreateActiveX(iid, pUnk);
586}
587
588wxActiveXContainer::~wxActiveXContainer()
589{
590 // disconnect connection points
591 if (m_oleInPlaceObject.Ok())
592 {
593 m_oleInPlaceObject->InPlaceDeactivate();
594 m_oleInPlaceObject->UIDeactivate();
595 }
596
597 if (m_oleObject.Ok())
598 {
599 if (m_docAdviseCookie != 0)
600 m_oleObject->Unadvise(m_docAdviseCookie);
601
602 m_oleObject->DoVerb(
603 OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL);
604 m_oleObject->Close(OLECLOSE_NOSAVE);
605 m_oleObject->SetClientSite(NULL);
606 }
607}
608
609void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
610{
611 HRESULT hret;
612 hret = m_ActiveX.QueryInterface(iid, pUnk);
613 wxASSERT(SUCCEEDED(hret));
614
615 // FrameSite
616 FrameSite *frame = new FrameSite(m_realparent, this);
617 // oleClientSite
618 hret = m_clientSite.QueryInterface(
619 IID_IOleClientSite, (IDispatch *) frame);
620 wxASSERT(SUCCEEDED(hret));
621 // adviseSink
622 wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) frame);
623 wxASSERT(adviseSink.Ok());
624
625 // Get Dispatch interface
626 hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
627
628 // Get IOleObject interface
629 hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
630 wxASSERT(SUCCEEDED(hret));
631
632 // get IViewObject Interface
633 hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
634 wxASSERT(SUCCEEDED(hret));
635
636 // document advise
637 m_docAdviseCookie = 0;
638 hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
639 m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
640 OleSetContainedObject(m_oleObject, TRUE);
641 OleRun(m_oleObject);
642
643
644 // Get IOleInPlaceObject interface
645 hret = m_oleInPlaceObject.QueryInterface(
646 IID_IOleInPlaceObject, m_ActiveX);
647 wxASSERT(SUCCEEDED(hret));
648
649 // status
650 DWORD dwMiscStatus;
651 m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
652 wxASSERT(SUCCEEDED(hret));
653
654 // set client site first ?
655 if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
656 m_oleObject->SetClientSite(m_clientSite);
657
658
659 // stream init
660 wxAutoIPersistStreamInit
661 pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
662
663 if (pPersistStreamInit.Ok())
664 {
665 hret = pPersistStreamInit->InitNew();
666 }
667
668 if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
669 m_oleObject->SetClientSite(m_clientSite);
670
671
672 RECT posRect;
673 ::GetClientRect((HWND)m_realparent->GetHWND(), &posRect);
674
675 m_oleObjectHWND = 0;
676
677 if (m_oleInPlaceObject.Ok())
678 {
679 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
680 if (SUCCEEDED(hret))
681 ::SetActiveWindow(m_oleObjectHWND);
682 }
683
684
685 if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
686 {
687 if (posRect.right > 0 && posRect.bottom > 0 &&
688 m_oleInPlaceObject.Ok())
689 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
690
691 hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
692 m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
693 hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
694 (HWND)m_realparent->GetHWND(), &posRect);
695 }
696
697 if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
698 {
699 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
700 }
701
702 if (m_oleObjectHWND)
703 {
704 ::SetActiveWindow(m_oleObjectHWND);
705 ::ShowWindow(m_oleObjectHWND, SW_SHOW);
706
707 this->AssociateHandle(m_oleObjectHWND);
708 this->Reparent(m_realparent);
709
710 wxWindow* pWnd = m_realparent;
711 int id = m_realparent->GetId();
712
713 pWnd->Connect(id, wxEVT_SIZE,
714 wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this);
715 pWnd->Connect(id, wxEVT_SET_FOCUS,
716 wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this);
717 pWnd->Connect(id, wxEVT_KILL_FOCUS,
718 wxFocusEventHandler(wxActiveXContainer::OnKillFocus), 0, this);
719 }
720}
721
722#define HIMETRIC_PER_INCH 2540
723#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
724
725static void PixelsToHimetric(SIZEL &sz)
726{
727 static int logX = 0;
728 static int logY = 0;
729
730 if (logY == 0)
731 {
732 // initaliase
733 HDC dc = GetDC(NULL);
734 logX = GetDeviceCaps(dc, LOGPIXELSX);
735 logY = GetDeviceCaps(dc, LOGPIXELSY);
736 ReleaseDC(NULL, dc);
737 };
738
739#define HIMETRIC_INCH 2540
740#define CONVERT(x, logpixels) MulDiv(HIMETRIC_INCH, (x), (logpixels))
741
742 sz.cx = CONVERT(sz.cx, logX);
743 sz.cy = CONVERT(sz.cy, logY);
744
745#undef CONVERT
746#undef HIMETRIC_INCH
747}
748
749
750void wxActiveXContainer::OnSize(wxSizeEvent& event)
751{
752 int w, h;
753 GetParent()->GetClientSize(&w, &h);
754
755 RECT posRect;
756 posRect.left = 0;
757 posRect.top = 0;
758 posRect.right = w;
759 posRect.bottom = h;
760
761 if (w <= 0 && h <= 0)
762 return;
763
764 // extents are in HIMETRIC units
765 if (m_oleObject.Ok())
766 {
767 SIZEL sz = {w, h};
768 PixelsToHimetric(sz);
769
770 SIZEL sz2;
771
772 m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
773 if (sz2.cx != sz.cx || sz.cy != sz2.cy)
774 m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
775 };
776
777 if (m_oleInPlaceObject.Ok())
778 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
779
780 event.Skip();
781}
782
783void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
784{
785 wxPaintDC dc(this);
786 // Draw only when control is windowless or deactivated
787 if (m_viewObject)
788 {
789 dc.BeginDrawing();
790 int w, h;
791 GetParent()->GetSize(&w, &h);
792 RECT posRect;
793 posRect.left = 0;
794 posRect.top = 0;
795 posRect.right = w;
796 posRect.bottom = h;
797
798 ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
799 RECTL *prcBounds = (RECTL *) &posRect;
800 m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
801 (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
802
803 dc.EndDrawing();
804 }
805
806// We've got this one I think
807// event.Skip();
808}
809
810void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
811{
812 if (m_oleInPlaceActiveObject.Ok())
813 m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
814
815 event.Skip();
816}
817
818void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
819{
820 if (m_oleInPlaceActiveObject.Ok())
821 m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
822
823 event.Skip();
824}