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