1 #ifndef WX_ACTIVE_X 2 #define WX_ACTIVE_X 3 #pragma warning( disable : 4101 4786) 4 #pragma warning( disable : 4786) 5 6 7 #include <wx/setup.h> 8 #include <wx/wx.h> 9 #include <wx/variant.h> 10 #include <oleidl.h> 11 #include <exdisp.h> 12 #include <docobj.h> 13 #include <iostream> 14 #include <vector> 15 #include <map> 16 using namespace std; 17 18 ////////////////////////////////////////// 19 // wxAutoOleInterface<Interface> 20 // Template class for smart interface handling 21 // - Automatically dereferences ole interfaces 22 // - Smart Copy Semantics 23 // - Can Create Interfaces 24 // - Can query for other interfaces 25 template <class I> class wxAutoOleInterface 26 { 27 protected: 28 I *m_interface; 29 30 public: 31 // takes ownership of an existing interface 32 // Assumed to already have a AddRef() applied m_interface(pInterface)33 explicit wxAutoOleInterface(I *pInterface = NULL) : m_interface(pInterface) {} 34 35 // queries for an interface wxAutoOleInterface(REFIID riid,IUnknown * pUnk)36 wxAutoOleInterface(REFIID riid, IUnknown *pUnk) : m_interface(NULL) 37 { 38 QueryInterface(riid, pUnk); 39 }; 40 // queries for an interface wxAutoOleInterface(REFIID riid,IDispatch * pDispatch)41 wxAutoOleInterface(REFIID riid, IDispatch *pDispatch) : m_interface(NULL) 42 { 43 QueryInterface(riid, pDispatch); 44 }; 45 46 // Creates an Interface wxAutoOleInterface(REFCLSID clsid,REFIID riid)47 wxAutoOleInterface(REFCLSID clsid, REFIID riid) : m_interface(NULL) 48 { 49 CreateInstance(clsid, riid); 50 }; 51 52 // copy constructor wxAutoOleInterface(const wxAutoOleInterface<I> & ti)53 wxAutoOleInterface(const wxAutoOleInterface<I>& ti) : m_interface(NULL) 54 { 55 operator = (ti); 56 } 57 58 // assignment operator 59 wxAutoOleInterface<I>& operator = (const wxAutoOleInterface<I>& ti) 60 { 61 if (ti.m_interface) 62 ti.m_interface->AddRef(); 63 Free(); 64 m_interface = ti.m_interface; 65 return *this; 66 } 67 68 // takes ownership of an existing interface 69 // Assumed to already have a AddRef() applied 70 wxAutoOleInterface<I>& operator = (I *&ti) 71 { 72 Free(); 73 m_interface = ti; 74 return *this; 75 } 76 ~wxAutoOleInterface()77 ~wxAutoOleInterface() 78 { 79 Free(); 80 }; 81 82 Free()83 inline void Free() 84 { 85 if (m_interface) 86 m_interface->Release(); 87 m_interface = NULL; 88 }; 89 90 // queries for an interface QueryInterface(REFIID riid,IUnknown * pUnk)91 HRESULT QueryInterface(REFIID riid, IUnknown *pUnk) 92 { 93 Free(); 94 wxASSERT(pUnk != NULL); 95 return pUnk->QueryInterface(riid, (void **) &m_interface); 96 }; 97 98 // Create a Interface instance CreateInstance(REFCLSID clsid,REFIID riid)99 HRESULT CreateInstance(REFCLSID clsid, REFIID riid) 100 { 101 Free(); 102 return CoCreateInstance(clsid, NULL, CLSCTX_ALL, riid, (void **) &m_interface); 103 }; 104 105 106 107 inline operator I *() const {return m_interface;} 108 inline I* operator ->() {return m_interface;} GetRef()109 inline I** GetRef() {return &m_interface;} 110 Ok()111 inline bool Ok() const {return m_interface != NULL;} 112 }; 113 114 115 wxString OLEHResultToString(HRESULT hr); 116 wxString GetIIDName(REFIID riid); 117 118 //#define __WXOLEDEBUG 119 120 121 #ifdef __WXOLEDEBUG 122 #define WXOLE_TRACE(str) {OutputDebugString(str);OutputDebugString("\r\n");} 123 #define WXOLE_TRACEOUT(stuff)\ 124 {\ 125 ostringstream os;\ 126 os << stuff << ends;\ 127 WXOLE_TRACE(os.str().c_str());\ 128 } 129 130 #define WXOLE_WARN(__hr,msg)\ 131 {\ 132 if (__hr != S_OK)\ 133 {\ 134 wxString s = "*** ";\ 135 s += msg;\ 136 s += " : "+ OLEHResultToString(__hr);\ 137 WXOLE_TRACE(s.c_str());\ 138 }\ 139 } 140 #else 141 #define WXOLE_TRACE(str) 142 #define WXOLE_TRACEOUT(stuff) 143 #define WXOLE_WARN(_proc,msg) {_proc;} 144 #endif 145 146 // Auto Initialisation 147 class wxOleInit 148 { 149 public: 150 static IMalloc *GetIMalloc(); 151 152 wxOleInit(); 153 ~wxOleInit(); 154 }; 155 156 #define DECLARE_OLE_UNKNOWN(cls)\ 157 private:\ 158 class TAutoInitInt\ 159 {\ 160 public:\ 161 LONG l;\ 162 TAutoInitInt() : l(0) {}\ 163 };\ 164 TAutoInitInt refCount, lockCount;\ 165 wxOleInit oleInit;\ 166 static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\ 167 public:\ 168 LONG GetRefCount();\ 169 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\ 170 ULONG STDMETHODCALLTYPE AddRef();\ 171 ULONG STDMETHODCALLTYPE Release();\ 172 ULONG STDMETHODCALLTYPE AddLock();\ 173 ULONG STDMETHODCALLTYPE ReleaseLock() 174 175 #define DEFINE_OLE_TABLE(cls)\ 176 LONG cls::GetRefCount() {return refCount.l;}\ 177 HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\ 178 {\ 179 if (! ppvObject)\ 180 {\ 181 WXOLE_TRACE("*** NULL POINTER ***");\ 182 return E_FAIL;\ 183 };\ 184 const char *desc = NULL;\ 185 cls::_GetInterface(this, iid, ppvObject, desc);\ 186 if (! *ppvObject)\ 187 {\ 188 WXOLE_TRACEOUT("<" << GetIIDName(iid).c_str() << "> Not Found");\ 189 return E_NOINTERFACE;\ 190 };\ 191 WXOLE_TRACEOUT("QI : <" << desc <<">");\ 192 ((IUnknown * )(*ppvObject))->AddRef();\ 193 return S_OK;\ 194 };\ 195 ULONG STDMETHODCALLTYPE cls::AddRef()\ 196 {\ 197 WXOLE_TRACEOUT(# cls << "::Add ref(" << refCount.l << ")");\ 198 InterlockedIncrement(&refCount.l);\ 199 return refCount.l;\ 200 };\ 201 ULONG STDMETHODCALLTYPE cls::Release()\ 202 {\ 203 if (refCount.l > 0)\ 204 {\ 205 InterlockedDecrement(&refCount.l);\ 206 WXOLE_TRACEOUT(# cls << "::Del ref(" << refCount.l << ")");\ 207 if (refCount.l == 0)\ 208 {\ 209 delete this;\ 210 return 0;\ 211 };\ 212 return refCount.l;\ 213 }\ 214 else\ 215 return 0;\ 216 }\ 217 ULONG STDMETHODCALLTYPE cls::AddLock()\ 218 {\ 219 WXOLE_TRACEOUT(# cls << "::Add Lock(" << lockCount.l << ")");\ 220 InterlockedIncrement(&lockCount.l);\ 221 return lockCount.l;\ 222 };\ 223 ULONG STDMETHODCALLTYPE cls::ReleaseLock()\ 224 {\ 225 if (lockCount.l > 0)\ 226 {\ 227 InterlockedDecrement(&lockCount.l);\ 228 WXOLE_TRACEOUT(# cls << "::Del Lock(" << lockCount.l << ")");\ 229 return lockCount.l;\ 230 }\ 231 else\ 232 return 0;\ 233 }\ 234 DEFINE_OLE_BASE(cls) 235 236 #define DEFINE_OLE_BASE(cls)\ 237 void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\ 238 {\ 239 *_interface = NULL;\ 240 desc = NULL; 241 242 #define OLE_INTERFACE(_iid, _type)\ 243 if (IsEqualIID(iid, _iid))\ 244 {\ 245 WXOLE_TRACE("Found Interface <" # _type ">");\ 246 *_interface = (IUnknown *) (_type *) self;\ 247 desc = # _iid;\ 248 return;\ 249 } 250 251 #define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face) 252 253 #define OLE_INTERFACE_CUSTOM(func)\ 254 if (func(self, iid, _interface, desc))\ 255 return 256 257 #define END_OLE_TABLE\ 258 } 259 260 261 262 class wxActiveX : public wxWindow { 263 public: 264 //////////////////////////////////////// 265 // type stuff 266 class ParamX // refer to ELEMDESC, IDLDESC in MSDN 267 { 268 public: 269 USHORT flags; 270 bool isPtr, isSafeArray; 271 VARTYPE vt; 272 wxString name; 273 IsIn()274 inline bool IsIn() const {return (flags & IDLFLAG_FIN) != 0;} IsOut()275 inline bool IsOut() const {return (flags & IDLFLAG_FOUT) != 0;} IsRetVal()276 inline bool IsRetVal() const {return (flags & IDLFLAG_FRETVAL) != 0;} 277 }; 278 279 typedef vector<ParamX> ParamXArray; 280 281 class FuncX // refer to FUNCDESC in MSDN 282 { 283 public: 284 wxString name; 285 MEMBERID memid; 286 bool hasOut; 287 288 ParamXArray params; 289 }; 290 291 typedef vector<FuncX> FuncXArray; 292 typedef map<MEMBERID, int> MemberIdList; 293 294 wxActiveX(wxWindow * parent, REFCLSID clsid, wxWindowID id = -1, 295 const wxPoint& pos = wxDefaultPosition, 296 const wxSize& size = wxDefaultSize, 297 long style = 0, 298 const wxString& name = wxPanelNameStr); 299 wxActiveX(wxWindow * parent, wxString progId, wxWindowID id = -1, 300 const wxPoint& pos = wxDefaultPosition, 301 const wxSize& size = wxDefaultSize, 302 long style = 0, 303 const wxString& name = wxPanelNameStr); 304 virtual ~wxActiveX(); 305 306 void CreateActiveX(REFCLSID clsid); 307 void CreateActiveX(LPOLESTR progId); 308 309 // expose type info GetEventCount()310 inline int GetEventCount() const {return m_events.size();} 311 const FuncX& GetEvent(int idx) const; 312 313 HRESULT ConnectAdvise(REFIID riid, IUnknown *eventSink); 314 315 void OnSize(wxSizeEvent&); 316 void OnPaint(wxPaintEvent& event); 317 void OnMouse(wxMouseEvent& event); 318 319 void OnSetFocus(wxFocusEvent&); 320 void OnKillFocus(wxFocusEvent&); 321 322 DECLARE_EVENT_TABLE(); 323 324 protected: 325 friend class FrameSite; 326 friend class wxActiveXEvents; 327 328 typedef wxAutoOleInterface<IConnectionPoint> wxOleConnectionPoint; 329 typedef pair<wxOleConnectionPoint, DWORD> wxOleConnection; 330 typedef vector<wxOleConnection> wxOleConnectionArray; 331 332 wxAutoOleInterface<IOleClientSite> m_clientSite; 333 wxAutoOleInterface<IUnknown> m_ActiveX; 334 wxAutoOleInterface<IOleObject> m_oleObject; 335 wxAutoOleInterface<IOleInPlaceObject> m_oleInPlaceObject; 336 wxAutoOleInterface<IOleInPlaceActiveObject> 337 338 m_oleInPlaceActiveObject; 339 wxAutoOleInterface<IOleDocumentView> m_docView; 340 wxAutoOleInterface<IViewObject> m_viewObject; 341 HWND m_oleObjectHWND; 342 bool m_bAmbientUserMode; 343 DWORD m_docAdviseCookie; 344 wxOleConnectionArray m_connections; 345 346 HRESULT AmbientPropertyChanged(DISPID dispid); 347 348 void GetTypeInfo(); 349 void GetTypeInfo(ITypeInfo *ti, bool defEventSink); 350 351 352 // events 353 FuncXArray m_events; 354 MemberIdList m_eventsIdx; 355 356 long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); 357 358 }; 359 360 // events 361 class wxActiveXEvent : public wxCommandEvent 362 { 363 private: 364 friend class wxActiveXEvents; 365 366 wxVariant m_params; 367 368 public: 369 Clone()370 virtual wxEvent *Clone() const { return new wxActiveXEvent(*this); } 371 372 wxString EventName(); 373 int ParamCount() const; 374 wxString ParamType(int idx); 375 wxString ParamName(int idx); 376 wxVariant& operator[] (int idx); 377 wxVariant& operator[] (wxString name); 378 }; 379 380 const wxEventType& RegisterActiveXEvent(const wxChar *eventName); 381 const wxEventType& RegisterActiveXEvent(DISPID event); 382 383 typedef void (wxEvtHandler::*wxActiveXEventFunction)(wxActiveXEvent&); 384 385 #define EVT_ACTIVEX(id, eventName, fn) DECLARE_EVENT_TABLE_ENTRY(RegisterActiveXEvent(wxT(eventName)), id, -1, (wxObjectEventFunction) (wxEventFunction) (wxActiveXEventFunction) & fn, (wxObject *) NULL ), 386 #define EVT_ACTIVEX_DISPID(id, eventDispId, fn) DECLARE_EVENT_TABLE_ENTRY(RegisterActiveXEvent(eventDispId), id, -1, (wxObjectEventFunction) (wxEventFunction) (wxActiveXEventFunction) & fn, (wxObject *) NULL ), 387 388 //util 389 bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx); 390 bool VariantToMSWVariant(wxVariant& vx, VARIANTARG& va); 391 392 #endif /* _IEHTMLWIN_H_ */ 393