1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/ole/activex.cpp
3 // Purpose: wxActiveXContainer implementation
4 // Author: Ryan Norton <wxprojects@comcast.net>, Lindsay Mathieson <???>
8 // Copyright: (c) 2003 Lindsay Mathieson, (c) 2005 Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
27 #include "wx/dcclient.h"
31 // I don't know why members of tagVARIANT aren't found when compiling
35 #include "wx/msw/ole/activex.h"
36 // autointerfaces that we only use here
37 WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite
, IOleInPlaceSite
)
38 WX_DECLARE_AUTOOLE(wxAutoIOleDocument
, IOleDocument
)
39 WX_DECLARE_AUTOOLE(wxAutoIPersistStreamInit
, IPersistStreamInit
)
40 WX_DECLARE_AUTOOLE(wxAutoIAdviseSink
, IAdviseSink
)
41 WX_DECLARE_AUTOOLE(wxAutoIProvideClassInfo
, IProvideClassInfo
)
42 WX_DECLARE_AUTOOLE(wxAutoITypeInfo
, ITypeInfo
)
43 WX_DECLARE_AUTOOLE(wxAutoIConnectionPoint
, IConnectionPoint
)
44 WX_DECLARE_AUTOOLE(wxAutoIConnectionPointContainer
, IConnectionPointContainer
)
46 DEFINE_EVENT_TYPE(wxEVT_ACTIVEX
)
48 // Ole class helpers (sort of MFC-like) from wxActiveX
49 #define DECLARE_OLE_UNKNOWN(cls)\
55 TAutoInitInt() : l(0) {}\
57 TAutoInitInt refCount, lockCount;\
58 static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\
61 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\
62 ULONG STDMETHODCALLTYPE AddRef();\
63 ULONG STDMETHODCALLTYPE Release();\
64 ULONG STDMETHODCALLTYPE AddLock();\
65 ULONG STDMETHODCALLTYPE ReleaseLock()
67 #define DEFINE_OLE_TABLE(cls)\
68 LONG cls::GetRefCount() {return refCount.l;}\
69 HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\
75 const char *desc = NULL;\
76 cls::_GetInterface(this, iid, ppvObject, desc);\
79 return E_NOINTERFACE;\
81 ((IUnknown * )(*ppvObject))->AddRef();\
84 ULONG STDMETHODCALLTYPE cls::AddRef()\
86 InterlockedIncrement(&refCount.l);\
89 ULONG STDMETHODCALLTYPE cls::Release()\
93 InterlockedDecrement(&refCount.l);\
104 ULONG STDMETHODCALLTYPE cls::AddLock()\
106 InterlockedIncrement(&lockCount.l);\
109 ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
111 if (lockCount.l > 0)\
113 InterlockedDecrement(&lockCount.l);\
121 #define DEFINE_OLE_BASE(cls)\
122 void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\
127 #define OLE_INTERFACE(_iid, _type)\
128 if (IsEqualIID(iid, _iid))\
130 *_interface = (IUnknown *) (_type *) self;\
135 #define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face)
137 #define OLE_INTERFACE_CUSTOM(func)\
138 if (func(self, iid, _interface, desc))\
143 #define END_OLE_TABLE\
146 // ============================================================================
148 // ============================================================================
150 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
153 // Utility to convert from pixels to the himetric values in some COM methods
154 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
157 #define HIMETRIC_PER_INCH 2540
158 #define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
160 static void PixelsToHimetric(SIZEL
&sz
)
168 HDC dc
= GetDC(NULL
);
169 logX
= GetDeviceCaps(dc
, LOGPIXELSX
);
170 logY
= GetDeviceCaps(dc
, LOGPIXELSY
);
174 #define HIMETRIC_INCH 2540
175 #define CONVERT(x, logpixels) wxMulDivInt32(HIMETRIC_INCH, (x), (logpixels))
177 sz
.cx
= CONVERT(sz
.cx
, logX
);
178 sz
.cy
= CONVERT(sz
.cy
, logY
);
185 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
189 // Handles the actual wxActiveX container implementation
191 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
193 public IOleClientSite
,
194 public IOleInPlaceSiteEx
,
195 public IOleInPlaceFrame
,
196 public IOleItemContainer
,
198 public IOleCommandTarget
,
199 public IOleDocumentSite
,
201 public IOleControlSite
204 DECLARE_OLE_UNKNOWN(FrameSite
);
207 FrameSite(wxWindow
* win
, wxActiveXContainer
* win2
)
210 m_bSupportsWindowlessActivation
= true;
211 m_bInPlaceLocked
= false;
213 m_bInPlaceActive
= false;
214 m_bWindowless
= false;
216 m_nAmbientLocale
= 0;
217 m_clrAmbientForeColor
= ::GetSysColor(COLOR_WINDOWTEXT
);
218 m_clrAmbientBackColor
= ::GetSysColor(COLOR_WINDOW
);
219 m_bAmbientShowHatching
= true;
220 m_bAmbientShowGrabHandles
= true;
221 m_bAmbientAppearance
= true;
224 m_hWndParent
= (HWND
)win
->GetHWND();
226 virtual ~FrameSite(){}
227 //***************************IDispatch*****************************
228 HRESULT STDMETHODCALLTYPE
GetIDsOfNames(REFIID
, OLECHAR
** ,
229 unsigned int , LCID
,
231 { return E_NOTIMPL
; }
232 STDMETHOD(GetTypeInfo
)(unsigned int, LCID
, ITypeInfo
**)
233 { return E_NOTIMPL
; }
234 HRESULT STDMETHODCALLTYPE
GetTypeInfoCount(unsigned int *)
235 { return E_NOTIMPL
; }
236 HRESULT STDMETHODCALLTYPE
Invoke(DISPID dispIdMember
, REFIID
, LCID
,
237 WORD wFlags
, DISPPARAMS
*,
238 VARIANT
* pVarResult
, EXCEPINFO
*,
241 if (!(wFlags
& DISPATCH_PROPERTYGET
))
244 if (pVarResult
== NULL
)
247 //The most common case is boolean, use as an initial type
248 V_VT(pVarResult
) = VT_BOOL
;
250 switch (dispIdMember
)
252 case DISPID_AMBIENT_MESSAGEREFLECT
:
253 V_BOOL(pVarResult
)= FALSE
;
256 case DISPID_AMBIENT_DISPLAYASDEFAULT
:
257 V_BOOL(pVarResult
)= TRUE
;
260 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED
:
261 V_BOOL(pVarResult
) = TRUE
;
264 case DISPID_AMBIENT_SILENT
:
265 V_BOOL(pVarResult
)= TRUE
;
268 case DISPID_AMBIENT_APPEARANCE
:
269 pVarResult
->vt
= VT_BOOL
;
270 pVarResult
->boolVal
= m_bAmbientAppearance
;
273 case DISPID_AMBIENT_FORECOLOR
:
274 pVarResult
->vt
= VT_I4
;
275 pVarResult
->lVal
= (long) m_clrAmbientForeColor
;
278 case DISPID_AMBIENT_BACKCOLOR
:
279 pVarResult
->vt
= VT_I4
;
280 pVarResult
->lVal
= (long) m_clrAmbientBackColor
;
283 case DISPID_AMBIENT_LOCALEID
:
284 pVarResult
->vt
= VT_I4
;
285 pVarResult
->lVal
= (long) m_nAmbientLocale
;
288 case DISPID_AMBIENT_USERMODE
:
289 pVarResult
->vt
= VT_BOOL
;
290 pVarResult
->boolVal
= m_window
->m_bAmbientUserMode
;
293 case DISPID_AMBIENT_SHOWGRABHANDLES
:
294 pVarResult
->vt
= VT_BOOL
;
295 pVarResult
->boolVal
= m_bAmbientShowGrabHandles
;
298 case DISPID_AMBIENT_SHOWHATCHING
:
299 pVarResult
->vt
= VT_BOOL
;
300 pVarResult
->boolVal
= m_bAmbientShowHatching
;
304 return DISP_E_MEMBERNOTFOUND
;
310 //**************************IOleWindow***************************
311 HRESULT STDMETHODCALLTYPE
GetWindow(HWND
* phwnd
)
315 (*phwnd
) = m_hWndParent
;
318 HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL
)
320 //**************************IOleInPlaceUIWindow*****************
321 HRESULT STDMETHODCALLTYPE
GetBorder(LPRECT lprectBorder
)
323 if (lprectBorder
== NULL
)
325 return INPLACE_E_NOTOOLSPACE
;
327 HRESULT STDMETHODCALLTYPE
RequestBorderSpace(LPCBORDERWIDTHS pborderwidths
)
329 if (pborderwidths
== NULL
)
331 return INPLACE_E_NOTOOLSPACE
;
333 HRESULT STDMETHODCALLTYPE
SetBorderSpace(LPCBORDERWIDTHS
)
335 HRESULT STDMETHODCALLTYPE
SetActiveObject(
336 IOleInPlaceActiveObject
*pActiveObject
, LPCOLESTR
)
339 pActiveObject
->AddRef();
341 m_window
->m_oleInPlaceActiveObject
= pActiveObject
;
345 //********************IOleInPlaceFrame************************
347 STDMETHOD(InsertMenus
)(HMENU
, LPOLEMENUGROUPWIDTHS
){return S_OK
;}
348 STDMETHOD(SetMenu
)(HMENU
, HOLEMENU
, HWND
){ return S_OK
;}
349 STDMETHOD(RemoveMenus
)(HMENU
){return S_OK
;}
350 STDMETHOD(SetStatusText
)(LPCOLESTR
){ return S_OK
;}
351 HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL
){return S_OK
;}
352 HRESULT STDMETHODCALLTYPE
TranslateAccelerator(LPMSG lpmsg
, WORD
)
354 // TODO: send an event with this id
355 if (m_window
->m_oleInPlaceActiveObject
.Ok())
356 m_window
->m_oleInPlaceActiveObject
->TranslateAccelerator(lpmsg
);
360 //*******************IOleInPlaceSite**************************
361 HRESULT STDMETHODCALLTYPE
CanInPlaceActivate(){return S_OK
;}
362 HRESULT STDMETHODCALLTYPE
OnInPlaceActivate()
363 { m_bInPlaceActive
= true; return S_OK
; }
364 HRESULT STDMETHODCALLTYPE
OnUIActivate()
365 { m_bUIActive
= true; return S_OK
; }
366 HRESULT STDMETHODCALLTYPE
GetWindowContext(IOleInPlaceFrame
**ppFrame
,
367 IOleInPlaceUIWindow
**ppDoc
,
370 LPOLEINPLACEFRAMEINFO lpFrameInfo
)
372 if (ppFrame
== NULL
|| ppDoc
== NULL
|| lprcPosRect
== NULL
||
373 lprcClipRect
== NULL
|| lpFrameInfo
== NULL
)
382 HRESULT hr
= QueryInterface(IID_IOleInPlaceFrame
, (void **) ppFrame
);
388 hr
= QueryInterface(IID_IOleInPlaceUIWindow
, (void **) ppDoc
);
391 (*ppFrame
)->Release();
397 ::GetClientRect(m_hWndParent
, &rect
);
400 lprcPosRect
->left
= lprcPosRect
->top
= 0;
401 lprcPosRect
->right
= rect
.right
;
402 lprcPosRect
->bottom
= rect
.bottom
;
406 lprcClipRect
->left
= lprcClipRect
->top
= 0;
407 lprcClipRect
->right
= rect
.right
;
408 lprcClipRect
->bottom
= rect
.bottom
;
411 memset(lpFrameInfo
, 0, sizeof(OLEINPLACEFRAMEINFO
));
412 lpFrameInfo
->cb
= sizeof(OLEINPLACEFRAMEINFO
);
413 lpFrameInfo
->hwndFrame
= m_hWndParent
;
417 HRESULT STDMETHODCALLTYPE
Scroll(SIZE
){return S_OK
;}
418 HRESULT STDMETHODCALLTYPE
OnUIDeactivate(BOOL
)
419 { m_bUIActive
= false; return S_OK
; }
420 HRESULT STDMETHODCALLTYPE
OnInPlaceDeactivate()
421 { m_bInPlaceActive
= false; return S_OK
; }
422 HRESULT STDMETHODCALLTYPE
DiscardUndoState(){return S_OK
;}
423 HRESULT STDMETHODCALLTYPE
DeactivateAndUndo(){return S_OK
; }
424 HRESULT STDMETHODCALLTYPE
OnPosRectChange(LPCRECT lprcPosRect
)
426 if (m_window
->m_oleInPlaceObject
.Ok() && lprcPosRect
)
429 // Result of several hours and days of bug hunting -
430 // this is called by an object when it wants to resize
431 // itself to something different then our parent window -
434 // m_window->m_oleInPlaceObject->SetObjectRects(
435 // lprcPosRect, lprcPosRect);
437 ::GetClientRect(m_hWndParent
, &rcClient
);
438 m_window
->m_oleInPlaceObject
->SetObjectRects(
439 &rcClient
, &rcClient
);
443 //*************************IOleInPlaceSiteEx***********************
444 HRESULT STDMETHODCALLTYPE
OnInPlaceActivateEx(BOOL
* pfNoRedraw
, DWORD
)
447 IRunnableObject
* runnable
= NULL
;
448 HRESULT hr
= QueryInterface(
449 IID_IRunnableObject
, (void**)(& runnable
));
452 runnable
->LockRunning(TRUE
, FALSE
);
455 OleLockRunning(m_window
->m_ActiveX
, TRUE
, FALSE
);
458 (*pfNoRedraw
) = FALSE
;
462 HRESULT STDMETHODCALLTYPE
OnInPlaceDeactivateEx(BOOL
)
465 IRunnableObject
* runnable
= NULL
;
466 HRESULT hr
= QueryInterface(
467 IID_IRunnableObject
, (void**)(& runnable
));
470 runnable
->LockRunning(FALSE
, FALSE
);
473 OleLockRunning(m_window
->m_ActiveX
, FALSE
, FALSE
);
477 STDMETHOD(RequestUIActivate
)(){ return S_OK
;}
478 //*************************IOleClientSite**************************
479 HRESULT STDMETHODCALLTYPE
SaveObject(){return S_OK
;}
480 const char *OleGetMonikerToStr(DWORD dwAssign
)
484 case OLEGETMONIKER_ONLYIFTHERE
: return "OLEGETMONIKER_ONLYIFTHERE";
485 case OLEGETMONIKER_FORCEASSIGN
: return "OLEGETMONIKER_FORCEASSIGN";
486 case OLEGETMONIKER_UNASSIGN
: return "OLEGETMONIKER_UNASSIGN";
487 case OLEGETMONIKER_TEMPFORUSER
: return "OLEGETMONIKER_TEMPFORUSER";
488 default : return "Bad Enum";
492 const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker
)
494 switch(dwWhichMoniker
)
496 case OLEWHICHMK_CONTAINER
: return "OLEWHICHMK_CONTAINER";
497 case OLEWHICHMK_OBJREL
: return "OLEWHICHMK_OBJREL";
498 case OLEWHICHMK_OBJFULL
: return "OLEWHICHMK_OBJFULL";
499 default : return "Bad Enum";
502 STDMETHOD(GetMoniker
)(DWORD
, DWORD
, IMoniker
**){return E_FAIL
;}
503 HRESULT STDMETHODCALLTYPE
GetContainer(LPOLECONTAINER
* ppContainer
)
505 if (ppContainer
== NULL
)
507 HRESULT hr
= QueryInterface(
508 IID_IOleContainer
, (void**)(ppContainer
));
509 wxASSERT(SUCCEEDED(hr
));
512 HRESULT STDMETHODCALLTYPE
ShowObject()
514 if (m_window
->m_oleObjectHWND
)
515 ::ShowWindow(m_window
->m_oleObjectHWND
, SW_SHOW
);
518 STDMETHOD(OnShowWindow
)(BOOL
){return S_OK
;}
519 STDMETHOD(RequestNewObjectLayout
)(){return E_NOTIMPL
;}
520 //********************IParseDisplayName***************************
521 HRESULT STDMETHODCALLTYPE
ParseDisplayName(
522 IBindCtx
*, LPOLESTR
, ULONG
*, IMoniker
**){return E_NOTIMPL
;}
523 //********************IOleContainer*******************************
524 STDMETHOD(EnumObjects
)(DWORD
, IEnumUnknown
**){return E_NOTIMPL
;}
525 HRESULT STDMETHODCALLTYPE
LockContainer(BOOL
){return S_OK
;}
526 //********************IOleItemContainer***************************
527 HRESULT STDMETHODCALLTYPE
528 #if 0 // defined(__WXWINCE__) && __VISUALC__ < 1400
530 #elif defined(_UNICODE)
535 (LPOLESTR pszItem
, DWORD
, IBindCtx
*, REFIID
, void ** ppvObject
)
537 if (pszItem
== NULL
|| ppvObject
== NULL
)
540 return MK_E_NOOBJECT
;
542 HRESULT STDMETHODCALLTYPE
GetObjectStorage(
543 LPOLESTR pszItem
, IBindCtx
* , REFIID
, void ** ppvStorage
)
545 if (pszItem
== NULL
|| ppvStorage
== NULL
)
548 return MK_E_NOOBJECT
;
550 HRESULT STDMETHODCALLTYPE
IsRunning(LPOLESTR pszItem
)
554 return MK_E_NOOBJECT
;
556 //***********************IOleControlSite*****************************
557 HRESULT STDMETHODCALLTYPE
OnControlInfoChanged()
559 HRESULT STDMETHODCALLTYPE
LockInPlaceActive(BOOL fLock
)
561 m_bInPlaceLocked
= (fLock
) ? true : false;
564 HRESULT STDMETHODCALLTYPE
GetExtendedControl(IDispatch
**)
566 HRESULT STDMETHODCALLTYPE
TransformCoords(
567 POINTL
* pPtlHimetric
, POINTF
* pPtfContainer
, DWORD
)
569 if (pPtlHimetric
== NULL
|| pPtfContainer
== NULL
)
573 HRESULT STDMETHODCALLTYPE
TranslateAccelerator(LPMSG
, DWORD
)
575 HRESULT STDMETHODCALLTYPE
OnFocus(BOOL
){return S_OK
;}
576 HRESULT STDMETHODCALLTYPE
ShowPropertyFrame(){return E_NOTIMPL
;}
577 //**************************IOleCommandTarget***********************
578 HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*, ULONG cCmds
,
579 OLECMD prgCmds
[], OLECMDTEXT
*)
581 if (prgCmds
== NULL
) return E_INVALIDARG
;
582 for (ULONG nCmd
= 0; nCmd
< cCmds
; nCmd
++)
584 // unsupported by default
585 prgCmds
[nCmd
].cmdf
= 0;
587 return OLECMDERR_E_UNKNOWNGROUP
;
590 HRESULT STDMETHODCALLTYPE
Exec(const GUID
*, DWORD
,
591 DWORD
, VARIANTARG
*, VARIANTARG
*)
592 {return OLECMDERR_E_NOTSUPPORTED
;}
594 //**********************IAdviseSink************************************
595 void STDMETHODCALLTYPE
OnDataChange(FORMATETC
*, STGMEDIUM
*) {}
596 void STDMETHODCALLTYPE
OnViewChange(DWORD
, LONG
) {}
597 void STDMETHODCALLTYPE
OnRename(IMoniker
*){}
598 void STDMETHODCALLTYPE
OnSave(){}
599 void STDMETHODCALLTYPE
OnClose(){}
601 //**********************IOleDocumentSite***************************
602 HRESULT STDMETHODCALLTYPE
ActivateMe(
603 IOleDocumentView __RPC_FAR
*pViewToActivate
)
605 wxAutoIOleInPlaceSite
inPlaceSite(
606 IID_IOleInPlaceSite
, (IDispatch
*) this);
607 if (!inPlaceSite
.Ok())
612 m_window
->m_docView
= pViewToActivate
;
613 m_window
->m_docView
->SetInPlaceSite(inPlaceSite
);
617 wxAutoIOleDocument
oleDoc(
618 IID_IOleDocument
, m_window
->m_oleObject
);
622 HRESULT hr
= oleDoc
->CreateView(inPlaceSite
, NULL
,
623 0, m_window
->m_docView
.GetRef());
627 m_window
->m_docView
->SetInPlaceSite(inPlaceSite
);
630 m_window
->m_docView
->UIActivate(TRUE
);
636 wxActiveXContainer
* m_window
;
641 bool m_bSupportsWindowlessActivation
;
642 bool m_bInPlaceLocked
;
643 bool m_bInPlaceActive
;
647 LCID m_nAmbientLocale
;
648 COLORREF m_clrAmbientForeColor
;
649 COLORREF m_clrAmbientBackColor
;
650 bool m_bAmbientShowHatching
;
651 bool m_bAmbientShowGrabHandles
;
652 bool m_bAmbientAppearance
;
655 DEFINE_OLE_TABLE(FrameSite
)
656 OLE_INTERFACE(IID_IUnknown
, IOleClientSite
)
657 OLE_IINTERFACE(IOleClientSite
)
658 OLE_INTERFACE(IID_IOleWindow
, IOleInPlaceSite
)
659 OLE_IINTERFACE(IOleInPlaceSite
)
660 OLE_IINTERFACE(IOleInPlaceSiteEx
)
661 OLE_IINTERFACE(IOleInPlaceUIWindow
)
662 OLE_IINTERFACE(IOleInPlaceFrame
)
663 OLE_IINTERFACE(IParseDisplayName
)
664 OLE_IINTERFACE(IOleContainer
)
665 OLE_IINTERFACE(IOleItemContainer
)
666 OLE_IINTERFACE(IDispatch
)
667 OLE_IINTERFACE(IOleCommandTarget
)
668 OLE_IINTERFACE(IOleDocumentSite
)
669 OLE_IINTERFACE(IAdviseSink
)
670 OLE_IINTERFACE(IOleControlSite
)
674 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
678 // Handles and sends activex events received from the ActiveX control
679 // to the appropriate wxEvtHandler
681 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
682 class wxActiveXEvents
: public IDispatch
685 DECLARE_OLE_UNKNOWN(wxActiveXEvents
);
688 wxActiveXContainer
*m_activeX
;
692 friend bool wxActiveXEventsInterface(wxActiveXEvents
*self
, REFIID iid
, void **_interface
, const char *&desc
);
695 wxActiveXEvents(wxActiveXContainer
*ax
) : m_activeX(ax
), m_haveCustomId(false) {}
696 wxActiveXEvents(wxActiveXContainer
*ax
, REFIID iid
) : m_activeX(ax
), m_customId(iid
), m_haveCustomId(true) {}
697 virtual ~wxActiveXEvents()
702 STDMETHODIMP
GetIDsOfNames(REFIID
, OLECHAR
**, unsigned int, LCID
, DISPID
*)
707 STDMETHODIMP
GetTypeInfo(unsigned int, LCID
, ITypeInfo
**)
712 STDMETHODIMP
GetTypeInfoCount(unsigned int*)
718 STDMETHODIMP
Invoke(DISPID dispIdMember
, REFIID
WXUNUSED(riid
),
720 WORD wFlags
, DISPPARAMS
* pDispParams
,
721 VARIANT
* WXUNUSED(pVarResult
), EXCEPINFO
* WXUNUSED(pExcepInfo
),
722 unsigned int * WXUNUSED(puArgErr
))
724 if (wFlags
& (DISPATCH_PROPERTYGET
| DISPATCH_PROPERTYPUT
| DISPATCH_PROPERTYPUTREF
))
732 wxActiveXEvent event
;
733 event
.SetEventType(wxEVT_ACTIVEX
);
734 event
.m_params
.NullList();
735 event
.m_dispid
= dispIdMember
;
740 for (DWORD i
= pDispParams
->cArgs
; i
> 0; i
--)
742 VARIANTARG
& va
= pDispParams
->rgvarg
[i
-1];
745 // vx.SetName(px.name);
746 wxConvertOleToVariant(va
, vx
);
747 event
.m_params
.Append(vx
);
751 // process the events from the activex method
752 m_activeX
->ProcessEvent(event
);
753 for (DWORD i
= 0; i
< pDispParams
->cArgs
; i
++)
755 VARIANTARG
& va
= pDispParams
->rgvarg
[i
];
757 event
.m_params
[pDispParams
->cArgs
- i
- 1];
758 wxConvertVariantToOle(vx
, va
);
761 if(event
.GetSkipped())
762 return DISP_E_MEMBERNOTFOUND
;
768 bool wxActiveXEventsInterface(wxActiveXEvents
*self
, REFIID iid
, void **_interface
, const char *&desc
)
770 if (self
->m_haveCustomId
&& IsEqualIID(iid
, self
->m_customId
))
772 // WXOLE_TRACE("Found Custom Dispatch Interface");
773 *_interface
= (IUnknown
*) (IDispatch
*) self
;
774 desc
= "Custom Dispatch Interface";
781 DEFINE_OLE_TABLE(wxActiveXEvents
)
782 OLE_IINTERFACE(IUnknown
)
783 OLE_INTERFACE(IID_IDispatch
, IDispatch
)
784 OLE_INTERFACE_CUSTOM(wxActiveXEventsInterface
)
787 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
789 // wxActiveXContainer
791 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
793 //---------------------------------------------------------------------------
794 // wxActiveXContainer Constructor
796 // Initializes members and creates the native ActiveX container
797 //---------------------------------------------------------------------------
798 wxActiveXContainer::wxActiveXContainer(wxWindow
* parent
,
799 REFIID iid
, IUnknown
* pUnk
)
800 : m_realparent(parent
)
802 m_bAmbientUserMode
= true;
803 m_docAdviseCookie
= 0;
804 CreateActiveX(iid
, pUnk
);
807 //---------------------------------------------------------------------------
808 // wxActiveXContainer Destructor
810 // Destroys members (the FrameSite et al. are destroyed implicitly
811 // through COM ref counting)
812 //---------------------------------------------------------------------------
813 wxActiveXContainer::~wxActiveXContainer()
815 // disconnect connection points
816 if (m_oleInPlaceObject
.Ok())
818 m_oleInPlaceObject
->InPlaceDeactivate();
819 m_oleInPlaceObject
->UIDeactivate();
822 if (m_oleObject
.Ok())
824 if (m_docAdviseCookie
!= 0)
825 m_oleObject
->Unadvise(m_docAdviseCookie
);
828 OLEIVERB_HIDE
, NULL
, m_clientSite
, 0, (HWND
) GetHWND(), NULL
);
829 m_oleObject
->Close(OLECLOSE_NOSAVE
);
830 m_oleObject
->SetClientSite(NULL
);
834 //---------------------------------------------------------------------------
835 // wxActiveXContainer::CreateActiveX
837 // Actually creates the ActiveX container through the FrameSite
838 // and sets up ActiveX events
840 // TODO: Document this more
841 //---------------------------------------------------------------------------
842 void wxActiveXContainer::CreateActiveX(REFIID iid
, IUnknown
* pUnk
)
845 hret
= m_ActiveX
.QueryInterface(iid
, pUnk
);
846 wxASSERT(SUCCEEDED(hret
));
849 FrameSite
*frame
= new FrameSite(m_realparent
, this);
851 hret
= m_clientSite
.QueryInterface(
852 IID_IOleClientSite
, (IDispatch
*) frame
);
853 wxASSERT(SUCCEEDED(hret
));
855 wxAutoIAdviseSink
adviseSink(IID_IAdviseSink
, (IDispatch
*) frame
);
856 wxASSERT(adviseSink
.Ok());
858 // Get Dispatch interface
859 hret
= m_Dispatch
.QueryInterface(IID_IDispatch
, m_ActiveX
);
862 // SETUP TYPEINFO AND ACTIVEX EVENTS
865 // get type info via class info
866 wxAutoIProvideClassInfo
classInfo(IID_IProvideClassInfo
, m_ActiveX
);
867 wxASSERT(classInfo
.Ok());
870 wxAutoITypeInfo typeInfo
;
871 hret
= classInfo
->GetClassInfo(typeInfo
.GetRef());
872 wxASSERT(typeInfo
.Ok());
876 hret
= typeInfo
->GetTypeAttr(&ta
);
879 // this should be a TKIND_COCLASS
880 wxASSERT(ta
->typekind
== TKIND_COCLASS
);
882 // iterate contained interfaces
883 for (int i
= 0; i
< ta
->cImplTypes
; i
++)
887 // get dispatch type info handle
888 hret
= typeInfo
->GetRefTypeOfImplType(i
, &rt
);
889 if (! SUCCEEDED(hret
))
892 // get dispatch type info interface
894 hret
= typeInfo
->GetRefTypeInfo(rt
, ti
.GetRef());
898 // check if default event sink
899 bool defInterface
= false;
900 bool defEventSink
= false;
901 int impTypeFlags
= 0;
902 typeInfo
->GetImplTypeFlags(i
, &impTypeFlags
);
904 if (impTypeFlags
& IMPLTYPEFLAG_FDEFAULT
)
906 if (impTypeFlags
& IMPLTYPEFLAG_FSOURCE
)
908 // WXOLE_TRACEOUT("Default Event Sink");
910 if (impTypeFlags
& IMPLTYPEFLAG_FDEFAULTVTABLE
)
912 // WXOLE_TRACEOUT("*ERROR* - Default Event Sink is via vTable");
913 defEventSink
= false;
914 wxFAIL_MSG(wxT("Default event sink is in vtable!"));
919 // WXOLE_TRACEOUT("Default Interface");
925 // wxAutoOleInterface<> assumes a ref has already been added
928 hret
= ti
->GetTypeAttr(&ta
);
931 if (ta
->typekind
== TKIND_DISPATCH
)
933 // WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
936 wxAutoIConnectionPoint cp
;
937 DWORD adviseCookie
= 0;
939 wxAutoIConnectionPointContainer
cpContainer(IID_IConnectionPointContainer
, m_ActiveX
);
940 wxASSERT( cpContainer
.Ok());
943 cpContainer
->FindConnectionPoint(ta
->guid
, cp
.GetRef());
944 wxASSERT ( SUCCEEDED(hret
));
947 frame
->QueryInterface(IID_IDispatch
, (void**)&disp
);
948 hret
= cp
->Advise(new wxActiveXEvents(this, ta
->guid
),
950 wxASSERT_MSG( SUCCEEDED(hret
),
951 wxString::Format(wxT("Cannot connect!\nHRESULT:%X"), (unsigned int)hret
)
956 ti
->ReleaseTypeAttr(ta
);
960 typeInfo
->ReleaseTypeAttr(ta
);
966 // Get IOleObject interface
967 hret
= m_oleObject
.QueryInterface(IID_IOleObject
, m_ActiveX
);
968 wxASSERT(SUCCEEDED(hret
));
970 // get IViewObject Interface
971 hret
= m_viewObject
.QueryInterface(IID_IViewObject
, m_ActiveX
);
972 wxASSERT(SUCCEEDED(hret
));
975 m_docAdviseCookie
= 0;
976 hret
= m_oleObject
->Advise(adviseSink
, &m_docAdviseCookie
);
978 // hret = m_viewObject->SetAdvise(DVASPECT_CONTENT, 0, adviseSink);
979 m_oleObject
->SetHostNames(L
"wxActiveXContainer", NULL
);
980 OleSetContainedObject(m_oleObject
, TRUE
);
984 // Get IOleInPlaceObject interface
985 hret
= m_oleInPlaceObject
.QueryInterface(
986 IID_IOleInPlaceObject
, m_ActiveX
);
987 wxASSERT(SUCCEEDED(hret
));
991 m_oleObject
->GetMiscStatus(DVASPECT_CONTENT
, &dwMiscStatus
);
992 wxASSERT(SUCCEEDED(hret
));
994 // set client site first ?
995 if (dwMiscStatus
& OLEMISC_SETCLIENTSITEFIRST
)
996 m_oleObject
->SetClientSite(m_clientSite
);
1000 wxAutoIPersistStreamInit
1001 pPersistStreamInit(IID_IPersistStreamInit
, m_oleObject
);
1003 if (pPersistStreamInit
.Ok())
1005 hret
= pPersistStreamInit
->InitNew();
1008 if (! (dwMiscStatus
& OLEMISC_SETCLIENTSITEFIRST
))
1009 m_oleObject
->SetClientSite(m_clientSite
);
1013 ::GetClientRect((HWND
)m_realparent
->GetHWND(), &posRect
);
1015 m_oleObjectHWND
= 0;
1017 if (m_oleInPlaceObject
.Ok())
1019 hret
= m_oleInPlaceObject
->GetWindow(&m_oleObjectHWND
);
1020 if (SUCCEEDED(hret
))
1021 ::SetActiveWindow(m_oleObjectHWND
);
1025 if (! (dwMiscStatus
& OLEMISC_INVISIBLEATRUNTIME
))
1027 if (posRect
.right
> 0 && posRect
.bottom
> 0 &&
1028 m_oleInPlaceObject
.Ok())
1029 m_oleInPlaceObject
->SetObjectRects(&posRect
, &posRect
);
1031 hret
= m_oleObject
->DoVerb(OLEIVERB_INPLACEACTIVATE
, NULL
,
1032 m_clientSite
, 0, (HWND
)m_realparent
->GetHWND(), &posRect
);
1033 hret
= m_oleObject
->DoVerb(OLEIVERB_SHOW
, 0, m_clientSite
, 0,
1034 (HWND
)m_realparent
->GetHWND(), &posRect
);
1037 if (! m_oleObjectHWND
&& m_oleInPlaceObject
.Ok())
1039 hret
= m_oleInPlaceObject
->GetWindow(&m_oleObjectHWND
);
1042 if (m_oleObjectHWND
)
1044 ::SetActiveWindow(m_oleObjectHWND
);
1045 ::ShowWindow(m_oleObjectHWND
, SW_SHOW
);
1047 this->AssociateHandle(m_oleObjectHWND
);
1048 this->Reparent(m_realparent
);
1050 wxWindow
* pWnd
= m_realparent
;
1051 int id
= m_realparent
->GetId();
1053 pWnd
->Connect(id
, wxEVT_SIZE
,
1054 wxSizeEventHandler(wxActiveXContainer::OnSize
), 0, this);
1055 // this->Connect(GetId(), wxEVT_PAINT,
1056 // wxPaintEventHandler(wxActiveXContainer::OnPaint), 0, this);
1057 pWnd
->Connect(id
, wxEVT_SET_FOCUS
,
1058 wxFocusEventHandler(wxActiveXContainer::OnSetFocus
), 0, this);
1059 pWnd
->Connect(id
, wxEVT_KILL_FOCUS
,
1060 wxFocusEventHandler(wxActiveXContainer::OnKillFocus
), 0, this);
1064 //---------------------------------------------------------------------------
1065 // wxActiveXContainer::OnSize
1067 // Called when the parent is resized - we need to do this to actually
1068 // move the ActiveX control to where the parent is
1069 //---------------------------------------------------------------------------
1070 void wxActiveXContainer::OnSize(wxSizeEvent
& event
)
1073 GetParent()->GetClientSize(&w
, &h
);
1081 if (w
<= 0 && h
<= 0)
1084 // extents are in HIMETRIC units
1085 if (m_oleObject
.Ok())
1087 m_oleObject
->DoVerb(OLEIVERB_HIDE
, 0, m_clientSite
, 0,
1088 (HWND
)m_realparent
->GetHWND(), &posRect
);
1091 PixelsToHimetric(sz
);
1095 m_oleObject
->GetExtent(DVASPECT_CONTENT
, &sz2
);
1096 if (sz2
.cx
!= sz
.cx
|| sz
.cy
!= sz2
.cy
)
1097 m_oleObject
->SetExtent(DVASPECT_CONTENT
, &sz
);
1099 m_oleObject
->DoVerb(OLEIVERB_SHOW
, 0, m_clientSite
, 0,
1100 (HWND
)m_realparent
->GetHWND(), &posRect
);
1103 if (m_oleInPlaceObject
.Ok())
1104 m_oleInPlaceObject
->SetObjectRects(&posRect
, &posRect
);
1109 //---------------------------------------------------------------------------
1110 // wxActiveXContainer::OnPaint
1112 // Called when the parent is resized - repaints the ActiveX control
1113 //---------------------------------------------------------------------------
1114 void wxActiveXContainer::OnPaint(wxPaintEvent
& WXUNUSED(event
))
1117 // Draw only when control is windowless or deactivated
1121 GetParent()->GetSize(&w
, &h
);
1128 #if !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
1129 ::RedrawWindow(m_oleObjectHWND
, NULL
, NULL
, RDW_INTERNALPAINT
);
1131 ::InvalidateRect(m_oleObjectHWND
, NULL
, false);
1133 RECTL
*prcBounds
= (RECTL
*) &posRect
;
1134 m_viewObject
->Draw(DVASPECT_CONTENT
, -1, NULL
, NULL
, NULL
,
1135 (HDC
)dc
.GetHDC(), prcBounds
, NULL
, NULL
, 0);
1139 //---------------------------------------------------------------------------
1140 // wxActiveXContainer::OnSetFocus
1142 // Called when the focus is set on the parent - activates the activex control
1143 //---------------------------------------------------------------------------
1144 void wxActiveXContainer::OnSetFocus(wxFocusEvent
& event
)
1146 if (m_oleInPlaceActiveObject
.Ok())
1147 m_oleInPlaceActiveObject
->OnFrameWindowActivate(TRUE
);
1152 //---------------------------------------------------------------------------
1153 // wxActiveXContainer::OnKillFocus
1155 // Called when the focus is killed on the parent -
1156 // deactivates the activex control
1157 //---------------------------------------------------------------------------
1158 void wxActiveXContainer::OnKillFocus(wxFocusEvent
& event
)
1160 if (m_oleInPlaceActiveObject
.Ok())
1161 m_oleInPlaceActiveObject
->OnFrameWindowActivate(FALSE
);