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" 
  29     #include "wx/dcclient.h" 
  33 #include "wx/msw/ole/activex.h" 
  34 // autointerfaces that we only use here 
  35 WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite
, IOleInPlaceSite
) 
  36 WX_DECLARE_AUTOOLE(wxAutoIOleDocument
, IOleDocument
) 
  37 WX_DECLARE_AUTOOLE(wxAutoIPersistStreamInit
, IPersistStreamInit
) 
  38 WX_DECLARE_AUTOOLE(wxAutoIAdviseSink
, IAdviseSink
) 
  39 WX_DECLARE_AUTOOLE(wxAutoIProvideClassInfo
, IProvideClassInfo
) 
  40 WX_DECLARE_AUTOOLE(wxAutoITypeInfo
, ITypeInfo
) 
  41 WX_DECLARE_AUTOOLE(wxAutoIConnectionPoint
, IConnectionPoint
) 
  42 WX_DECLARE_AUTOOLE(wxAutoIConnectionPointContainer
, IConnectionPointContainer
) 
  44 DEFINE_EVENT_TYPE(wxEVT_ACTIVEX
) 
  46 // Ole class helpers (sort of MFC-like) from wxActiveX 
  47 #define DECLARE_OLE_UNKNOWN(cls)\ 
  53         TAutoInitInt() : l(0) {}\ 
  55     TAutoInitInt refCount, lockCount;\ 
  56     static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\ 
  59     HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\ 
  60     ULONG STDMETHODCALLTYPE AddRef();\ 
  61     ULONG STDMETHODCALLTYPE Release();\ 
  62     ULONG STDMETHODCALLTYPE AddLock();\ 
  63     ULONG STDMETHODCALLTYPE ReleaseLock() 
  65 #define DEFINE_OLE_TABLE(cls)\ 
  66     LONG cls::GetRefCount() {return refCount.l;}\ 
  67     HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\ 
  73         const char *desc = NULL;\ 
  74         cls::_GetInterface(this, iid, ppvObject, desc);\ 
  77             return E_NOINTERFACE;\ 
  79         ((IUnknown * )(*ppvObject))->AddRef();\ 
  82     ULONG STDMETHODCALLTYPE cls::AddRef()\ 
  84         InterlockedIncrement(&refCount.l);\ 
  87     ULONG STDMETHODCALLTYPE cls::Release()\ 
  91             InterlockedDecrement(&refCount.l);\ 
 102     ULONG STDMETHODCALLTYPE cls::AddLock()\ 
 104         InterlockedIncrement(&lockCount.l);\ 
 107     ULONG STDMETHODCALLTYPE cls::ReleaseLock()\ 
 109         if (lockCount.l > 0)\ 
 111             InterlockedDecrement(&lockCount.l);\ 
 119 #define DEFINE_OLE_BASE(cls)\ 
 120     void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\ 
 125 #define OLE_INTERFACE(_iid, _type)\ 
 126     if (IsEqualIID(iid, _iid))\ 
 128         *_interface = (IUnknown *) (_type *) self;\ 
 133 #define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face) 
 135 #define OLE_INTERFACE_CUSTOM(func)\ 
 136     if (func(self, iid, _interface, desc))\ 
 141 #define END_OLE_TABLE\ 
 144 // ============================================================================ 
 146 // ============================================================================ 
 148 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 151 // Utility to convert from pixels to the himetric values in some COM methods 
 152 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 155 #define HIMETRIC_PER_INCH   2540 
 156 #define MAP_PIX_TO_LOGHIM(x,ppli)   MulDiv(HIMETRIC_PER_INCH, (x), (ppli)) 
 158 static void PixelsToHimetric(SIZEL 
&sz
) 
 166         HDC dc 
= GetDC(NULL
); 
 167         logX 
= GetDeviceCaps(dc
, LOGPIXELSX
); 
 168         logY 
= GetDeviceCaps(dc
, LOGPIXELSY
); 
 172 #define HIMETRIC_INCH   2540 
 173 #define CONVERT(x, logpixels)   wxMulDivInt32(HIMETRIC_INCH, (x), (logpixels)) 
 175     sz
.cx 
= CONVERT(sz
.cx
, logX
); 
 176     sz
.cy 
= CONVERT(sz
.cy
, logY
); 
 183 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 187 // Handles the actual wxActiveX container implementation 
 189 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 191     public IOleClientSite
, 
 192     public IOleInPlaceSiteEx
, 
 193     public IOleInPlaceFrame
, 
 194     public IOleItemContainer
, 
 196     public IOleCommandTarget
, 
 197     public IOleDocumentSite
, 
 199     public IOleControlSite
 
 202     DECLARE_OLE_UNKNOWN(FrameSite
); 
 205     FrameSite(wxWindow 
* win
, wxActiveXContainer 
* win2
) 
 208         m_bSupportsWindowlessActivation 
= true; 
 209         m_bInPlaceLocked 
= false; 
 211         m_bInPlaceActive 
= false; 
 212         m_bWindowless 
= false; 
 214         m_nAmbientLocale 
= 0; 
 215         m_clrAmbientForeColor 
= ::GetSysColor(COLOR_WINDOWTEXT
); 
 216         m_clrAmbientBackColor 
= ::GetSysColor(COLOR_WINDOW
); 
 217         m_bAmbientShowHatching 
= true; 
 218         m_bAmbientShowGrabHandles 
