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