]> git.saurik.com Git - wxWidgets.git/blob - wxPython/contrib/iewin/wxactivex.h
New wxActiveX and wxIEHtmlWin from Lindsay
[wxWidgets.git] / wxPython / contrib / iewin / wxactivex.h
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
33 explicit wxAutoOleInterface(I *pInterface = NULL) : m_interface(pInterface) {}
34
35 // queries for an interface
36 wxAutoOleInterface(REFIID riid, IUnknown *pUnk) : m_interface(NULL)
37 {
38 QueryInterface(riid, pUnk);
39 };
40 // queries for an interface
41 wxAutoOleInterface(REFIID riid, IDispatch *pDispatch) : m_interface(NULL)
42 {
43 QueryInterface(riid, pDispatch);
44 };
45
46 // Creates an Interface
47 wxAutoOleInterface(REFCLSID clsid, REFIID riid) : m_interface(NULL)
48 {
49 CreateInstance(clsid, riid);
50 };
51
52 // copy constructor
53 explicit 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
77 ~wxAutoOleInterface()
78 {
79 Free();
80 };
81
82
83 inline void Free()
84 {
85 if (m_interface)
86 m_interface->Release();
87 m_interface = NULL;
88 };
89
90 // queries for an interface
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
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;}
109 inline I** GetRef() {return &m_interface;}
110
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 wxActiveX(wxWindow * parent, REFCLSID clsid, wxWindowID id = -1,
265 const wxPoint& pos = wxDefaultPosition,
266 const wxSize& size = wxDefaultSize,
267 long style = 0,
268 const wxString& name = wxPanelNameStr);
269 wxActiveX(wxWindow * parent, wxString progId, wxWindowID id = -1,
270 const wxPoint& pos = wxDefaultPosition,
271 const wxSize& size = wxDefaultSize,
272 long style = 0,
273 const wxString& name = wxPanelNameStr);
274 virtual ~wxActiveX();
275
276 void CreateActiveX(REFCLSID clsid);
277 void CreateActiveX(LPOLESTR progId);
278
279 void GetTypeInfo();
280 void GetTypeInfo(ITypeInfo *ti, bool defEventSink);
281
282 HRESULT ConnectAdvise(REFIID riid, IUnknown *eventSink);
283
284 void OnSize(wxSizeEvent&);
285 void OnSetFocus(wxFocusEvent&);
286 void OnKillFocus(wxFocusEvent&);
287
288 DECLARE_EVENT_TABLE();
289
290 protected:
291 friend class FrameSite;
292 friend class wxActiveXEvents;
293
294 typedef wxAutoOleInterface<IConnectionPoint> wxOleConnectionPoint;
295 typedef pair<wxOleConnectionPoint, DWORD> wxOleConnection;
296 typedef vector<wxOleConnection> wxOleConnectionArray;
297
298 wxAutoOleInterface<IOleClientSite> m_clientSite;
299 wxAutoOleInterface<IUnknown> m_ActiveX;
300 wxAutoOleInterface<IOleObject> m_oleObject;
301 wxAutoOleInterface<IOleInPlaceObject> m_oleInPlaceObject;
302 wxAutoOleInterface<IOleInPlaceActiveObject>
303
304 m_oleInPlaceActiveObject;
305 wxAutoOleInterface<IOleDocumentView> m_docView;
306 HWND m_oleObjectHWND;
307 bool m_bAmbientUserMode;
308 DWORD m_docAdviseCookie;
309 wxOleConnectionArray m_connections;
310
311 HRESULT AmbientPropertyChanged(DISPID dispid);
312
313 // type stuff
314 class ParamX // refer to ELEMDESC, IDLDESC in MSDN
315 {
316 public:
317 USHORT flags;
318 VARTYPE vt;
319 wxString name;
320
321 inline bool IsIn() const {return (flags & IDLFLAG_FIN) != 0;}
322 inline bool IsOut() const {return (flags & IDLFLAG_FOUT) != 0;}
323 inline bool IsRetVal() const {return (flags & IDLFLAG_FRETVAL) != 0;}
324 };
325
326 typedef vector<ParamX> ParamXArray;
327
328 class FuncX // refer to FUNCDESC in MSDN
329 {
330 public:
331 wxString name;
332 MEMBERID memid;
333 bool hasOut;
334
335 ParamXArray params;
336 };
337
338 typedef vector<FuncX> FuncXArray;
339 typedef map<MEMBERID, int> MemberIdList;
340
341 // events
342 FuncXArray m_events;
343 MemberIdList m_eventsIdx;
344 };
345
346 // events
347 class wxActiveXEvent : public wxNotifyEvent
348 {
349 private:
350 friend class wxActiveXEvents;
351
352 wxVariant m_params;
353
354 public:
355
356 virtual wxEvent *Clone() const { return new wxActiveXEvent(*this); }
357
358 int ParamCount() const;
359 wxVariant operator[] (int idx) const;
360 wxVariant& operator[] (int idx);
361 wxVariant operator[] (wxString name) const;
362 wxVariant& operator[] (wxString name);
363 };
364
365 const wxEventType& RegisterActiveXEvent(wxString eventName);
366
367 typedef void (wxEvtHandler::*wxActiveXEventFunction)(wxActiveXEvent&);
368
369 #define EVT_ACTIVEX(id, eventName, fn) DECLARE_EVENT_TABLE_ENTRY(RegisterActiveXEvent(eventName), id, -1, (wxObjectEventFunction) (wxEventFunction) (wxActiveXEventFunction) & fn, (wxObject *) NULL ),
370
371 //util
372 bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx);
373 bool VariantToMSWVariant(wxVariant& vx, VARIANTARG& va);
374
375 #endif /* _IEHTMLWIN_H_ */