= true; 
 219         m_bAmbientAppearance 
= true; 
 222         m_hWndParent 
= (HWND
)win
->GetHWND(); 
 224     virtual ~FrameSite(){} 
 225     //***************************IDispatch***************************** 
 226     HRESULT STDMETHODCALLTYPE 
GetIDsOfNames(REFIID
, OLECHAR 
** , 
 227                                             unsigned int , LCID 
, 
 229     {   return E_NOTIMPL
;   } 
 230     STDMETHOD(GetTypeInfo
)(unsigned int, LCID
, ITypeInfo 
**) 
 231     {   return E_NOTIMPL
;   } 
 232     HRESULT STDMETHODCALLTYPE 
GetTypeInfoCount(unsigned int *) 
 233     {   return E_NOTIMPL
;   } 
 234     HRESULT STDMETHODCALLTYPE 
Invoke(DISPID dispIdMember
, REFIID
, LCID
, 
 235                             WORD wFlags
, DISPPARAMS 
*, 
 236                             VARIANT 
* pVarResult
, EXCEPINFO 
*, 
 239         if (!(wFlags 
& DISPATCH_PROPERTYGET
)) 
 242         if (pVarResult 
== NULL
) 
 245         //The most common case is boolean, use as an initial type 
 246         V_VT(pVarResult
) = VT_BOOL
; 
 248         switch (dispIdMember
) 
 250             case DISPID_AMBIENT_MESSAGEREFLECT
: 
 251                 V_BOOL(pVarResult
)= FALSE
; 
 254             case DISPID_AMBIENT_DISPLAYASDEFAULT
: 
 255                 V_BOOL(pVarResult
)= TRUE
; 
 258             case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED
: 
 259                 V_BOOL(pVarResult
) = TRUE
; 
 262             case DISPID_AMBIENT_SILENT
: 
 263                 V_BOOL(pVarResult
)= TRUE
; 
 266             case DISPID_AMBIENT_APPEARANCE
: 
 267                 pVarResult
->vt 
= VT_BOOL
; 
 268                 pVarResult
->boolVal 
= m_bAmbientAppearance
; 
 271             case DISPID_AMBIENT_FORECOLOR
: 
 272                 pVarResult
->vt 
= VT_I4
; 
 273                 pVarResult
->lVal 
= (long) m_clrAmbientForeColor
; 
 276             case DISPID_AMBIENT_BACKCOLOR
: 
 277                 pVarResult
->vt 
= VT_I4
; 
 278                 pVarResult
->lVal 
= (long) m_clrAmbientBackColor
; 
 281             case DISPID_AMBIENT_LOCALEID
: 
 282                 pVarResult
->vt 
= VT_I4
; 
 283                 pVarResult
->lVal 
= (long) m_nAmbientLocale
; 
 286             case DISPID_AMBIENT_USERMODE
: 
 287                 pVarResult
->vt 
= VT_BOOL
; 
 288                 pVarResult
->boolVal 
= m_window
->m_bAmbientUserMode
; 
 291             case DISPID_AMBIENT_SHOWGRABHANDLES
: 
 292                 pVarResult
->vt 
= VT_BOOL
; 
 293                 pVarResult
->boolVal 
= m_bAmbientShowGrabHandles
; 
 296             case DISPID_AMBIENT_SHOWHATCHING
: 
 297                 pVarResult
->vt 
= VT_BOOL
; 
 298                 pVarResult
->boolVal 
= m_bAmbientShowHatching
; 
 302                 return DISP_E_MEMBERNOTFOUND
; 
 308     //**************************IOleWindow*************************** 
 309     HRESULT STDMETHODCALLTYPE 
GetWindow(HWND 
* phwnd
) 
 313         (*phwnd
) = m_hWndParent
; 
 316     HRESULT STDMETHODCALLTYPE 
ContextSensitiveHelp(BOOL
) 
 318     //**************************IOleInPlaceUIWindow***************** 
 319     HRESULT STDMETHODCALLTYPE 
GetBorder(LPRECT lprectBorder
) 
 321         if (lprectBorder 
== NULL
) 
 323         return INPLACE_E_NOTOOLSPACE
; 
 325     HRESULT STDMETHODCALLTYPE 
RequestBorderSpace(LPCBORDERWIDTHS pborderwidths
) 
 327         if (pborderwidths 
== NULL
) 
 329         return INPLACE_E_NOTOOLSPACE
; 
 331     HRESULT STDMETHODCALLTYPE 
SetBorderSpace(LPCBORDERWIDTHS
) 
 333     HRESULT STDMETHODCALLTYPE 
SetActiveObject( 
 334         IOleInPlaceActiveObject 
*pActiveObject
, LPCOLESTR
) 
 337             pActiveObject
->AddRef(); 
 339         m_window
->m_oleInPlaceActiveObject 
= pActiveObject
; 
 343     //********************IOleInPlaceFrame************************ 
 345     STDMETHOD(InsertMenus
)(HMENU
, LPOLEMENUGROUPWIDTHS
){return S_OK
;} 
 346     STDMETHOD(SetMenu
)(HMENU
, HOLEMENU
, HWND
){  return S_OK
;} 
 347     STDMETHOD(RemoveMenus
)(HMENU
){return S_OK
;} 
 348     STDMETHOD(SetStatusText
)(LPCOLESTR
){ return S_OK
;} 
 349     HRESULT STDMETHODCALLTYPE 
EnableModeless(BOOL
){return S_OK
;} 
 350     HRESULT STDMETHODCALLTYPE 
TranslateAccelerator(LPMSG lpmsg
, WORD
) 
 352         // TODO: send an event with this id 
 353         if (m_window
->m_oleInPlaceActiveObject
.Ok()) 
 354             m_window
->m_oleInPlaceActiveObject
->TranslateAccelerator(lpmsg
); 
 358     //*******************IOleInPlaceSite************************** 
 359     HRESULT STDMETHODCALLTYPE 
CanInPlaceActivate(){return S_OK
;} 
 360     HRESULT STDMETHODCALLTYPE 
OnInPlaceActivate() 
 361     {   m_bInPlaceActive 
= true;    return S_OK
;    } 
 362     HRESULT STDMETHODCALLTYPE 
OnUIActivate() 
 363     {   m_bUIActive 
= true;         return S_OK
;    } 
 364     HRESULT STDMETHODCALLTYPE 
GetWindowContext(IOleInPlaceFrame 
**ppFrame
, 
 365                                         IOleInPlaceUIWindow 
**ppDoc
, 
 368                                         LPOLEINPLACEFRAMEINFO lpFrameInfo
) 
 370         if (ppFrame 
== NULL 
|| ppDoc 
== NULL 
|| lprcPosRect 
== NULL 
|| 
 371             lprcClipRect 
== NULL 
|| lpFrameInfo 
== NULL
) 
 380         HRESULT hr 
= QueryInterface(IID_IOleInPlaceFrame
, (void **) ppFrame
); 
 386         hr 
= QueryInterface(IID_IOleInPlaceUIWindow
, (void **) ppDoc
); 
 389             (*ppFrame
)->Release(); 
 395         ::GetClientRect(m_hWndParent
, &rect
); 
 398             lprcPosRect
->left 
= lprcPosRect
->top 
= 0; 
 399             lprcPosRect
->right 
= rect
.right
; 
 400             lprcPosRect
->bottom 
= rect
.bottom
; 
 404             lprcClipRect
->left 
= lprcClipRect
->top 
= 0; 
 405             lprcClipRect
->right 
= rect
.right
; 
 406             lprcClipRect
->bottom 
= rect
.bottom
; 
 409         memset(lpFrameInfo
, 0, sizeof(OLEINPLACEFRAMEINFO
)); 
 410         lpFrameInfo
->cb 
= sizeof(OLEINPLACEFRAMEINFO
); 
 411         lpFrameInfo
->hwndFrame 
= m_hWndParent
; 
 415     HRESULT STDMETHODCALLTYPE 
Scroll(SIZE
){return S_OK
;} 
 416     HRESULT STDMETHODCALLTYPE 
OnUIDeactivate(BOOL
) 
 417     {   m_bUIActive 
= false;         return S_OK
;    } 
 418     HRESULT STDMETHODCALLTYPE 
OnInPlaceDeactivate() 
 419     {   m_bInPlaceActive 
= false;    return S_OK
;    } 
 420     HRESULT STDMETHODCALLTYPE 
DiscardUndoState(){return S_OK
;} 
 421     HRESULT STDMETHODCALLTYPE 
DeactivateAndUndo(){return S_OK
; } 
 422     HRESULT STDMETHODCALLTYPE 
OnPosRectChange(LPCRECT lprcPosRect
) 
 424         if (m_window
->m_oleInPlaceObject
.Ok() && lprcPosRect
) 
 427            // Result of several hours and days of bug hunting - 
 428            // this is called by an object when it wants to resize 
 429            // itself to something different then our parent window - 
 432 //            m_window->m_oleInPlaceObject->SetObjectRects( 
 433 //                lprcPosRect, lprcPosRect); 
 435            ::GetClientRect(m_hWndParent
, &rcClient
); 
 436             m_window
->m_oleInPlaceObject
->SetObjectRects( 
 437                 &rcClient
, &rcClient
); 
 441     //*************************IOleInPlaceSiteEx*********************** 
 442     HRESULT STDMETHODCALLTYPE 
OnInPlaceActivateEx(BOOL 
* pfNoRedraw
, DWORD
) 
 445         IRunnableObject
* runnable 
= NULL
; 
 446         HRESULT hr 
= QueryInterface( 
 447             IID_IRunnableObject
, (void**)(& runnable
)); 
 450             runnable
->LockRunning(TRUE
, FALSE
); 
 453         OleLockRunning(m_window
->m_ActiveX
, TRUE
, FALSE
); 
 456             (*pfNoRedraw
) = FALSE
; 
 460     HRESULT STDMETHODCALLTYPE 
OnInPlaceDeactivateEx(BOOL
) 
 463         IRunnableObject
* runnable 
= NULL
; 
 464         HRESULT hr 
= QueryInterface( 
 465             IID_IRunnableObject
, (void**)(& runnable
)); 
 468             runnable
->LockRunning(FALSE
, FALSE
); 
 471         OleLockRunning(m_window
->m_ActiveX
, FALSE
, FALSE
); 
 475     STDMETHOD(RequestUIActivate
)(){ return S_OK
;} 
 476     //*************************IOleClientSite************************** 
 477     HRESULT STDMETHODCALLTYPE 
SaveObject(){return S_OK
;} 
 478     const char *OleGetMonikerToStr(DWORD dwAssign
) 
 482         case OLEGETMONIKER_ONLYIFTHERE  
: return "OLEGETMONIKER_ONLYIFTHERE"; 
 483         case OLEGETMONIKER_FORCEASSIGN  
: return "OLEGETMONIKER_FORCEASSIGN"; 
 484         case OLEGETMONIKER_UNASSIGN     
: return "OLEGETMONIKER_UNASSIGN"; 
 485         case OLEGETMONIKER_TEMPFORUSER  
: return "OLEGETMONIKER_TEMPFORUSER"; 
 486         default                         : return "Bad Enum"; 
 490     const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker
) 
 492         switch(dwWhichMoniker
) 
 494         case OLEWHICHMK_CONTAINER   
: return "OLEWHICHMK_CONTAINER"; 
 495         case OLEWHICHMK_OBJREL      
: return "OLEWHICHMK_OBJREL"; 
 496         case OLEWHICHMK_OBJFULL     
: return "OLEWHICHMK_OBJFULL"; 
 497         default                     : return "Bad Enum"; 
 500     STDMETHOD(GetMoniker
)(DWORD
, DWORD
, IMoniker 
**){return E_FAIL
;} 
 501     HRESULT STDMETHODCALLTYPE 
GetContainer(LPOLECONTAINER 
* ppContainer
) 
 503         if (ppContainer 
== NULL
) 
 505         HRESULT hr 
= QueryInterface( 
 506             IID_IOleContainer
, (void**)(ppContainer
)); 
 507         wxASSERT(SUCCEEDED(hr
)); 
 510     HRESULT STDMETHODCALLTYPE 
ShowObject() 
 512         if (m_window
->m_oleObjectHWND
) 
 513             ::ShowWindow(m_window
->m_oleObjectHWND
, SW_SHOW
); 
 516     STDMETHOD(OnShowWindow
)(BOOL
){return S_OK
;} 
 517     STDMETHOD(RequestNewObjectLayout
)(){return E_NOTIMPL
;} 
 518     //********************IParseDisplayName*************************** 
 519     HRESULT STDMETHODCALLTYPE 
ParseDisplayName( 
 520         IBindCtx 
*, LPOLESTR
, ULONG 
*, IMoniker 
**){return E_NOTIMPL
;} 
 521     //********************IOleContainer******************************* 
 522     STDMETHOD(EnumObjects
)(DWORD
, IEnumUnknown 
**){return E_NOTIMPL
;} 
 523     HRESULT STDMETHODCALLTYPE 
LockContainer(BOOL
){return S_OK
;} 
 524     //********************IOleItemContainer*************************** 
 525     HRESULT STDMETHODCALLTYPE
 
 526     #if 0 // defined(__WXWINCE__) && __VISUALC__ < 1400 
 528     #elif defined(_UNICODE) 
 533     (LPOLESTR pszItem
, DWORD
, IBindCtx 
*, REFIID
, void ** ppvObject
) 
 535         if (pszItem 
== NULL 
|| ppvObject 
== NULL
) 
 538         return MK_E_NOOBJECT
; 
 540     HRESULT STDMETHODCALLTYPE 
GetObjectStorage( 
 541         LPOLESTR pszItem
, IBindCtx 
* , REFIID
, void ** ppvStorage
) 
 543         if (pszItem 
== NULL 
|| ppvStorage 
== NULL
) 
 546         return MK_E_NOOBJECT
; 
 548     HRESULT STDMETHODCALLTYPE 
IsRunning(LPOLESTR pszItem
) 
 552         return MK_E_NOOBJECT
; 
 554     //***********************IOleControlSite***************************** 
 555     HRESULT STDMETHODCALLTYPE 
OnControlInfoChanged() 
 557     HRESULT STDMETHODCALLTYPE 
LockInPlaceActive(BOOL fLock
) 
 559         m_bInPlaceLocked 
= (fLock
) ? true : false; 
 562     HRESULT STDMETHODCALLTYPE 
GetExtendedControl(IDispatch 
**) 
 564     HRESULT STDMETHODCALLTYPE 
TransformCoords( 
 565         POINTL 
* pPtlHimetric
, POINTF 
* pPtfContainer
, DWORD
) 
 567         if (pPtlHimetric 
== NULL 
|| pPtfContainer 
== NULL
) 
 571     HRESULT STDMETHODCALLTYPE 
TranslateAccelerator(LPMSG
, DWORD
) 
 573     HRESULT STDMETHODCALLTYPE 
OnFocus(BOOL
){return S_OK
;} 
 574     HRESULT STDMETHODCALLTYPE 
ShowPropertyFrame(){return E_NOTIMPL
;} 
 575     //**************************IOleCommandTarget*********************** 
 576     HRESULT STDMETHODCALLTYPE 
QueryStatus(const GUID 
*, ULONG cCmds
, 
 577                                 OLECMD prgCmds
[], OLECMDTEXT 
*) 
 579         if (prgCmds 
== NULL
) return E_INVALIDARG
; 
 580         for (ULONG nCmd 
= 0; nCmd 
< cCmds
; nCmd
++) 
 582             // unsupported by default 
 583             prgCmds
[nCmd
].cmdf 
= 0; 
 585         return OLECMDERR_E_UNKNOWNGROUP
; 
 588     HRESULT STDMETHODCALLTYPE 
Exec(const GUID 
*, DWORD
, 
 589                             DWORD
, VARIANTARG 
*, VARIANTARG 
*) 
 590     {return OLECMDERR_E_NOTSUPPORTED
;} 
 592     //**********************IAdviseSink************************************ 
 593     void STDMETHODCALLTYPE 
OnDataChange(FORMATETC 
*, STGMEDIUM 
*) {} 
 594     void STDMETHODCALLTYPE 
OnViewChange(DWORD
, LONG
) {} 
 595     void STDMETHODCALLTYPE 
OnRename(IMoniker 
*){} 
 596     void STDMETHODCALLTYPE 
OnSave(){} 
 597     void STDMETHODCALLTYPE 
OnClose(){} 
 599     //**********************IOleDocumentSite*************************** 
 600     HRESULT STDMETHODCALLTYPE 
ActivateMe( 
 601         IOleDocumentView __RPC_FAR 
*pViewToActivate
) 
 603         wxAutoIOleInPlaceSite 
inPlaceSite( 
 604             IID_IOleInPlaceSite
, (IDispatch 
*) this); 
 605         if (!inPlaceSite
.Ok()) 
 610             m_window
->m_docView 
= pViewToActivate
; 
 611             m_window
->m_docView
->SetInPlaceSite(inPlaceSite
); 
 615             wxAutoIOleDocument 
oleDoc( 
 616                 IID_IOleDocument
, m_window
->m_oleObject
); 
 620             HRESULT hr 
= oleDoc
->CreateView(inPlaceSite
, NULL
, 
 621                                     0, m_window
->m_docView
.GetRef()); 
 625             m_window
->m_docView
->SetInPlaceSite(inPlaceSite
); 
 628         m_window
->m_docView
->UIActivate(TRUE
); 
 634     wxActiveXContainer 
* m_window
; 
 639     bool m_bSupportsWindowlessActivation
; 
 640     bool m_bInPlaceLocked
; 
 641     bool m_bInPlaceActive
; 
 645     LCID m_nAmbientLocale
; 
 646     COLORREF m_clrAmbientForeColor
; 
 647     COLORREF m_clrAmbientBackColor
; 
 648     bool m_bAmbientShowHatching
; 
 649     bool m_bAmbientShowGrabHandles
; 
 650     bool m_bAmbientAppearance
; 
 653 DEFINE_OLE_TABLE(FrameSite
) 
 654     OLE_INTERFACE(IID_IUnknown
, IOleClientSite
) 
 655     OLE_IINTERFACE(IOleClientSite
) 
 656     OLE_INTERFACE(IID_IOleWindow
, IOleInPlaceSite
) 
 657     OLE_IINTERFACE(IOleInPlaceSite
) 
 658     OLE_IINTERFACE(IOleInPlaceSiteEx
) 
 659     OLE_IINTERFACE(IOleInPlaceUIWindow
) 
 660     OLE_IINTERFACE(IOleInPlaceFrame
) 
 661     OLE_IINTERFACE(IParseDisplayName
) 
 662     OLE_IINTERFACE(IOleContainer
) 
 663     OLE_IINTERFACE(IOleItemContainer
) 
 664     OLE_IINTERFACE(IDispatch
) 
 665     OLE_IINTERFACE(IOleCommandTarget
) 
 666     OLE_IINTERFACE(IOleDocumentSite
) 
 667     OLE_IINTERFACE(IAdviseSink
) 
 668     OLE_IINTERFACE(IOleControlSite
) 
 672 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 676 // Handles and sends activex events received from the ActiveX control 
 677 // to the appropriate wxEvtHandler 
 679 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 680 class wxActiveXEvents 
: public IDispatch
 
 683     DECLARE_OLE_UNKNOWN(wxActiveXEvents
); 
 686     wxActiveXContainer 
*m_activeX
; 
 690     friend bool wxActiveXEventsInterface(wxActiveXEvents 
*self
, REFIID iid
, void **_interface
, const char *&desc
); 
 693     wxActiveXEvents(wxActiveXContainer 
*ax
) : m_activeX(ax
), m_haveCustomId(false) {} 
 694     wxActiveXEvents(wxActiveXContainer 
*ax
, REFIID iid
) : m_activeX(ax
), m_customId(iid
), m_haveCustomId(true) {} 
 695     virtual ~wxActiveXEvents() 
 700     STDMETHODIMP 
GetIDsOfNames(REFIID
, OLECHAR
**, unsigned int, LCID
, DISPID
*) 
 705     STDMETHODIMP 
GetTypeInfo(unsigned int, LCID
, ITypeInfo
**) 
 710     STDMETHODIMP 
GetTypeInfoCount(unsigned int*) 
 716     STDMETHODIMP 
Invoke(DISPID dispIdMember
, REFIID 
WXUNUSED(riid
), 
 718                           WORD wFlags
, DISPPARAMS 
* pDispParams
, 
 719                           VARIANT 
* WXUNUSED(pVarResult
), EXCEPINFO 
* WXUNUSED(pExcepInfo
), 
 720                           unsigned int * WXUNUSED(puArgErr
)) 
 722         if (wFlags 
& (DISPATCH_PROPERTYGET 
| DISPATCH_PROPERTYPUT 
| DISPATCH_PROPERTYPUTREF
)) 
 730         wxActiveXEvent  event
; 
 731         event
.SetEventType(wxEVT_ACTIVEX
); 
 732         event
.m_params
.NullList(); 
 733         event
.m_dispid 
= dispIdMember
; 
 738             for (DWORD i 
= pDispParams
->cArgs
; i 
> 0; i
--) 
 740                 VARIANTARG
& va 
= pDispParams
->rgvarg
[i
-1]; 
 743 //                        vx.SetName(px.name); 
 744                 wxConvertOleToVariant(va
, vx
); 
 745                 event
.m_params
.Append(vx
); 
 749         // process the events from the activex method 
 750            m_activeX
->ProcessEvent(event
); 
 751         for (DWORD i 
= 0; i 
< pDispParams
->cArgs
; i
++) 
 753             VARIANTARG
& va 
= pDispParams
->rgvarg
[i
]; 
 755                 event
.m_params
[pDispParams
->cArgs 
- i 
- 1]; 
 756             wxConvertVariantToOle(vx
, va
); 
 759         if(event
.GetSkipped()) 
 760             return DISP_E_MEMBERNOTFOUND
; 
 766 bool wxActiveXEventsInterface(wxActiveXEvents 
*self
, REFIID iid
, void **_interface
, const char *&desc
) 
 768     if (self
->m_haveCustomId 
&& IsEqualIID(iid
, self
->m_customId
)) 
 770 //        WXOLE_TRACE("Found Custom Dispatch Interface"); 
 771         *_interface 
= (IUnknown 
*) (IDispatch 
*) self
; 
 772         desc 
= "Custom Dispatch Interface"; 
 779 DEFINE_OLE_TABLE(wxActiveXEvents
) 
 780     OLE_IINTERFACE(IUnknown
) 
 781     OLE_INTERFACE(IID_IDispatch
, IDispatch
) 
 782     OLE_INTERFACE_CUSTOM(wxActiveXEventsInterface
) 
 785 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 787 // wxActiveXContainer 
 789 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 791 //--------------------------------------------------------------------------- 
 792 // wxActiveXContainer Constructor 
 794 // Initializes members and creates the native ActiveX container 
 795 //--------------------------------------------------------------------------- 
 796 wxActiveXContainer::wxActiveXContainer(wxWindow 
* parent
, 
 797                                        REFIID iid
, IUnknown
* pUnk
) 
 798     : m_realparent(parent
) 
 800     m_bAmbientUserMode 
= true; 
 801     m_docAdviseCookie 
= 0; 
 802     CreateActiveX(iid
, pUnk
); 
 805 //--------------------------------------------------------------------------- 
 806 // wxActiveXContainer Destructor 
 808 // Destroys members (the FrameSite et al. are destroyed implicitly 
 809 // through COM ref counting) 
 810 //--------------------------------------------------------------------------- 
 811 wxActiveXContainer::~wxActiveXContainer() 
 813     // disconnect connection points 
 814     if (m_oleInPlaceObject
.Ok()) 
 816         m_oleInPlaceObject
->InPlaceDeactivate(); 
 817         m_oleInPlaceObject
->UIDeactivate(); 
 820     if (m_oleObject
.Ok()) 
 822         if (m_docAdviseCookie 
!= 0) 
 823             m_oleObject
->Unadvise(m_docAdviseCookie
); 
 826             OLEIVERB_HIDE
, NULL
, m_clientSite
, 0, (HWND
) GetHWND(), NULL
); 
 827         m_oleObject
