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