00001
00005 #ifndef WX_ACTIVE_X
00006 #define WX_ACTIVE_X
00007 #pragma warning( disable : 4101 4786)
00008 #pragma warning( disable : 4786)
00009
00010
00011 #include <wx/setup.h>
00012 #include <wx/wx.h>
00013 #include <wx/variant.h>
00014 #include <wx/datetime.h>
00015 #include <oleidl.h>
00016 #include <exdisp.h>
00017 #include <docobj.h>
00018 #include <iostream>
00019 #include <vector>
00020 #include <map>
00021 using namespace std;
00022
00024 namespace NS_wxActiveX
00025 {
00029 struct less_wxStringI
00030 {
00031 bool operator()(const wxString& x, const wxString& y) const
00032 {
00033 return x.CmpNoCase(y) < 0;
00034 };
00035 };
00036 };
00037
00038
00045 template <class I> class wxAutoOleInterface
00046 {
00047 protected:
00048 I *m_interface;
00049
00050 public:
00053 explicit wxAutoOleInterface(I *pInterface = NULL) : m_interface(pInterface) {}
00054
00056 wxAutoOleInterface(REFIID riid, IUnknown *pUnk) : m_interface(NULL)
00057 {
00058 QueryInterface(riid, pUnk);
00059 };
00061 wxAutoOleInterface(REFIID riid, IDispatch *pDispatch) : m_interface(NULL)
00062 {
00063 QueryInterface(riid, pDispatch);
00064 };
00065
00067 wxAutoOleInterface(REFCLSID clsid, REFIID riid) : m_interface(NULL)
00068 {
00069 CreateInstance(clsid, riid);
00070 };
00071
00073 wxAutoOleInterface(const wxAutoOleInterface<I>& ti) : m_interface(NULL)
00074 {
00075 operator = (ti);
00076 }
00077
00079 wxAutoOleInterface<I>& operator = (const wxAutoOleInterface<I>& ti)
00080 {
00081 if (ti.m_interface)
00082 ti.m_interface->AddRef();
00083 Free();
00084 m_interface = ti.m_interface;
00085 return *this;
00086 }
00087
00090 wxAutoOleInterface<I>& operator = (I *&ti)
00091 {
00092 Free();
00093 m_interface = ti;
00094 return *this;
00095 }
00096
00098 ~wxAutoOleInterface()
00099 {
00100 Free();
00101 };
00102
00103
00105 inline void Free()
00106 {
00107 if (m_interface)
00108 m_interface->Release();
00109 m_interface = NULL;
00110 };
00111
00113 HRESULT QueryInterface(REFIID riid, IUnknown *pUnk)
00114 {
00115 Free();
00116 wxASSERT(pUnk != NULL);
00117 return pUnk->QueryInterface(riid, (void **) &m_interface);
00118 };
00119
00121 HRESULT CreateInstance(REFCLSID clsid, REFIID riid)
00122 {
00123 Free();
00124 return CoCreateInstance(clsid, NULL, CLSCTX_ALL, riid, (void **) &m_interface);
00125 };
00126
00127
00129 inline operator I *() const {return m_interface;}
00130
00132 inline I* operator ->() {return m_interface;}
00134 inline I** GetRef() {return &m_interface;}
00136 inline bool Ok() const {return m_interface != NULL;}
00137 };
00138
00139
00142 wxString OLEHResultToString(HRESULT hr);
00145 wxString GetIIDName(REFIID riid);
00146
00147
00148
00149
00150 #ifdef __WXOLEDEBUG
00151 #define WXOLE_TRACE(str) {OutputDebugString(str);OutputDebugString("\r\n");}
00152 #define WXOLE_TRACEOUT(stuff)\
00153 {\
00154 wxString os;\
00155 os << stuff << "\r\n";\
00156 WXOLE_TRACE(os.mb_str());\
00157 }
00158
00159 #define WXOLE_WARN(__hr,msg)\
00160 {\
00161 if (__hr != S_OK)\
00162 {\
00163 wxString s = "*** ";\
00164 s += msg;\
00165 s += " : "+ OLEHResultToString(__hr);\
00166 WXOLE_TRACE(s.c_str());\
00167 }\
00168 }
00169 #else
00170 #define WXOLE_TRACE(str)
00171 #define WXOLE_TRACEOUT(stuff)
00172 #define WXOLE_WARN(_proc,msg) {_proc;}
00173 #endif
00174
00175 class wxOleInit
00176 {
00177 public:
00178 static IMalloc *GetIMalloc();
00179
00180 wxOleInit();
00181 ~wxOleInit();
00182 };
00183
00184 #define DECLARE_OLE_UNKNOWN(cls)\
00185 private:\
00186 class TAutoInitInt\
00187 {\
00188 public:\
00189 LONG l;\
00190 TAutoInitInt() : l(0) {}\
00191 };\
00192 TAutoInitInt refCount, lockCount;\
00193 wxOleInit oleInit;\
00194 static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\
00195 public:\
00196 LONG GetRefCount();\
00197 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\
00198 ULONG STDMETHODCALLTYPE AddRef();\
00199 ULONG STDMETHODCALLTYPE Release();\
00200 ULONG STDMETHODCALLTYPE AddLock();\
00201 ULONG STDMETHODCALLTYPE ReleaseLock()
00202
00203 #define DEFINE_OLE_TABLE(cls)\
00204 LONG cls::GetRefCount() {return refCount.l;}\
00205 HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\
00206 {\
00207 if (! ppvObject)\
00208 {\
00209 WXOLE_TRACE("*** NULL POINTER ***");\
00210 return E_FAIL;\
00211 };\
00212 const char *desc = NULL;\
00213 cls::_GetInterface(this, iid, ppvObject, desc);\
00214 if (! *ppvObject)\
00215 {\
00216 WXOLE_TRACEOUT("<" << GetIIDName(iid).c_str() << "> Not Found");\
00217 return E_NOINTERFACE;\
00218 };\
00219 WXOLE_TRACEOUT("QI : <" << desc <<">");\
00220 ((IUnknown * )(*ppvObject))->AddRef();\
00221 return S_OK;\
00222 };\
00223 ULONG STDMETHODCALLTYPE cls::AddRef()\
00224 {\
00225 WXOLE_TRACEOUT(# cls << "::Add ref(" << refCount.l << ")");\
00226 InterlockedIncrement(&refCount.l);\
00227 return refCount.l;\
00228 };\
00229 ULONG STDMETHODCALLTYPE cls::Release()\
00230 {\
00231 if (refCount.l > 0)\
00232 {\
00233 InterlockedDecrement(&refCount.l);\
00234 WXOLE_TRACEOUT(# cls << "::Del ref(" << refCount.l << ")");\
00235 if (refCount.l == 0)\
00236 {\
00237 delete this;\
00238 return 0;\
00239 };\
00240 return refCount.l;\
00241 }\
00242 else\
00243 return 0;\
00244 }\
00245 ULONG STDMETHODCALLTYPE cls::AddLock()\
00246 {\
00247 WXOLE_TRACEOUT(# cls << "::Add Lock(" << lockCount.l << ")");\
00248 InterlockedIncrement(&lockCount.l);\
00249 return lockCount.l;\
00250 };\
00251 ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
00252 {\
00253 if (lockCount.l > 0)\
00254 {\
00255 InterlockedDecrement(&lockCount.l);\
00256 WXOLE_TRACEOUT(# cls << "::Del Lock(" << lockCount.l << ")");\
00257 return lockCount.l;\
00258 }\
00259 else\
00260 return 0;\
00261 }\
00262 DEFINE_OLE_BASE(cls)
00263
00264 #define DEFINE_OLE_BASE(cls)\
00265 void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\
00266 {\
00267 *_interface = NULL;\
00268 desc = NULL;
00269
00270 #define OLE_INTERFACE(_iid, _type)\
00271 if (IsEqualIID(iid, _iid))\
00272 {\
00273 WXOLE_TRACE("Found Interface <" # _type ">");\
00274 *_interface = (IUnknown *) (_type *) self;\
00275 desc = # _iid;\
00276 return;\
00277 }
00278
00279 #define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face)
00280
00281 #define OLE_INTERFACE_CUSTOM(func)\
00282 if (func(self, iid, _interface, desc))\
00283 {\
00284 return;\
00285 }
00286
00287 #define END_OLE_TABLE\
00288 }
00289
00290
00328
00329 class wxActiveX : public wxWindow {
00330 public:
00333 class ParamX
00334 {
00335 public:
00336 USHORT flags;
00337 bool isPtr, isSafeArray;
00338 VARTYPE vt;
00339 wxString name;
00340
00341 ParamX() : vt(VT_EMPTY) {}
00342 inline bool IsIn() const {return (flags & IDLFLAG_FIN) != 0;}
00343 inline bool IsOut() const {return (flags & IDLFLAG_FOUT) != 0;}
00344 inline bool IsRetVal() const {return (flags & IDLFLAG_FRETVAL) != 0;}
00345 };
00346 typedef vector<ParamX> ParamXArray;
00347
00350 class FuncX
00351 {
00352 public:
00353 wxString name;
00354 MEMBERID memid;
00355 bool hasOut;
00356
00357 ParamX retType;
00358 ParamXArray params;
00359 };
00360
00362 class PropX
00363 {
00364 public:
00365 wxString name;
00366 MEMBERID memid;
00367 ParamX type;
00368 ParamX arg;
00369 bool putByRef;
00370
00371 PropX() : putByRef (false) {}
00372 inline bool CanGet() const {return type.vt != VT_EMPTY;}
00373 inline bool CanSet() const {return arg.vt != VT_EMPTY;}
00374 };
00375
00377 wxActiveX(wxWindow * parent, REFCLSID clsid, wxWindowID id = -1,
00378 const wxPoint& pos = wxDefaultPosition,
00379 const wxSize& size = wxDefaultSize,
00380 long style = 0,
00381 const wxString& name = wxPanelNameStr);
00383 wxActiveX(wxWindow * parent, wxString progId, wxWindowID id = -1,
00384 const wxPoint& pos = wxDefaultPosition,
00385 const wxSize& size = wxDefaultSize,
00386 long style = 0,
00387 const wxString& name = wxPanelNameStr);
00388 virtual ~wxActiveX();
00389
00391 inline int GetEventCount() const {return m_events.size();}
00394 const FuncX& GetEventDesc(int idx) const;
00395
00397 inline int GetPropCount() const {return m_props.size();}
00400 const PropX& GetPropDesc(int idx) const;
00403 const PropX& GetPropDesc(wxString name) const;
00404
00406 inline int GetMethodCount() const {return m_methods.size();}
00409 const FuncX& GetMethodDesc(int idx) const;
00412 const FuncX& GetMethodDesc(wxString name) const;
00413
00415 void SetProp(MEMBERID name, VARIANTARG& value);
00417 void SetProp(const wxString &name, const wxVariant &value);
00418
00419 class wxPropertySetter
00420 {
00421 public:
00422 wxActiveX *m_ctl;
00423 wxString m_propName;
00424
00425 wxPropertySetter(wxActiveX *ctl, wxString propName) :
00426 m_ctl(ctl), m_propName(propName) {}
00427
00428 inline const wxPropertySetter& operator = (wxVariant v) const
00429 {
00430 m_ctl->SetProp(m_propName, v);
00431 return *this;
00432 };
00433
00434 inline operator wxVariant() const {return m_ctl->GetPropAsWxVariant(m_propName);};
00435 inline operator wxString() const {return m_ctl->GetPropAsString(m_propName);};
00436 inline operator char() const {return m_ctl->GetPropAsChar(m_propName);};
00437 inline operator long() const {return m_ctl->GetPropAsLong(m_propName);};
00438 inline operator bool() const {return m_ctl->GetPropAsBool(m_propName);};
00439 inline operator double() const {return m_ctl->GetPropAsDouble(m_propName);};
00440 inline operator wxDateTime() const {return m_ctl->GetPropAsDateTime(m_propName);};
00441 inline operator void *() const {return m_ctl->GetPropAsPointer(m_propName);};
00442 };
00443
00458 inline wxPropertySetter Prop(wxString name) {return wxPropertySetter(this, name);}
00459
00460 VARIANT GetPropAsVariant(MEMBERID name);
00461 VARIANT GetPropAsVariant(const wxString& name);
00462 wxVariant GetPropAsWxVariant(const wxString& name);
00463 wxString GetPropAsString(const wxString& name);
00464 char GetPropAsChar(const wxString& name);
00465 long GetPropAsLong(const wxString& name);
00466 bool GetPropAsBool(const wxString& name);
00467 double GetPropAsDouble(const wxString& name);
00468 wxDateTime GetPropAsDateTime(const wxString& name);
00469 void *GetPropAsPointer(const wxString& name);
00470
00471
00472
00473
00474 VARIANT CallMethod(MEMBERID name, VARIANTARG args[], int argc);
00475 VARIANT CallMethod(wxString name, VARIANTARG args[] = NULL, int argc = -1);
00476
00477
00493
00494
00495 HRESULT ConnectAdvise(REFIID riid, IUnknown *eventSink);
00496
00497 void OnSize(wxSizeEvent&);
00498 void OnPaint(wxPaintEvent& event);
00499 void OnMouse(wxMouseEvent& event);
00500 void OnSetFocus(wxFocusEvent&);
00501 void OnKillFocus(wxFocusEvent&);
00502
00503 DECLARE_EVENT_TABLE();
00504
00505 protected:
00506 friend class FrameSite;
00507 friend class wxActiveXEvents;
00508
00509 typedef map<MEMBERID, FuncX> FuncXMap;
00510 typedef map<wxString, FuncX, NS_wxActiveX::less_wxStringI> FuncXStringMap;
00511 typedef map<wxString, PropX, NS_wxActiveX::less_wxStringI> PropXMap;
00512 typedef wxAutoOleInterface<IConnectionPoint> wxOleConnectionPoint;
00513 typedef pair<wxOleConnectionPoint, DWORD> wxOleConnection;
00514 typedef vector<wxOleConnection> wxOleConnectionArray;
00515
00516 wxAutoOleInterface<IDispatch> m_Dispatch;
00517 wxAutoOleInterface<IOleClientSite> m_clientSite;
00518 wxAutoOleInterface<IUnknown> m_ActiveX;
00519 wxAutoOleInterface<IOleObject> m_oleObject;
00520 wxAutoOleInterface<IOleInPlaceObject> m_oleInPlaceObject;
00521 wxAutoOleInterface<IOleInPlaceActiveObject>
00522
00523 m_oleInPlaceActiveObject;
00524 wxAutoOleInterface<IOleDocumentView> m_docView;
00525 wxAutoOleInterface<IViewObject> m_viewObject;
00526 HWND m_oleObjectHWND;
00527 bool m_bAmbientUserMode;
00528 DWORD m_docAdviseCookie;
00529 wxOleConnectionArray m_connections;
00530
00531 void CreateActiveX(REFCLSID clsid);
00532 void CreateActiveX(LPOLESTR progId);
00533 HRESULT AmbientPropertyChanged(DISPID dispid);
00534
00535 void GetTypeInfo();
00536 void GetTypeInfo(ITypeInfo *ti, bool defInterface, bool defEventSink);
00537
00538
00539
00540 FuncXMap m_events;
00541
00542
00543 PropXMap m_props;
00544
00545
00546 FuncXStringMap m_methods;
00547
00548 long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
00549 };
00550
00551
00552 class wxActiveXEvent : public wxCommandEvent
00553 {
00554 private:
00555 friend class wxActiveXEvents;
00556
00557 wxVariant m_params;
00558
00559 public:
00560
00561 virtual wxEvent *Clone() const { return new wxActiveXEvent(*this); }
00562
00563 wxString EventName();
00564 int ParamCount() const;
00565 wxString ParamType(int idx);
00566 wxString ParamName(int idx);
00567 wxVariant& operator[] (int idx);
00568 wxVariant& operator[] (wxString name);
00569 };
00570
00571 const wxEventType& RegisterActiveXEvent(const wxChar *eventName);
00572 const wxEventType& RegisterActiveXEvent(DISPID event);
00573
00574 typedef void (wxEvtHandler::*wxActiveXEventFunction)(wxActiveXEvent&);
00575
00578 #define EVT_ACTIVEX(id, eventName, fn) DECLARE_EVENT_TABLE_ENTRY(RegisterActiveXEvent(wxT(eventName)), id, -1, (wxObjectEventFunction) (wxEventFunction) (wxActiveXEventFunction) & fn, (wxObject *) NULL ),
00581 #define EVT_ACTIVEX_DISPID(id, eventDispId, fn) DECLARE_EVENT_TABLE_ENTRY(RegisterActiveXEvent(eventDispId), id, -1, (wxObjectEventFunction) (wxEventFunction) (wxActiveXEventFunction) & fn, (wxObject *) NULL ),
00582
00583
00584 bool wxDateTimeToVariant(wxDateTime dt, VARIANTARG& va);
00585 bool VariantToWxDateTime(VARIANTARG va, wxDateTime& dt);
00596 bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx);
00607 bool VariantToMSWVariant(const wxVariant& vx, VARIANTARG& va);
00608
00609 #endif