->Close(OLECLOSE_NOSAVE
); 
 828         m_oleObject
->SetClientSite(NULL
); 
 832 //--------------------------------------------------------------------------- 
 833 // wxActiveXContainer::CreateActiveX 
 835 // Actually creates the ActiveX container through the FrameSite 
 836 // and sets up ActiveX events 
 838 // TODO: Document this more 
 839 //--------------------------------------------------------------------------- 
 840 void wxActiveXContainer::CreateActiveX(REFIID iid
, IUnknown
* pUnk
) 
 843     hret 
= m_ActiveX
.QueryInterface(iid
, pUnk
); 
 844     wxASSERT(SUCCEEDED(hret
)); 
 847     FrameSite 
*frame 
= new FrameSite(m_realparent
, this); 
 849     hret 
= m_clientSite
.QueryInterface( 
 850         IID_IOleClientSite
, (IDispatch 
*) frame
); 
 851     wxASSERT(SUCCEEDED(hret
)); 
 853     wxAutoIAdviseSink 
adviseSink(IID_IAdviseSink
, (IDispatch 
*) frame
); 
 854     wxASSERT(adviseSink
.Ok()); 
 856     // Get Dispatch interface 
 857     hret 
= m_Dispatch
.QueryInterface(IID_IDispatch
, m_ActiveX
); 
 860     // SETUP TYPEINFO AND ACTIVEX EVENTS 
 863     // get type info via class info 
 864     wxAutoIProvideClassInfo 
