1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/msw/ole/oleutils.h
3 // Purpose: OLE helper routines, OLE debugging support &c
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_OLEUTILS_H
12 #define _WX_OLEUTILS_H
18 // ole2.h includes windows.h, so include wrapwin.h first
19 #include "wx/msw/wrapwin.h"
20 // get IUnknown, REFIID &c
25 // ============================================================================
26 // General purpose functions and macros
27 // ============================================================================
29 // ----------------------------------------------------------------------------
30 // initialize/cleanup OLE
31 // ----------------------------------------------------------------------------
33 // call OleInitialize() or CoInitialize[Ex]() depending on the platform
35 // return true if ok, false otherwise
36 inline bool wxOleInitialize()
40 hr
= ::CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
42 hr
= ::OleInitialize(NULL
);
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
) )
52 wxLogError(_("Cannot initialize OLE"));
60 inline void wxOleUninitialize()
69 // ----------------------------------------------------------------------------
70 // misc helper functions/macros
71 // ----------------------------------------------------------------------------
73 // release the interface pointer (if !NULL)
74 inline void ReleaseInterface(IUnknown
*pIUnk
)
80 // release the interface pointer (if !NULL) and make it NULL
81 #define RELEASE_AND_NULL(p) if ( (p) != NULL ) { p->Release(); p = NULL; };
83 // return true if the iid is in the array
84 extern WXDLLIMPEXP_CORE
bool IsIidFromList(REFIID riid
, const IID
*aIids
[], size_t nCount
);
86 // ============================================================================
87 // IUnknown implementation helpers
88 // ============================================================================
91 The most dumb implementation of IUnknown methods. We don't support
92 aggregation nor containment, but for 99% of cases this simple
93 implementation is quite enough.
95 Usage is trivial: here is all you should have
96 1) DECLARE_IUNKNOWN_METHODS in your (IUnknown derived!) class declaration
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
100 3) IMPLEMENT_IUNKNOWN_METHODS somewhere also
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.
108 wxAutoULong: this class is used for automatically initalising m_cRef to 0
113 wxAutoULong(ULONG value
= 0) : m_Value(value
) { }
115 operator ULONG
&() { return m_Value
; }
116 ULONG
& operator=(ULONG value
) { m_Value
= value
; return m_Value
; }
118 wxAutoULong
& operator++() { ++m_Value
; return *this; }
119 const wxAutoULong
operator++( int ) { wxAutoULong temp
= *this; ++m_Value
; return temp
; }
121 wxAutoULong
& operator--() { --m_Value
; return *this; }
122 const wxAutoULong
operator--( int ) { wxAutoULong temp
= *this; --m_Value
; return temp
; }
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)
132 #define DECLARE_IUNKNOWN_METHODS \
134 STDMETHODIMP QueryInterface(REFIID, void **); \
135 STDMETHODIMP_(ULONG) AddRef(); \
136 STDMETHODIMP_(ULONG) Release(); \
138 static const IID *ms_aIids[]; \
141 // macros for declaring supported interfaces
142 // NB: ADD_IID prepends IID_I whereas ADD_RAW_IID does not
143 #define BEGIN_IID_TABLE(cname) const IID *cname::ms_aIids[] = {
144 #define ADD_IID(iid) &IID_I##iid,
145 #define ADD_RAW_IID(iid) &iid,
146 #define END_IID_TABLE }
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) \
153 wxLogQueryInterface(wxT(#classname), riid); \
155 if ( IsIidFromList(riid, ms_aIids, WXSIZEOF(ms_aIids)) ) { \
164 return (HRESULT) E_NOINTERFACE; \
168 STDMETHODIMP_(ULONG) classname::AddRef() \
170 wxLogAddRef(wxT(#classname), m_cRef); \
175 STDMETHODIMP_(ULONG) classname::Release() \
177 wxLogRelease(wxT(#classname), m_cRef); \
179 if ( --m_cRef == wxAutoULong(0) ) { \
187 // ============================================================================
189 // ============================================================================
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.
194 #if defined(__WXDEBUG__) && (( defined(__VISUALC__) && (__VISUALC__ >= 1000) ))
195 // ----------------------------------------------------------------------------
196 // All OLE specific log functions have DebugTrace level (as LogTrace)
197 // ----------------------------------------------------------------------------
199 // tries to translate riid into a symbolic name, if possible
200 WXDLLIMPEXP_CORE
void wxLogQueryInterface(const wxChar
*szInterface
, REFIID riid
);
202 // these functions print out the new value of reference counter
203 WXDLLIMPEXP_CORE
void wxLogAddRef (const wxChar
*szInterface
, ULONG cRef
);
204 WXDLLIMPEXP_CORE
void wxLogRelease(const wxChar
*szInterface
, ULONG cRef
);
207 #define wxLogQueryInterface(szInterface, riid)
208 #define wxLogAddRef(szInterface, cRef)
209 #define wxLogRelease(szInterface, cRef)
212 // wrapper around BSTR type (by Vadim Zeitlin)
214 class WXDLLIMPEXP_CORE wxBasicString
218 wxBasicString(const wxString
& str
);
219 wxBasicString(const wxBasicString
& bstr
);
222 wxBasicString
& operator=(const wxBasicString
& bstr
);
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
); }
237 class WXDLLIMPEXP_FWD_BASE wxVariant
;
239 // wrapper for CURRENCY type used in VARIANT (VARIANT.vt == VT_CY)
240 class WXDLLIMPEXP_CORE wxVariantDataCurrency
: public wxVariantData
243 wxVariantDataCurrency() { VarCyFromR8(0.0, &m_value
); }
244 wxVariantDataCurrency(CURRENCY value
) { m_value
= value
; }
246 CURRENCY
GetValue() const { return m_value
; }
247 void SetValue(CURRENCY value
) { m_value
= value
; }
249 virtual bool Eq(wxVariantData
& data
) const;
251 #if wxUSE_STD_IOSTREAM
252 virtual bool Write(wxSTD ostream
& str
) const;
254 virtual bool Write(wxString
& str
) const;
256 wxVariantData
* Clone() const { return new wxVariantDataCurrency(m_value
); }
257 virtual wxString
GetType() const { return wxS("currency"); }
259 DECLARE_WXANY_CONVERSION()
266 // wrapper for SCODE type used in VARIANT (VARIANT.vt == VT_ERROR)
267 class WXDLLIMPEXP_CORE wxVariantDataErrorCode
: public wxVariantData
270 wxVariantDataErrorCode(SCODE value
= S_OK
) { m_value
= value
; }
272 SCODE
GetValue() const { return m_value
; }
273 void SetValue(SCODE value
) { m_value
= value
; }
275 virtual bool Eq(wxVariantData
& data
) const;
277 #if wxUSE_STD_IOSTREAM
278 virtual bool Write(wxSTD ostream
& str
) const;
280 virtual bool Write(wxString
& str
) const;
282 wxVariantData
* Clone() const { return new wxVariantDataErrorCode(m_value
); }
283 virtual wxString
GetType() const { return wxS("errorcode"); }
285 DECLARE_WXANY_CONVERSION()
291 // wrapper for SAFEARRAY, used for passing multidimensional arrays in wxVariant
292 class WXDLLIMPEXP_CORE wxVariantDataSafeArray
: public wxVariantData
295 wxEXPLICIT
wxVariantDataSafeArray(SAFEARRAY
* value
= NULL
)
300 SAFEARRAY
* GetValue() const { return m_value
; }
301 void SetValue(SAFEARRAY
* value
) { m_value
= value
; }
303 virtual bool Eq(wxVariantData
& data
) const;
305 #if wxUSE_STD_IOSTREAM
306 virtual bool Write(wxSTD ostream
& str
) const;
308 virtual bool Write(wxString
& str
) const;
310 wxVariantData
* Clone() const { return new wxVariantDataSafeArray(m_value
); }
311 virtual wxString
GetType() const { return wxS("safearray"); }
313 DECLARE_WXANY_CONVERSION()
320 WXDLLIMPEXP_CORE
bool wxConvertVariantToOle(const wxVariant
& variant
, VARIANTARG
& oleVariant
);
321 WXDLLIMPEXP_CORE
bool wxConvertOleToVariant(const VARIANTARG
& oleVariant
, wxVariant
& variant
);
322 #endif // wxUSE_VARIANT
324 // Convert string to Unicode
325 WXDLLIMPEXP_CORE BSTR
wxConvertStringToOle(const wxString
& str
);
327 // Convert string from BSTR to wxString
328 WXDLLIMPEXP_CORE wxString
wxConvertStringFromOle(BSTR bStr
);
332 // ----------------------------------------------------------------------------
333 // stub functions to avoid #if wxUSE_OLE in the main code
334 // ----------------------------------------------------------------------------
336 inline bool wxOleInitialize() { return false; }
337 inline void wxOleUninitialize() { }
339 #endif // wxUSE_OLE/!wxUSE_OLE
341 #endif //_WX_OLEUTILS_H