]> git.saurik.com Git - wxWidgets.git/blame - src/msw/ole/activex.cpp
Always define wxUSE_OWNER_DRAWN so that we don't get lots of warnings
[wxWidgets.git] / src / msw / ole / activex.cpp
CommitLineData
bf354396 1/////////////////////////////////////////////////////////////////////////////
5ccb95f6 2// Name: src/msw/ole/activex.cpp
bf354396
VZ
3// Purpose: wxActiveXContainer implementation
4// Author: Ryan Norton <wxprojects@comcast.net>, Lindsay Mathieson <???>
c493691d 5// Modified by:
bf354396
VZ
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
c493691d
WS
12// ============================================================================
13// declarations
14// ============================================================================
bf354396 15
c493691d
WS
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
bf354396 19
c493691d 20#include "wx/wxprec.h"
bf354396 21
c493691d
WS
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
bf354396 25
c493691d 26#include "wx/dcclient.h"
5ccb95f6 27#include "wx/geometry.h"
c493691d 28#include "wx/msw/ole/activex.h"
bf354396
VZ
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;\
ae199d6e 62 }\
bf354396
VZ
63 const char *desc = NULL;\
64 cls::_GetInterface(this, iid, ppvObject, desc);\
65 if (! *ppvObject)\
66 {\
67 return E_NOINTERFACE;\
ae199d6e 68 }\
bf354396
VZ
69 ((IUnknown * )(*ppvObject))->AddRef();\
70 return S_OK;\
ae199d6e 71 }\
bf354396
VZ
72 ULONG STDMETHODCALLTYPE cls::AddRef()\
73 {\
74 InterlockedIncrement(&refCount.l);\
75 return refCount.l;\
ae199d6e 76 }\
bf354396
VZ
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;\
ae199d6e 86 }\
bf354396
VZ
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;\
ae199d6e 96 }\
bf354396
VZ
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
135class 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{
146private:
147 DECLARE_OLE_UNKNOWN(FrameSite);
148
149public:
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;
4708068c 210#ifndef __WINE__
bf354396
VZ
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;
4708068c 245#endif
bf354396
VZ
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;
ae199d6e 329 }
bf354396
VZ
330
331 hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
332 if (! SUCCEEDED(hr))
333 {
334 (*ppFrame)->Release();
335 *ppFrame = NULL;
336 return E_UNEXPECTED;
ae199d6e 337 }
bf354396
VZ
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;
ae199d6e 346 }
bf354396
VZ
347 if (lprcClipRect)
348 {
349 lprcClipRect->left = lprcClipRect->top = 0;
350 lprcClipRect->right = rect.right;
351 lprcClipRect->bottom = rect.bottom;
ae199d6e 352 }
bf354396
VZ
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";
ae199d6e
VZ
402 }
403 }
bf354396
VZ
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";
ae199d6e
VZ
413 }
414 }
bf354396
VZ
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 #ifdef _UNICODE
442 GetObjectW
443 #else
444 GetObjectA
445 #endif
446 (LPOLESTR pszItem, DWORD, IBindCtx *, REFIID, void ** ppvObject)
447 {
448 if (pszItem == NULL || ppvObject == NULL)
449 return E_INVALIDARG;
450 *ppvObject = NULL;
451 return MK_E_NOOBJECT;
452 }
453 HRESULT STDMETHODCALLTYPE GetObjectStorage(
454 LPOLESTR pszItem, IBindCtx * , REFIID, void ** ppvStorage)
455 {
456 if (pszItem == NULL || ppvStorage == NULL)
457 return E_INVALIDARG;
458 *ppvStorage = NULL;
459 return MK_E_NOOBJECT;
460 }
461 HRESULT STDMETHODCALLTYPE IsRunning(LPOLESTR pszItem)
462 {
463 if (pszItem == NULL)
464 return E_INVALIDARG;
465 return MK_E_NOOBJECT;
466 }
467 //***********************IOleControlSite*****************************
468 HRESULT STDMETHODCALLTYPE OnControlInfoChanged()
469 {return S_OK;}
470 HRESULT STDMETHODCALLTYPE LockInPlaceActive(BOOL fLock)
471 {
472 m_bInPlaceLocked = (fLock) ? true : false;
473 return S_OK;
474 }
475 HRESULT STDMETHODCALLTYPE GetExtendedControl(IDispatch **)
476 {return E_NOTIMPL;}
477 HRESULT STDMETHODCALLTYPE TransformCoords(
478 POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD)
479 {
480 if (pPtlHimetric == NULL || pPtfContainer == NULL)
481 return E_INVALIDARG;
482 return E_NOTIMPL;
483 }
484 HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG, DWORD)
485 {return E_NOTIMPL;}
486 HRESULT STDMETHODCALLTYPE OnFocus(BOOL){return S_OK;}
487 HRESULT STDMETHODCALLTYPE ShowPropertyFrame(){return E_NOTIMPL;}
488 //**************************IOleCommandTarget***********************
489 HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *, ULONG cCmds,
490 OLECMD prgCmds[], OLECMDTEXT *)
491 {
492 if (prgCmds == NULL) return E_INVALIDARG;
493 for (ULONG nCmd = 0; nCmd < cCmds; nCmd++)
494 {
495 // unsupported by default
496 prgCmds[nCmd].cmdf = 0;
497 }
498 return OLECMDERR_E_UNKNOWNGROUP;
499 }
500
501 HRESULT STDMETHODCALLTYPE Exec(const GUID *, DWORD,
502 DWORD, VARIANTARG *, VARIANTARG *)
503 {return OLECMDERR_E_NOTSUPPORTED;}
504
505 //**********************IAdviseSink************************************
506 void STDMETHODCALLTYPE OnDataChange(FORMATETC *, STGMEDIUM *) {}
507 void STDMETHODCALLTYPE OnViewChange(DWORD, LONG) {}
508 void STDMETHODCALLTYPE OnRename(IMoniker *){}
509 void STDMETHODCALLTYPE OnSave(){}
510 void STDMETHODCALLTYPE OnClose(){}
511
512 //**********************IOleDocumentSite***************************
513 HRESULT STDMETHODCALLTYPE ActivateMe(
514 IOleDocumentView __RPC_FAR *pViewToActivate)
515 {
516 wxAutoIOleInPlaceSite inPlaceSite(
517 IID_IOleInPlaceSite, (IDispatch *) this);
518 if (!inPlaceSite.Ok())
519 return E_FAIL;
520
521 if (pViewToActivate)
522 {
523 m_window->m_docView = pViewToActivate;
524 m_window->m_docView->SetInPlaceSite(inPlaceSite);
525 }
526 else
527 {
528 wxAutoIOleDocument oleDoc(
529 IID_IOleDocument, m_window->m_oleObject);
530 if (! oleDoc.Ok())
531 return E_FAIL;
532
533 HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL,
534 0, m_window->m_docView.GetRef());
535 if (hr != S_OK)
536 return E_FAIL;
537
538 m_window->m_docView->SetInPlaceSite(inPlaceSite);
ae199d6e 539 }
bf354396
VZ
540
541 m_window->m_docView->UIActivate(TRUE);
542 return S_OK;
ae199d6e 543 }
bf354396
VZ
544
545
546protected:
547 wxActiveXContainer * m_window;
548
549 HDC m_hDCBuffer;
550 HWND m_hWndParent;
551
552 bool m_bSupportsWindowlessActivation;
553 bool m_bInPlaceLocked;
554 bool m_bInPlaceActive;
555 bool m_bUIActive;
556 bool m_bWindowless;
557
558 LCID m_nAmbientLocale;
559 COLORREF m_clrAmbientForeColor;
560 COLORREF m_clrAmbientBackColor;
561 bool m_bAmbientShowHatching;
562 bool m_bAmbientShowGrabHandles;
563 bool m_bAmbientAppearance;
564};
565
566DEFINE_OLE_TABLE(FrameSite)
567 OLE_INTERFACE(IID_IUnknown, IOleClientSite)
568 OLE_IINTERFACE(IOleClientSite)
569 OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite)
570 OLE_IINTERFACE(IOleInPlaceSite)
571 OLE_IINTERFACE(IOleInPlaceSiteEx)
572 OLE_IINTERFACE(IOleInPlaceUIWindow)
573 OLE_IINTERFACE(IOleInPlaceFrame)
574 OLE_IINTERFACE(IParseDisplayName)
575 OLE_IINTERFACE(IOleContainer)
576 OLE_IINTERFACE(IOleItemContainer)
577 OLE_IINTERFACE(IDispatch)
578 OLE_IINTERFACE(IOleCommandTarget)
579 OLE_IINTERFACE(IOleDocumentSite)
580 OLE_IINTERFACE(IAdviseSink)
581 OLE_IINTERFACE(IOleControlSite)
ae199d6e 582END_OLE_TABLE
bf354396
VZ
583
584
585wxActiveXContainer::wxActiveXContainer(wxWindow * parent, REFIID iid, IUnknown* pUnk)
586 : m_realparent(parent)
587{
588 m_bAmbientUserMode = true;
589 m_docAdviseCookie = 0;
590 CreateActiveX(iid, pUnk);
591}
592
593wxActiveXContainer::~wxActiveXContainer()
594{
595 // disconnect connection points
596 if (m_oleInPlaceObject.Ok())
597 {
598 m_oleInPlaceObject->InPlaceDeactivate();
599 m_oleInPlaceObject->UIDeactivate();
600 }
601
602 if (m_oleObject.Ok())
603 {
604 if (m_docAdviseCookie != 0)
605 m_oleObject->Unadvise(m_docAdviseCookie);
606
607 m_oleObject->DoVerb(
608 OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL);
609 m_oleObject->Close(OLECLOSE_NOSAVE);
610 m_oleObject->SetClientSite(NULL);
611 }
612}
613
614void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
615{
616 HRESULT hret;
617 hret = m_ActiveX.QueryInterface(iid, pUnk);
618 wxASSERT(SUCCEEDED(hret));
619
620 // FrameSite
621 FrameSite *frame = new FrameSite(m_realparent, this);
622 // oleClientSite
623 hret = m_clientSite.QueryInterface(
624 IID_IOleClientSite, (IDispatch *) frame);
625 wxASSERT(SUCCEEDED(hret));
626 // adviseSink
627 wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) frame);
628 wxASSERT(adviseSink.Ok());
629
630 // Get Dispatch interface
631 hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
632
633 // Get IOleObject interface
634 hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
635 wxASSERT(SUCCEEDED(hret));
636
637 // get IViewObject Interface
638 hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
639 wxASSERT(SUCCEEDED(hret));
640
641 // document advise
642 m_docAdviseCookie = 0;
643 hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
644 m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
645 OleSetContainedObject(m_oleObject, TRUE);
646 OleRun(m_oleObject);
647
648
649 // Get IOleInPlaceObject interface
650 hret = m_oleInPlaceObject.QueryInterface(
651 IID_IOleInPlaceObject, m_ActiveX);
652 wxASSERT(SUCCEEDED(hret));
653
654 // status
655 DWORD dwMiscStatus;
656 m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
657 wxASSERT(SUCCEEDED(hret));
658
659 // set client site first ?
660 if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
661 m_oleObject->SetClientSite(m_clientSite);
662
663
664 // stream init
665 wxAutoIPersistStreamInit
666 pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
667
668 if (pPersistStreamInit.Ok())
669 {
670 hret = pPersistStreamInit->InitNew();
671 }
672
673 if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
674 m_oleObject->SetClientSite(m_clientSite);
675
676
677 RECT posRect;
678 ::GetClientRect((HWND)m_realparent->GetHWND(), &posRect);
679
680 m_oleObjectHWND = 0;
681
682 if (m_oleInPlaceObject.Ok())
683 {
684 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
685 if (SUCCEEDED(hret))
686 ::SetActiveWindow(m_oleObjectHWND);
687 }
688
689
690 if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
691 {
692 if (posRect.right > 0 && posRect.bottom > 0 &&
693 m_oleInPlaceObject.Ok())
694 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
695
696 hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
697 m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
698 hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
699 (HWND)m_realparent->GetHWND(), &posRect);
700 }
701
702 if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
703 {
704 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
705 }
706
707 if (m_oleObjectHWND)
708 {
709 ::SetActiveWindow(m_oleObjectHWND);
710 ::ShowWindow(m_oleObjectHWND, SW_SHOW);
711
712 this->AssociateHandle(m_oleObjectHWND);
713 this->Reparent(m_realparent);
714
715 wxWindow* pWnd = m_realparent;
716 int id = m_realparent->GetId();
717
718 pWnd->Connect(id, wxEVT_SIZE,
719 wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this);
720 pWnd->Connect(id, wxEVT_SET_FOCUS,
721 wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this);
722 pWnd->Connect(id, wxEVT_KILL_FOCUS,
723 wxFocusEventHandler(wxActiveXContainer::OnKillFocus), 0, this);
724 }
725}
726
727#define HIMETRIC_PER_INCH 2540
728#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
729
730static void PixelsToHimetric(SIZEL &sz)
731{
732 static int logX = 0;
733 static int logY = 0;
734
735 if (logY == 0)
736 {
737 // initaliase
738 HDC dc = GetDC(NULL);
739 logX = GetDeviceCaps(dc, LOGPIXELSX);
740 logY = GetDeviceCaps(dc, LOGPIXELSY);
741 ReleaseDC(NULL, dc);
742 };
743
744#define HIMETRIC_INCH 2540
5ccb95f6 745#define CONVERT(x, logpixels) wxMulDivInt32(HIMETRIC_INCH, (x), (logpixels))
bf354396
VZ
746
747 sz.cx = CONVERT(sz.cx, logX);
748 sz.cy = CONVERT(sz.cy, logY);
749
750#undef CONVERT
751#undef HIMETRIC_INCH
752}
753
754
755void wxActiveXContainer::OnSize(wxSizeEvent& event)
756{
757 int w, h;
758 GetParent()->GetClientSize(&w, &h);
759
760 RECT posRect;
761 posRect.left = 0;
762 posRect.top = 0;
763 posRect.right = w;
764 posRect.bottom = h;
765
766 if (w <= 0 && h <= 0)
767 return;
768
769 // extents are in HIMETRIC units
770 if (m_oleObject.Ok())
771 {
772 SIZEL sz = {w, h};
773 PixelsToHimetric(sz);
774
775 SIZEL sz2;
776
777 m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
778 if (sz2.cx != sz.cx || sz.cy != sz2.cy)
779 m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
780 };
781
782 if (m_oleInPlaceObject.Ok())
783 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
784
785 event.Skip();
786}
787
788void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
789{
790 wxPaintDC dc(this);
791 // Draw only when control is windowless or deactivated
792 if (m_viewObject)
793 {
794 dc.BeginDrawing();
795 int w, h;
796 GetParent()->GetSize(&w, &h);
797 RECT posRect;
798 posRect.left = 0;
799 posRect.top = 0;
800 posRect.right = w;
801 posRect.bottom = h;
802
803 ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
804 RECTL *prcBounds = (RECTL *) &posRect;
805 m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
806 (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
807
808 dc.EndDrawing();
809 }
810
811// We've got this one I think
812// event.Skip();
813}
814
815void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
816{
817 if (m_oleInPlaceActiveObject.Ok())
818 m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
819
820 event.Skip();
821}
822
823void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
824{
825 if (m_oleInPlaceActiveObject.Ok())
826 m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
827
828 event.Skip();
829}