classInfo(IID_IProvideClassInfo
, m_ActiveX
); 
 865     wxASSERT(classInfo
.Ok()); 
 868     wxAutoITypeInfo typeInfo
; 
 869     hret 
= classInfo
->GetClassInfo(typeInfo
.GetRef()); 
 870     wxASSERT(typeInfo
.Ok()); 
 874     hret 
= typeInfo
->GetTypeAttr(&ta
); 
 877     // this should be a TKIND_COCLASS 
 878     wxASSERT(ta
->typekind 
== TKIND_COCLASS
); 
 880     // iterate contained interfaces 
 881     for (int i 
= 0; i 
< ta
->cImplTypes
; i
++) 
 885         // get dispatch type info handle 
 886         hret 
= typeInfo
->GetRefTypeOfImplType(i
, &rt
); 
 887         if (! SUCCEEDED(hret
)) 
 890         // get dispatch type info interface 
 892         hret 
= typeInfo
->GetRefTypeInfo(rt
, ti
.GetRef()); 
 896         // check if default event sink 
 897         bool defInterface 
= false; 
 898         bool defEventSink 
= false; 
 899         int impTypeFlags 
= 0; 
 900         typeInfo
->GetImplTypeFlags(i
, &impTypeFlags
); 
 902         if (impTypeFlags 
& IMPLTYPEFLAG_FDEFAULT
) 
 904             if (impTypeFlags 
& IMPLTYPEFLAG_FSOURCE
) 
 906                 // WXOLE_TRACEOUT("Default Event Sink"); 
 908                 if (impTypeFlags 
& IMPLTYPEFLAG_FDEFAULTVTABLE
) 
 910                     // WXOLE_TRACEOUT("*ERROR* - Default Event Sink is via vTable"); 
 911                     defEventSink 
