]>
Commit | Line | Data |
---|---|---|
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 | 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 | //////////////////////////////////////// | |
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 | ||
274 | inline bool IsIn() const {return (flags & IDLFLAG_FIN) != 0;} | |
275 | inline bool IsOut() const {return (flags & IDLFLAG_FOUT) != 0;} | |
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 | |
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 | void OnSetFocus(wxFocusEvent&); | |
319 | void OnKillFocus(wxFocusEvent&); | |
320 | ||
321 | DECLARE_EVENT_TABLE(); | |
322 | ||
323 | protected: | |
324 | friend class FrameSite; | |
325 | friend class wxActiveXEvents; | |
326 | ||
327 | typedef wxAutoOleInterface<IConnectionPoint> wxOleConnectionPoint; | |
328 | typedef pair<wxOleConnectionPoint, DWORD> wxOleConnection; | |
329 | typedef vector<wxOleConnection> wxOleConnectionArray; | |
330 | ||
331 | wxAutoOleInterface<IOleClientSite> m_clientSite; | |
332 | wxAutoOleInterface<IUnknown> m_ActiveX; | |
333 | wxAutoOleInterface<IOleObject> m_oleObject; | |
334 | wxAutoOleInterface<IOleInPlaceObject> m_oleInPlaceObject; | |
335 | wxAutoOleInterface<IOleInPlaceActiveObject> | |
336 | ||
337 | m_oleInPlaceActiveObject; | |
338 | wxAutoOleInterface<IOleDocumentView> m_docView; | |
339 | wxAutoOleInterface<IViewObject> m_viewObject; | |
340 | HWND m_oleObjectHWND; | |
341 | bool m_bAmbientUserMode; | |
342 | DWORD m_docAdviseCookie; | |
343 | wxOleConnectionArray m_connections; | |
344 | ||
345 | HRESULT AmbientPropertyChanged(DISPID dispid); | |
346 | ||
347 | void GetTypeInfo(); | |
348 | void GetTypeInfo(ITypeInfo *ti, bool defEventSink); | |
349 | ||
350 | ||
351 | // events | |
352 | FuncXArray m_events; | |
353 | MemberIdList m_eventsIdx; | |
354 | ||
355 | long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); | |
356 | }; | |
357 | ||
358 | // events | |
359 | class wxActiveXEvent : public wxCommandEvent | |
360 | { | |
361 | private: | |
362 | friend class wxActiveXEvents; | |
363 | ||
364 | wxVariant m_params; | |
365 | ||
366 | public: | |
367 | ||
368 | virtual wxEvent *Clone() const { return new wxActiveXEvent(*this); } | |
369 | ||
370 | wxString EventName(); | |
371 | int ParamCount() const; | |
372 | wxString ParamType(int idx); | |
373 | wxString ParamName(int idx); | |
374 | wxVariant operator[] (int idx) const; | |
375 | wxVariant& operator[] (int idx); | |
376 | wxVariant operator[] (wxString name) const; | |
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_ */ |