]> git.saurik.com Git - wxWidgets.git/blob - include/wx/msw/ole/oleutils.h
Fix typo in definitions of BEGIN_EVENT_TABLE_TEMPLATEn() macros with n>=2.
[wxWidgets.git] / include / wx / msw / ole / oleutils.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/msw/ole/oleutils.h
3 // Purpose: OLE helper routines, OLE debugging support &c
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 19.02.1998
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_OLEUTILS_H
13 #define _WX_OLEUTILS_H
14
15 #include "wx/defs.h"
16
17 #if wxUSE_OLE
18
19 // ole2.h includes windows.h, so include wrapwin.h first
20 #include "wx/msw/wrapwin.h"
21 // get IUnknown, REFIID &c
22 #include <ole2.h>
23 #include "wx/intl.h"
24 #include "wx/log.h"
25
26 // ============================================================================
27 // General purpose functions and macros
28 // ============================================================================
29
30 // ----------------------------------------------------------------------------
31 // initialize/cleanup OLE
32 // ----------------------------------------------------------------------------
33
34 // call OleInitialize() or CoInitialize[Ex]() depending on the platform
35 //
36 // return true if ok, false otherwise
37 inline bool wxOleInitialize()
38 {
39 HRESULT
40 #ifdef __WXWINCE__
41 hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
42 #else
43 hr = ::OleInitialize(NULL);
44 #endif
45
46 // RPC_E_CHANGED_MODE indicates that OLE had been already initialized
47 // before, albeit with different mode. Don't consider it to be an error as
48 // we don't actually care ourselves about the mode used so this allows the
49 // main application to call OleInitialize() on its own before we do if it
50 // needs non-default mode.
51 if ( hr != RPC_E_CHANGED_MODE && FAILED(hr) )
52 {
53 wxLogError(_("Cannot initialize OLE"));
54
55 return false;
56 }
57
58 return true;
59 }
60
61 inline void wxOleUninitialize()
62 {
63 #ifdef __WXWINCE__
64 ::CoUninitialize();
65 #else
66 ::OleUninitialize();
67 #endif
68 }
69
70 // ----------------------------------------------------------------------------
71 // misc helper functions/macros
72 // ----------------------------------------------------------------------------
73
74 // release the interface pointer (if !NULL)
75 inline void ReleaseInterface(IUnknown *pIUnk)
76 {
77 if ( pIUnk != NULL )
78 pIUnk->Release();
79 }
80
81 // release the interface pointer (if !NULL) and make it NULL
82 #define RELEASE_AND_NULL(p) if ( (p) != NULL ) { p->Release(); p = NULL; };
83
84 // return true if the iid is in the array
85 extern WXDLLIMPEXP_CORE bool IsIidFromList(REFIID riid, const IID *aIids[], size_t nCount);
86
87 // ============================================================================
88 // IUnknown implementation helpers
89 // ============================================================================
90
91 /*
92 The most dumb implementation of IUnknown methods. We don't support
93 aggregation nor containment, but for 99% of cases this simple
94 implementation is quite enough.
95
96 Usage is trivial: here is all you should have
97 1) DECLARE_IUNKNOWN_METHODS in your (IUnknown derived!) class declaration
98 2) BEGIN/END_IID_TABLE with ADD_IID in between for all interfaces you
99 support (at least all for which you intent to return 'this' from QI,
100 i.e. you should derive from IFoo if you have ADD_IID(Foo)) somewhere else
101 3) IMPLEMENT_IUNKNOWN_METHODS somewhere also
102
103 These macros are quite simple: AddRef and Release are trivial and QI does
104 lookup in a static member array of IIDs and returns 'this' if it founds
105 the requested interface in it or E_NOINTERFACE if not.
106 */
107
108 /*
109 wxAutoULong: this class is used for automatically initalising m_cRef to 0
110 */
111 class wxAutoULong
112 {
113 public:
114 wxAutoULong(ULONG value = 0) : m_Value(value) { }
115
116 operator ULONG&() { return m_Value; }
117 ULONG& operator=(ULONG value) { m_Value = value; return m_Value; }
118
119 wxAutoULong& operator++() { ++m_Value; return *this; }
120 const wxAutoULong operator++( int ) { wxAutoULong temp = *this; ++m_Value; return temp; }
121
122 wxAutoULong& operator--() { --m_Value; return *this; }
123 const wxAutoULong operator--( int ) { wxAutoULong temp = *this; --m_Value; return temp; }
124
125 private:
126 ULONG m_Value;
127 };
128
129 // declare the methods and the member variable containing reference count
130 // you must also define the ms_aIids array somewhere with BEGIN_IID_TABLE
131 // and friends (see below)
132
133 #define DECLARE_IUNKNOWN_METHODS \
134 public: \
135 STDMETHODIMP QueryInterface(REFIID, void **); \
136 STDMETHODIMP_(ULONG) AddRef(); \
137 STDMETHODIMP_(ULONG) Release(); \
138 private: \
139 static const IID *ms_aIids[]; \
140 wxAutoULong m_cRef
141
142 // macros for declaring supported interfaces
143 // NB: ADD_IID prepends IID_I whereas ADD_RAW_IID does not
144 #define BEGIN_IID_TABLE(cname) const IID *cname::ms_aIids[] = {
145 #define ADD_IID(iid) &IID_I##iid,
146 #define ADD_RAW_IID(iid) &iid,
147 #define END_IID_TABLE }
148
149 // implementation is as straightforward as possible
150 // Parameter: classname - the name of the class
151 #define IMPLEMENT_IUNKNOWN_METHODS(classname) \
152 STDMETHODIMP classname::QueryInterface(REFIID riid, void **ppv) \
153 { \
154 wxLogQueryInterface(wxT(#classname), riid); \
155 \
156 if ( IsIidFromList(riid, ms_aIids, WXSIZEOF(ms_aIids)) ) { \
157 *ppv = this; \
158 AddRef(); \
159 \
160 return S_OK; \
161 } \
162 else { \
163 *ppv = NULL; \
164 \
165 return (HRESULT) E_NOINTERFACE; \
166 } \
167 } \
168 \
169 STDMETHODIMP_(ULONG) classname::AddRef() \
170 { \
171 wxLogAddRef(wxT(#classname), m_cRef); \
172 \
173 return ++m_cRef; \
174 } \
175 \
176 STDMETHODIMP_(ULONG) classname::Release() \
177 { \
178 wxLogRelease(wxT(#classname), m_cRef); \
179 \
180 if ( --m_cRef == wxAutoULong(0) ) { \
181 delete this; \
182 return 0; \
183 } \
184 else \
185 return m_cRef; \
186 }
187
188 // ============================================================================
189 // Debugging support
190 // ============================================================================
191
192 // VZ: I don't know it's not done for compilers other than VC++ but I leave it
193 // as is. Please note, though, that tracing OLE interface calls may be
194 // incredibly useful when debugging OLE programs.
195 #if defined(__WXDEBUG__) && (( defined(__VISUALC__) && (__VISUALC__ >= 1000) ))
196 // ----------------------------------------------------------------------------
197 // All OLE specific log functions have DebugTrace level (as LogTrace)
198 // ----------------------------------------------------------------------------
199
200 // tries to translate riid into a symbolic name, if possible
201 WXDLLIMPEXP_CORE void wxLogQueryInterface(const wxChar *szInterface, REFIID riid);
202
203 // these functions print out the new value of reference counter
204 WXDLLIMPEXP_CORE void wxLogAddRef (const wxChar *szInterface, ULONG cRef);
205 WXDLLIMPEXP_CORE void wxLogRelease(const wxChar *szInterface, ULONG cRef);
206
207 #else //!__WXDEBUG__
208 #define wxLogQueryInterface(szInterface, riid)
209 #define wxLogAddRef(szInterface, cRef)
210 #define wxLogRelease(szInterface, cRef)
211 #endif //__WXDEBUG__
212
213 // wrapper around BSTR type (by Vadim Zeitlin)
214
215 class WXDLLIMPEXP_CORE wxBasicString
216 {
217 public:
218 // ctors & dtor
219 wxBasicString(const wxString& str);
220 wxBasicString(const wxBasicString& bstr);
221 ~wxBasicString();
222
223 wxBasicString& operator=(const wxBasicString& bstr);
224
225 // accessors
226 // just get the string
227 operator BSTR() const { return m_bstrBuf; }
228 // retrieve a copy of our string - caller must SysFreeString() it later!
229 BSTR Get() const { return SysAllocString(m_bstrBuf); }
230
231 private:
232 // actual string
233 BSTR m_bstrBuf;
234 };
235
236 #if wxUSE_VARIANT
237 // Convert variants
238 class WXDLLIMPEXP_FWD_BASE wxVariant;
239
240 // wrapper for CURRENCY type used in VARIANT (VARIANT.vt == VT_CY)
241 class WXDLLIMPEXP_CORE wxVariantDataCurrency : public wxVariantData
242 {
243 public:
244 wxVariantDataCurrency() { VarCyFromR8(0.0, &m_value); }
245 wxVariantDataCurrency(CURRENCY value) { m_value = value; }
246
247 CURRENCY GetValue() const { return m_value; }
248 void SetValue(CURRENCY value) { m_value = value; }
249
250 virtual bool Eq(wxVariantData& data) const;
251
252 #if wxUSE_STD_IOSTREAM
253 virtual bool Write(wxSTD ostream& str) const;
254 #endif
255 virtual bool Write(wxString& str) const;
256
257 wxVariantData* Clone() const { return new wxVariantDataCurrency(m_value); }
258 virtual wxString GetType() const { return wxS("currency"); }
259
260 DECLARE_WXANY_CONVERSION()
261
262 private:
263 CURRENCY m_value;
264 };
265
266
267 // wrapper for SCODE type used in VARIANT (VARIANT.vt == VT_ERROR)
268 class WXDLLIMPEXP_CORE wxVariantDataErrorCode : public wxVariantData
269 {
270 public:
271 wxVariantDataErrorCode(SCODE value = S_OK) { m_value = value; }
272
273 SCODE GetValue() const { return m_value; }
274 void SetValue(SCODE value) { m_value = value; }
275
276 virtual bool Eq(wxVariantData& data) const;
277
278 #if wxUSE_STD_IOSTREAM
279 virtual bool Write(wxSTD ostream& str) const;
280 #endif
281 virtual bool Write(wxString& str) const;
282
283 wxVariantData* Clone() const { return new wxVariantDataErrorCode(m_value); }
284 virtual wxString GetType() const { return wxS("errorcode"); }
285
286 DECLARE_WXANY_CONVERSION()
287
288 private:
289 SCODE m_value;
290 };
291
292 // wrapper for SAFEARRAY, used for passing multidimensional arrays in wxVariant
293 class WXDLLIMPEXP_CORE wxVariantDataSafeArray : public wxVariantData
294 {
295 public:
296 wxEXPLICIT wxVariantDataSafeArray(SAFEARRAY* value = NULL)
297 {
298 m_value = value;
299 }
300
301 SAFEARRAY* GetValue() const { return m_value; }
302 void SetValue(SAFEARRAY* value) { m_value = value; }
303
304 virtual bool Eq(wxVariantData& data) const;
305
306 #if wxUSE_STD_IOSTREAM
307 virtual bool Write(wxSTD ostream& str) const;
308 #endif
309 virtual bool Write(wxString& str) const;
310
311 wxVariantData* Clone() const { return new wxVariantDataSafeArray(m_value); }
312 virtual wxString GetType() const { return wxS("safearray"); }
313
314 DECLARE_WXANY_CONVERSION()
315
316 private:
317 SAFEARRAY* m_value;
318 };
319
320
321 WXDLLIMPEXP_CORE bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant);
322 WXDLLIMPEXP_CORE bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant);
323 #endif // wxUSE_VARIANT
324
325 // Convert string to Unicode
326 WXDLLIMPEXP_CORE BSTR wxConvertStringToOle(const wxString& str);
327
328 // Convert string from BSTR to wxString
329 WXDLLIMPEXP_CORE wxString wxConvertStringFromOle(BSTR bStr);
330
331 #else // !wxUSE_OLE
332
333 // ----------------------------------------------------------------------------
334 // stub functions to avoid #if wxUSE_OLE in the main code
335 // ----------------------------------------------------------------------------
336
337 inline bool wxOleInitialize() { return false; }
338 inline void wxOleUninitialize() { }
339
340 #endif // wxUSE_OLE/!wxUSE_OLE
341
342 #endif //_WX_OLEUTILS_H