substitute WXDLLEXPORT with WXDLLIMPEXP_CORE and WXDLLEXPORT_DATA with WXDLLIMPEXP_DA...
[wxWidgets.git] / include / wx / msw / ole / oleutils.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: 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 // we need to initialize OLE library
40 #ifdef __WXWINCE__
41 if ( FAILED(::CoInitializeEx(NULL, COINIT_MULTITHREADED)) )
42 #else
43 if ( FAILED(::OleInitialize(NULL)) )
44 #endif
45 {
46 wxLogError(_("Cannot initialize OLE"));
47
48 return false;
49 }
50
51 return true;
52 }
53
54 inline void wxOleUninitialize()
55 {
56 #ifdef __WXWINCE__
57 ::CoUninitialize();
58 #else
59 ::OleUninitialize();
60 #endif
61 }
62
63 // ----------------------------------------------------------------------------
64 // misc helper functions/macros
65 // ----------------------------------------------------------------------------
66
67 // release the interface pointer (if !NULL)
68 inline void ReleaseInterface(IUnknown *pIUnk)
69 {
70 if ( pIUnk != NULL )
71 pIUnk->Release();
72 }
73
74 // release the interface pointer (if !NULL) and make it NULL
75 #define RELEASE_AND_NULL(p) if ( (p) != NULL ) { p->Release(); p = NULL; };
76
77 // return true if the iid is in the array
78 extern bool IsIidFromList(REFIID riid, const IID *aIids[], size_t nCount);
79
80 // ============================================================================
81 // IUnknown implementation helpers
82 // ============================================================================
83
84 /*
85 The most dumb implementation of IUnknown methods. We don't support
86 aggregation nor containment, but for 99% of cases this simple
87 implementation is quite enough.
88
89 Usage is trivial: here is all you should have
90 1) DECLARE_IUNKNOWN_METHODS in your (IUnknown derived!) class declaration
91 2) BEGIN/END_IID_TABLE with ADD_IID in between for all interfaces you
92 support (at least all for which you intent to return 'this' from QI,
93 i.e. you should derive from IFoo if you have ADD_IID(Foo)) somewhere else
94 3) IMPLEMENT_IUNKNOWN_METHODS somewhere also
95
96 These macros are quite simple: AddRef and Release are trivial and QI does
97 lookup in a static member array of IIDs and returns 'this' if it founds
98 the requested interface in it or E_NOINTERFACE if not.
99 */
100
101 /*
102 wxAutoULong: this class is used for automatically initalising m_cRef to 0
103 */
104 class wxAutoULong
105 {
106 public:
107 wxAutoULong(ULONG value = 0) : m_Value(value) { }
108
109 operator ULONG&() { return m_Value; }
110 ULONG& operator=(ULONG value) { m_Value = value; return m_Value; }
111
112 wxAutoULong& operator++() { ++m_Value; return *this; }
113 const wxAutoULong operator++( int ) { wxAutoULong temp = *this; ++m_Value; return temp; }
114
115 wxAutoULong& operator--() { --m_Value; return *this; }
116 const wxAutoULong operator--( int ) { wxAutoULong temp = *this; --m_Value; return temp; }
117
118 private:
119 ULONG m_Value;
120 };
121
122 // declare the methods and the member variable containing reference count
123 // you must also define the ms_aIids array somewhere with BEGIN_IID_TABLE
124 // and friends (see below)
125
126 #define DECLARE_IUNKNOWN_METHODS \
127 public: \
128 STDMETHODIMP QueryInterface(REFIID, void **); \
129 STDMETHODIMP_(ULONG) AddRef(); \
130 STDMETHODIMP_(ULONG) Release(); \
131 private: \
132 static const IID *ms_aIids[]; \
133 wxAutoULong m_cRef
134
135 // macros for declaring supported interfaces
136 // NB: you should write ADD_INTERFACE(Foo) and not ADD_INTERFACE(IID_IFoo)!
137 #define BEGIN_IID_TABLE(cname) const IID *cname::ms_aIids[] = {
138 #define ADD_IID(iid) &IID_I##iid,
139 #define END_IID_TABLE }
140
141 // implementation is as straightforward as possible
142 // Parameter: classname - the name of the class
143 #define IMPLEMENT_IUNKNOWN_METHODS(classname) \
144 STDMETHODIMP classname::QueryInterface(REFIID riid, void **ppv) \
145 { \
146 wxLogQueryInterface(_T(#classname), riid); \
147 \
148 if ( IsIidFromList(riid, ms_aIids, WXSIZEOF(ms_aIids)) ) { \
149 *ppv = this; \
150 AddRef(); \
151 \
152 return S_OK; \
153 } \
154 else { \
155 *ppv = NULL; \
156 \
157 return (HRESULT) E_NOINTERFACE; \
158 } \
159 } \
160 \
161 STDMETHODIMP_(ULONG) classname::AddRef() \
162 { \
163 wxLogAddRef(_T(#classname), m_cRef); \
164 \
165 return ++m_cRef; \
166 } \
167 \
168 STDMETHODIMP_(ULONG) classname::Release() \
169 { \
170 wxLogRelease(_T(#classname), m_cRef); \
171 \
172 if ( --m_cRef == wxAutoULong(0) ) { \
173 delete this; \
174 return 0; \
175 } \
176 else \
177 return m_cRef; \
178 }
179
180 // ============================================================================
181 // Debugging support
182 // ============================================================================
183
184 // VZ: I don't know it's not done for compilers other than VC++ but I leave it
185 // as is. Please note, though, that tracing OLE interface calls may be
186 // incredibly useful when debugging OLE programs.
187 #if defined(__WXDEBUG__) && ( ( defined(__VISUALC__) && (__VISUALC__ >= 1000) ) || defined(__MWERKS__) )
188 // ----------------------------------------------------------------------------
189 // All OLE specific log functions have DebugTrace level (as LogTrace)
190 // ----------------------------------------------------------------------------
191
192 // tries to translate riid into a symbolic name, if possible
193 void wxLogQueryInterface(const wxChar *szInterface, REFIID riid);
194
195 // these functions print out the new value of reference counter
196 void wxLogAddRef (const wxChar *szInterface, ULONG cRef);
197 void wxLogRelease(const wxChar *szInterface, ULONG cRef);
198
199 #else //!__WXDEBUG__
200 #define wxLogQueryInterface(szInterface, riid)
201 #define wxLogAddRef(szInterface, cRef)
202 #define wxLogRelease(szInterface, cRef)
203 #endif //__WXDEBUG__
204
205 // wrapper around BSTR type (by Vadim Zeitlin)
206
207 class WXDLLIMPEXP_CORE wxBasicString
208 {
209 public:
210 // ctors & dtor
211 wxBasicString(const wxString& str);
212 wxBasicString(const wxBasicString& bstr);
213 ~wxBasicString();
214
215 wxBasicString& operator=(const wxBasicString& bstr);
216
217 // accessors
218 // just get the string
219 operator BSTR() const { return m_bstrBuf; }
220 // retrieve a copy of our string - caller must SysFreeString() it later!
221 BSTR Get() const { return SysAllocString(m_bstrBuf); }
222
223 private:
224 // actual string
225 BSTR m_bstrBuf;
226 };
227
228 #if wxUSE_VARIANT
229 // Convert variants
230 class WXDLLIMPEXP_FWD_BASE wxVariant;
231
232 WXDLLIMPEXP_CORE bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant);
233 WXDLLIMPEXP_CORE bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant);
234 #endif // wxUSE_VARIANT
235
236 // Convert string to Unicode
237 WXDLLIMPEXP_CORE BSTR wxConvertStringToOle(const wxString& str);
238
239 // Convert string from BSTR to wxString
240 WXDLLIMPEXP_CORE wxString wxConvertStringFromOle(BSTR bStr);
241
242 #else // !wxUSE_OLE
243
244 // ----------------------------------------------------------------------------
245 // stub functions to avoid #if wxUSE_OLE in the main code
246 // ----------------------------------------------------------------------------
247
248 inline bool wxOleInitialize() { return false; }
249 inline void wxOleUninitialize() { }
250
251 #endif // wxUSE_OLE/!wxUSE_OLE
252
253 #endif //_WX_OLEUTILS_H