= false; 
 912                     wxFAIL_MSG(wxT("Default event sink is in vtable!")); 
 917                 // WXOLE_TRACEOUT("Default Interface"); 
 923         // wxAutoOleInterface<> assumes a ref has already been added 
 926         hret 
= ti
->GetTypeAttr(&ta
); 
 929         if (ta
->typekind 
== TKIND_DISPATCH
) 
 931             // WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str()); 
 934                 wxAutoIConnectionPoint    cp
; 
 935                 DWORD                    adviseCookie 
= 0; 
 937                 wxAutoIConnectionPointContainer 
cpContainer(IID_IConnectionPointContainer
, m_ActiveX
); 
 938                 wxASSERT( cpContainer
.Ok()); 
 941                     cpContainer
->FindConnectionPoint(ta
->guid
, cp
.GetRef()); 
 942                 wxASSERT ( SUCCEEDED(hret
)); 
 945                 frame
->QueryInterface(IID_IDispatch
, (void**)&disp
); 
 946                 hret 
= cp
->Advise(new wxActiveXEvents(this, ta
->guid
), 
 948                 wxASSERT_MSG( SUCCEEDED(hret
), 
 949                     wxString::Format(wxT("Cannot connect!\nHRESULT:%X"), (unsigned int)hret
) 
 954         ti
->ReleaseTypeAttr(ta
); 
 958     typeInfo
->ReleaseTypeAttr(ta
); 
 964     // Get IOleObject interface 
 965     hret 
= m_oleObject
.QueryInterface(IID_IOleObject
, m_ActiveX
); 
 966     wxASSERT(SUCCEEDED(hret
)); 
 968     // get IViewObject Interface 
 969     hret 
= m_viewObject
.QueryInterface(IID_IViewObject
, m_ActiveX
); 
 970     wxASSERT(SUCCEEDED(hret
)); 
 973     m_docAdviseCookie 
= 0; 
 974     hret 
= m_oleObject
->Advise(adviseSink
, &m_docAdviseCookie
); 
 976 //    hret = m_viewObject->SetAdvise(DVASPECT_CONTENT, 0, adviseSink); 
 977     m_oleObject
->SetHostNames(L
"wxActiveXContainer", NULL
); 
 978     OleSetContainedObject(m_oleObject
, TRUE
); 
 982     // Get IOleInPlaceObject interface 
 983     hret 
= m_oleInPlaceObject
.QueryInterface( 
 984         IID_IOleInPlaceObject
, m_ActiveX
); 
 985     wxASSERT(SUCCEEDED(hret
)); 
 989     m_oleObject
->GetMiscStatus(DVASPECT_CONTENT
, &dwMiscStatus
); 
 990     wxASSERT(SUCCEEDED(hret
)); 
 992     // set client site first ? 
 993     if (dwMiscStatus 
& OLEMISC_SETCLIENTSITEFIRST
) 
 994         m_oleObject
->SetClientSite(m_clientSite
); 
 998     wxAutoIPersistStreamInit
 
 999         pPersistStreamInit(IID_IPersistStreamInit
, m_oleObject
); 
1001     if (pPersistStreamInit
.Ok()) 
1003         hret 
= pPersistStreamInit
->InitNew(); 
1006     if (! (dwMiscStatus 
& OLEMISC_SETCLIENTSITEFIRST
)) 
1007         m_oleObject
->SetClientSite(m_clientSite
); 
1011     ::GetClientRect((HWND
)m_realparent
->GetHWND(), &posRect
); 
1013     m_oleObjectHWND 
= 0; 
1015     if (m_oleInPlaceObject
.Ok()) 
1017         hret 
= m_oleInPlaceObject
->GetWindow(&m_oleObjectHWND
); 
1018         if (SUCCEEDED(hret
)) 
1019             ::SetActiveWindow(m_oleObjectHWND
); 
1023     if (! (dwMiscStatus 
& OLEMISC_INVISIBLEATRUNTIME
)) 
1025         if (posRect
.right 
> 0 && posRect
.bottom 
> 0 && 
1026             m_oleInPlaceObject
.Ok()) 
1027                 m_oleInPlaceObject
->SetObjectRects(&posRect
, &posRect
); 
1029         hret 
= m_oleObject
->DoVerb(OLEIVERB_INPLACEACTIVATE
, NULL
, 
1030             m_clientSite
, 0, (HWND
)m_realparent
->GetHWND(), &posRect
); 
1031         hret 
= m_oleObject
->DoVerb(OLEIVERB_SHOW
, 0, m_clientSite
, 0, 
1032             (HWND
)m_realparent
->GetHWND(), &posRect
); 
1035     if (! m_oleObjectHWND 
&& m_oleInPlaceObject
.Ok()) 
1037         hret 
= m_oleInPlaceObject
->GetWindow(&m_oleObjectHWND
); 
1040     if (m_oleObjectHWND
) 
1042         ::SetActiveWindow(m_oleObjectHWND
); 
1043         ::ShowWindow(m_oleObjectHWND
, SW_SHOW
); 
1045         this->AssociateHandle(m_oleObjectHWND
); 
1046         this->Reparent(m_realparent
); 
1048         wxWindow
* pWnd 
= m_realparent
; 
1049         int id 
= m_realparent
->GetId(); 
1051         pWnd
->Connect(id
, wxEVT_SIZE
, 
1052             wxSizeEventHandler(wxActiveXContainer::OnSize
), 0, this); 
1053 //        this->Connect(GetId(), wxEVT_PAINT, 
1054 //            wxPaintEventHandler(wxActiveXContainer::OnPaint), 0, this); 
1055         pWnd
->Connect(id
, wxEVT_SET_FOCUS
, 
1056             wxFocusEventHandler(wxActiveXContainer::OnSetFocus
), 0, this); 
1057         pWnd
->Connect(id
, wxEVT_KILL_FOCUS
, 
1058             wxFocusEventHandler(wxActiveXContainer::OnKillFocus
), 0, this); 
1062 //--------------------------------------------------------------------------- 
1063 // wxActiveXContainer::OnSize 
1065 // Called when the parent is resized - we need to do this to actually 
1066 // move the ActiveX control to where the parent is 
1067 //--------------------------------------------------------------------------- 
1068 void wxActiveXContainer::OnSize(wxSizeEvent
& event
) 
1071     GetParent()->GetClientSize(&w
, &h
); 
1079     if (w 
<= 0 && h 
<= 0) 
1082     // extents are in HIMETRIC units 
1083     if (m_oleObject
.Ok()) 
1085         m_oleObject
->DoVerb(OLEIVERB_HIDE
, 0, m_clientSite
, 0, 
1086             (HWND
)m_realparent
->GetHWND(), &posRect
); 
1089         PixelsToHimetric(sz
); 
1093         m_oleObject
->GetExtent(DVASPECT_CONTENT
, &sz2
); 
1094         if (sz2
.cx 
!=  sz
.cx 
|| sz
.cy 
!= sz2
.cy
) 
1095             m_oleObject
->SetExtent(DVASPECT_CONTENT
, &sz
); 
1097         m_oleObject
->DoVerb(OLEIVERB_SHOW
, 0, m_clientSite
, 0, 
1098             (HWND
)m_realparent
->GetHWND(), &posRect
); 
1101     if (m_oleInPlaceObject
.Ok()) 
1102         m_oleInPlaceObject
->SetObjectRects(&posRect
, &posRect
); 
1107 //--------------------------------------------------------------------------- 
1108 // wxActiveXContainer::OnPaint 
1110 // Called when the parent is resized - repaints the ActiveX control 
1111 //--------------------------------------------------------------------------- 
1112 void wxActiveXContainer::OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
1115     // Draw only when control is windowless or deactivated 
1119         GetParent()->GetSize(&w
, &h
); 
1126 #if !(defined(_WIN32_WCE) && _WIN32_WCE < 400) 
1127         ::RedrawWindow(m_oleObjectHWND
, NULL
, NULL
, RDW_INTERNALPAINT
); 
1129         ::InvalidateRect(m_oleObjectHWND
, NULL
, false); 
1131         RECTL 
*prcBounds 
= (RECTL 
*) &posRect
; 
1132         m_viewObject
->Draw(DVASPECT_CONTENT
, -1, NULL
, NULL
, NULL
, 
1133             (HDC
)dc
.GetHDC(), prcBounds
, NULL
, NULL
, 0); 
1137 //--------------------------------------------------------------------------- 
1138 // wxActiveXContainer::OnSetFocus 
1140 // Called when the focus is set on the parent - activates the activex control 
1141 //--------------------------------------------------------------------------- 
1142 void wxActiveXContainer::OnSetFocus(wxFocusEvent
& event
) 
1144     if (m_oleInPlaceActiveObject
.Ok()) 
1145         m_oleInPlaceActiveObject
->OnFrameWindowActivate(TRUE
); 
1150 //--------------------------------------------------------------------------- 
1151 // wxActiveXContainer::OnKillFocus 
1153 // Called when the focus is killed on the parent - 
1154 // deactivates the activex control 
1155 //--------------------------------------------------------------------------- 
1156 void wxActiveXContainer::OnKillFocus(wxFocusEvent
& event
) 
1158     if (m_oleInPlaceActiveObject
.Ok()) 
1159         m_oleInPlaceActiveObject
->OnFrameWindowActivate(FALSE
); 
1164 #endif // wxUSE_ACTIVEX