]> git.saurik.com Git - wxWidgets.git/blob - src/msw/ole/activex.cpp
Further attempts at WinCE media control
[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 #ifdef __WXWINCE__
380 IRunnableObject* runnable = NULL;
381 HRESULT hr = QueryInterface(
382 IID_IRunnableObject, (void**)(& runnable));
383 if (SUCCEEDED(hr))
384 {
385 runnable->LockRunning(TRUE, FALSE);
386 }
387 #else
388 OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
389 #endif
390 if (pfNoRedraw)
391 (*pfNoRedraw) = FALSE;
392 return S_OK;
393 }
394
395 HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL)
396 {
397 #ifdef __WXWINCE__
398 IRunnableObject* runnable = NULL;
399 HRESULT hr = QueryInterface(
400 IID_IRunnableObject, (void**)(& runnable));
401 if (SUCCEEDED(hr))
402 {
403 runnable->LockRunning(FALSE, FALSE);
404 }
405 #else
406 OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
407 #endif
408 return S_OK;
409 }
410 STDMETHOD(RequestUIActivate)(){ return S_OK;}
411 //*************************IOleClientSite**************************
412 HRESULT STDMETHODCALLTYPE SaveObject(){return S_OK;}
413 const char *OleGetMonikerToStr(DWORD dwAssign)
414 {
415 switch (dwAssign)
416 {
417 case OLEGETMONIKER_ONLYIFTHERE : return "OLEGETMONIKER_ONLYIFTHERE";
418 case OLEGETMONIKER_FORCEASSIGN : return "OLEGETMONIKER_FORCEASSIGN";
419 case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN";
420 case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER";
421 default : return "Bad Enum";
422 }
423 }
424
425 const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
426 {
427 switch(dwWhichMoniker)
428 {
429 case OLEWHICHMK_CONTAINER : return "OLEWHICHMK_CONTAINER";
430 case OLEWHICHMK_OBJREL : return "OLEWHICHMK_OBJREL";
431 case OLEWHICHMK_OBJFULL : return "OLEWHICHMK_OBJFULL";
432 default : return "Bad Enum";
433 }
434 }
435 STDMETHOD(GetMoniker)(DWORD, DWORD, IMoniker **){return E_FAIL;}
436 HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer)
437 {
438 if (ppContainer == NULL)
439 return E_INVALIDARG;
440 HRESULT hr = QueryInterface(
441 IID_IOleContainer, (void**)(ppContainer));
442 wxASSERT(SUCCEEDED(hr));
443 return hr;
444 }
445 HRESULT STDMETHODCALLTYPE ShowObject()
446 {
447 if (m_window->m_oleObjectHWND)
448 ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
449 return S_OK;
450 }
451 STDMETHOD(OnShowWindow)(BOOL){return S_OK;}
452 STDMETHOD(RequestNewObjectLayout)(){return E_NOTIMPL;}
453 //********************IParseDisplayName***************************
454 HRESULT STDMETHODCALLTYPE ParseDisplayName(
455 IBindCtx *, LPOLESTR, ULONG *, IMoniker **){return E_NOTIMPL;}
456 //********************IOleContainer*******************************
457 STDMETHOD(EnumObjects)(DWORD, IEnumUnknown **){return E_NOTIMPL;}
458 HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;}
459 //********************IOleItemContainer***************************
460 HRESULT STDMETHODCALLTYPE
461 #if defined(__WXWINCE__)
462 GetObject
463 #elif defined(_UNICODE)
464 GetObjectW
465 #else
466 GetObjectA
467 #endif
468 (LPOLESTR pszItem, DWORD, IBindCtx *, REFIID, void ** ppvObject)
469 {
470 if (pszItem == NULL || ppvObject == NULL)
471 return E_INVALIDARG;
472 *ppvObject = NULL;
473 return MK_E_NOOBJECT;
474 }
475 HRESULT STDMETHODCALLTYPE GetObjectStorage(
476 LPOLESTR pszItem, IBindCtx * , REFIID, void ** ppvStorage)
477 {
478 if (pszItem == NULL || ppvStorage == NULL)
479 return E_INVALIDARG;
480 *ppvStorage = NULL;
481 return MK_E_NOOBJECT;
482 }
483 HRESULT STDMETHODCALLTYPE IsRunning(LPOLESTR pszItem)
484 {
485 if (pszItem == NULL)
486 return E_INVALIDARG;
487 return MK_E_NOOBJECT;
488 }
489 //***********************IOleControlSite*****************************
490 HRESULT STDMETHODCALLTYPE OnControlInfoChanged()
491 {return S_OK;}
492 HRESULT STDMETHODCALLTYPE LockInPlaceActive(BOOL fLock)
493 {
494 m_bInPlaceLocked = (fLock) ? true : false;
495 return S_OK;
496 }
497 HRESULT STDMETHODCALLTYPE GetExtendedControl(IDispatch **)
498 {return E_NOTIMPL;}
499 HRESULT STDMETHODCALLTYPE TransformCoords(
500 POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD)
501 {
502 if (pPtlHimetric == NULL || pPtfContainer == NULL)
503 return E_INVALIDARG;
504 return E_NOTIMPL;
505 }
506 HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG, DWORD)
507 {return E_NOTIMPL;}
508 HRESULT STDMETHODCALLTYPE OnFocus(BOOL){return S_OK;}
509 HRESULT STDMETHODCALLTYPE ShowPropertyFrame(){return E_NOTIMPL;}
510 //**************************IOleCommandTarget***********************
511 HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *, ULONG cCmds,
512 OLECMD prgCmds[], OLECMDTEXT *)
513 {
514 if (prgCmds == NULL) return E_INVALIDARG;
515 for (ULONG nCmd = 0; nCmd < cCmds; nCmd++)
516 {
517 // unsupported by default
518 prgCmds[nCmd].cmdf = 0;
519 }
520 return OLECMDERR_E_UNKNOWNGROUP;
521 }
522
523 HRESULT STDMETHODCALLTYPE Exec(const GUID *, DWORD,
524 DWORD, VARIANTARG *, VARIANTARG *)
525 {return OLECMDERR_E_NOTSUPPORTED;}
526
527 //**********************IAdviseSink************************************
528 void STDMETHODCALLTYPE OnDataChange(FORMATETC *, STGMEDIUM *) {}
529 void STDMETHODCALLTYPE OnViewChange(DWORD, LONG) {}
530 void STDMETHODCALLTYPE OnRename(IMoniker *){}
531 void STDMETHODCALLTYPE OnSave(){}
532 void STDMETHODCALLTYPE OnClose(){}
533
534 //**********************IOleDocumentSite***************************
535 HRESULT STDMETHODCALLTYPE ActivateMe(
536 IOleDocumentView __RPC_FAR *pViewToActivate)
537 {
538 wxAutoIOleInPlaceSite inPlaceSite(
539 IID_IOleInPlaceSite, (IDispatch *) this);
540 if (!inPlaceSite.Ok())
541 return E_FAIL;
542
543 if (pViewToActivate)
544 {
545 m_window->m_docView = pViewToActivate;
546 m_window->m_docView->SetInPlaceSite(inPlaceSite);
547 }
548 else
549 {
550 wxAutoIOleDocument oleDoc(
551 IID_IOleDocument, m_window->m_oleObject);
552 if (! oleDoc.Ok())
553 return E_FAIL;
554
555 HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL,
556 0, m_window->m_docView.GetRef());
557 if (hr != S_OK)
558 return E_FAIL;
559
560 m_window->m_docView->SetInPlaceSite(inPlaceSite);
561 }
562
563 m_window->m_docView->UIActivate(TRUE);
564 return S_OK;
565 }
566
567
568 protected:
569 wxActiveXContainer * m_window;
570
571 HDC m_hDCBuffer;
572 HWND m_hWndParent;
573
574 bool m_bSupportsWindowlessActivation;
575 bool m_bInPlaceLocked;
576 bool m_bInPlaceActive;
577 bool m_bUIActive;
578 bool m_bWindowless;
579
580 LCID m_nAmbientLocale;
581 COLORREF m_clrAmbientForeColor;
582 COLORREF m_clrAmbientBackColor;
583 bool m_bAmbientShowHatching;
584 bool m_bAmbientShowGrabHandles;
585 bool m_bAmbientAppearance;
586 };
587
588 DEFINE_OLE_TABLE(FrameSite)
589 OLE_INTERFACE(IID_IUnknown, IOleClientSite)
590 OLE_IINTERFACE(IOleClientSite)
591 OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite)
592 OLE_IINTERFACE(IOleInPlaceSite)
593 OLE_IINTERFACE(IOleInPlaceSiteEx)
594 OLE_IINTERFACE(IOleInPlaceUIWindow)
595 OLE_IINTERFACE(IOleInPlaceFrame)
596 OLE_IINTERFACE(IParseDisplayName)
597 OLE_IINTERFACE(IOleContainer)
598 OLE_IINTERFACE(IOleItemContainer)
599 OLE_IINTERFACE(IDispatch)
600 OLE_IINTERFACE(IOleCommandTarget)
601 OLE_IINTERFACE(IOleDocumentSite)
602 OLE_IINTERFACE(IAdviseSink)
603 OLE_IINTERFACE(IOleControlSite)
604 END_OLE_TABLE
605
606
607 wxActiveXContainer::wxActiveXContainer(wxWindow * parent, REFIID iid, IUnknown* pUnk)
608 : m_realparent(parent)
609 {
610 m_bAmbientUserMode = true;
611 m_docAdviseCookie = 0;
612 CreateActiveX(iid, pUnk);
613 }
614
615 wxActiveXContainer::~wxActiveXContainer()
616 {
617 // disconnect connection points
618 if (m_oleInPlaceObject.Ok())
619 {
620 m_oleInPlaceObject->InPlaceDeactivate();
621 m_oleInPlaceObject->UIDeactivate();
622 }
623
624 if (m_oleObject.Ok())
625 {
626 if (m_docAdviseCookie != 0)
627 m_oleObject->Unadvise(m_docAdviseCookie);
628
629 m_oleObject->DoVerb(
630 OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL);
631 m_oleObject->Close(OLECLOSE_NOSAVE);
632 m_oleObject->SetClientSite(NULL);
633 }
634 }
635
636 void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
637 {
638 HRESULT hret;
639 hret = m_ActiveX.QueryInterface(iid, pUnk);
640 wxASSERT(SUCCEEDED(hret));
641
642 // FrameSite
643 FrameSite *frame = new FrameSite(m_realparent, this);
644 // oleClientSite
645 hret = m_clientSite.QueryInterface(
646 IID_IOleClientSite, (IDispatch *) frame);
647 wxASSERT(SUCCEEDED(hret));
648 // adviseSink
649 wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) frame);
650 wxASSERT(adviseSink.Ok());
651
652 // Get Dispatch interface
653 hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
654
655 // Get IOleObject interface
656 hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
657 wxASSERT(SUCCEEDED(hret));
658
659 // get IViewObject Interface
660 hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
661 wxASSERT(SUCCEEDED(hret));
662
663 // document advise
664 m_docAdviseCookie = 0;
665 hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
666 m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
667 OleSetContainedObject(m_oleObject, TRUE);
668 OleRun(m_oleObject);
669
670
671 // Get IOleInPlaceObject interface
672 hret = m_oleInPlaceObject.QueryInterface(
673 IID_IOleInPlaceObject, m_ActiveX);
674 wxASSERT(SUCCEEDED(hret));
675
676 // status
677 DWORD dwMiscStatus;
678 m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
679 wxASSERT(SUCCEEDED(hret));
680
681 // set client site first ?
682 if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
683 m_oleObject->SetClientSite(m_clientSite);
684
685
686 // stream init
687 wxAutoIPersistStreamInit
688 pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
689
690 if (pPersistStreamInit.Ok())
691 {
692 hret = pPersistStreamInit->InitNew();
693 }
694
695 if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
696 m_oleObject->SetClientSite(m_clientSite);
697
698
699 RECT posRect;
700 ::GetClientRect((HWND)m_realparent->GetHWND(), &posRect);
701
702 m_oleObjectHWND = 0;
703
704 if (m_oleInPlaceObject.Ok())
705 {
706 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
707 if (SUCCEEDED(hret))
708 ::SetActiveWindow(m_oleObjectHWND);
709 }
710
711
712 if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
713 {
714 if (posRect.right > 0 && posRect.bottom > 0 &&
715 m_oleInPlaceObject.Ok())
716 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
717
718 hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
719 m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
720 hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
721 (HWND)m_realparent->GetHWND(), &posRect);
722 }
723
724 if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
725 {
726 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
727 }
728
729 if (m_oleObjectHWND)
730 {
731 ::SetActiveWindow(m_oleObjectHWND);
732 ::ShowWindow(m_oleObjectHWND, SW_SHOW);
733
734 this->AssociateHandle(m_oleObjectHWND);
735 this->Reparent(m_realparent);
736
737 wxWindow* pWnd = m_realparent;
738 int id = m_realparent->GetId();
739
740 pWnd->Connect(id, wxEVT_SIZE,
741 wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this);
742 pWnd->Connect(id, wxEVT_SET_FOCUS,
743 wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this);
744 pWnd->Connect(id, wxEVT_KILL_FOCUS,
745 wxFocusEventHandler(wxActiveXContainer::OnKillFocus), 0, this);
746 }
747 }
748
749 #define HIMETRIC_PER_INCH 2540
750 #define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
751
752 static void PixelsToHimetric(SIZEL &sz)
753 {
754 static int logX = 0;
755 static int logY = 0;
756
757 if (logY == 0)
758 {
759 // initaliase
760 HDC dc = GetDC(NULL);
761 logX = GetDeviceCaps(dc, LOGPIXELSX);
762 logY = GetDeviceCaps(dc, LOGPIXELSY);
763 ReleaseDC(NULL, dc);
764 };
765
766 #define HIMETRIC_INCH 2540
767 #define CONVERT(x, logpixels) wxMulDivInt32(HIMETRIC_INCH, (x), (logpixels))
768
769 sz.cx = CONVERT(sz.cx, logX);
770 sz.cy = CONVERT(sz.cy, logY);
771
772 #undef CONVERT
773 #undef HIMETRIC_INCH
774 }
775
776
777 void wxActiveXContainer::OnSize(wxSizeEvent& event)
778 {
779 int w, h;
780 GetParent()->GetClientSize(&w, &h);
781
782 RECT posRect;
783 posRect.left = 0;
784 posRect.top = 0;
785 posRect.right = w;
786 posRect.bottom = h;
787
788 if (w <= 0 && h <= 0)
789 return;
790
791 // extents are in HIMETRIC units
792 if (m_oleObject.Ok())
793 {
794 SIZEL sz = {w, h};
795 PixelsToHimetric(sz);
796
797 SIZEL sz2;
798
799 m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
800 if (sz2.cx != sz.cx || sz.cy != sz2.cy)
801 m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
802 };
803
804 if (m_oleInPlaceObject.Ok())
805 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
806
807 event.Skip();
808 }
809
810 void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
811 {
812 wxPaintDC dc(this);
813 // Draw only when control is windowless or deactivated
814 if (m_viewObject)
815 {
816 dc.BeginDrawing();
817 int w, h;
818 GetParent()->GetSize(&w, &h);
819 RECT posRect;
820 posRect.left = 0;
821 posRect.top = 0;
822 posRect.right = w;
823 posRect.bottom = h;
824
825 #if defined(_WIN32_WCE) && _WIN32_WCE < 400
826 ::InvalidateRect(m_oleObjectHWND, NULL, false);
827 #else
828 ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
829 #endif
830 RECTL *prcBounds = (RECTL *) &posRect;
831 m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
832 (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
833
834 dc.EndDrawing();
835 }
836
837 // We've got this one I think
838 // event.Skip();
839 }
840
841 void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
842 {
843 if (m_oleInPlaceActiveObject.Ok())
844 m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
845
846 event.Skip();
847 }
848
849 void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
850 {
851 if (m_oleInPlaceActiveObject.Ok())
852 m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
853
854 event.Skip();
855 }