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