]> git.saurik.com Git - wxWidgets.git/blame - include/wx/msw/ole/oleutils.h
Fix fatal bug with deleting the old contents in wxScopedArray::reset().
[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
KB
6// Created: 19.02.1998
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
65571936 9// Licence: wxWindows licence
bbf1f0e5
KB
10///////////////////////////////////////////////////////////////////////////////
11
bbcdf8bc
JS
12#ifndef _WX_OLEUTILS_H
13#define _WX_OLEUTILS_H
bbf1f0e5 14
e5ad6961 15#include "wx/defs.h"
82df67d9 16
360ae33f
VZ
17#if wxUSE_OLE
18
9dbe0022
MW
19// ole2.h includes windows.h, so include wrapwin.h first
20#include "wx/msw/wrapwin.h"
a7b4607f
VZ
21// get IUnknown, REFIID &c
22#include <ole2.h>
eaac61c3 23#include "wx/intl.h"
c493691d 24#include "wx/log.h"
82df67d9 25
bbf1f0e5
KB
26// ============================================================================
27// General purpose functions and macros
28// ============================================================================
29
360ae33f
VZ
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
37inline bool wxOleInitialize()
38{
35f82b01 39 HRESULT
360ae33f 40#ifdef __WXWINCE__
35f82b01 41 hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
360ae33f 42#else
35f82b01 43 hr = ::OleInitialize(NULL);
360ae33f 44#endif
35f82b01
VZ
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) )
360ae33f
VZ
52 {
53 wxLogError(_("Cannot initialize OLE"));
54
55 return false;
56 }
57
58 return true;
59}
60
61inline void wxOleUninitialize()
62{
63#ifdef __WXWINCE__
64 ::CoUninitialize();
65#else
66 ::OleUninitialize();
67#endif
68}
69
bbf1f0e5
KB
70// ----------------------------------------------------------------------------
71// misc helper functions/macros
72// ----------------------------------------------------------------------------
73
74// release the interface pointer (if !NULL)
75inline 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
0a0e6a5b 84// return true if the iid is in the array
d0400222 85WXDLLIMPEXP_CORE extern bool IsIidFromList(REFIID riid, const IID *aIids[], size_t nCount);
bbf1f0e5
KB
86
87// ============================================================================
88// IUnknown implementation helpers
89// ============================================================================
90
91/*
3f4a0c5b 92 The most dumb implementation of IUnknown methods. We don't support
bbf1f0e5
KB
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
82df67d9 97 1) DECLARE_IUNKNOWN_METHODS in your (IUnknown derived!) class declaration
bbf1f0e5
KB
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
82df67d9 101 3) IMPLEMENT_IUNKNOWN_METHODS somewhere also
bbf1f0e5
KB
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
82df67d9
VZ
108/*
109 wxAutoULong: this class is used for automatically initalising m_cRef to 0
110*/
111class wxAutoULong
112{
113public:
114 wxAutoULong(ULONG value = 0) : m_Value(value) { }
115
116 operator ULONG&() { return m_Value; }
81833075 117 ULONG& operator=(ULONG value) { m_Value = value; return m_Value; }
0a0e6a5b 118
018f2884
VZ
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; }
82df67d9
VZ
124
125private:
126 ULONG m_Value;
127};
128
bbf1f0e5
KB
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)
82df67d9 132
bbf1f0e5
KB
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[]; \
82df67d9 140 wxAutoULong m_cRef
bbf1f0e5
KB
141
142// macros for declaring supported interfaces
b8800bfe 143// NB: ADD_IID prepends IID_I whereas ADD_RAW_IID does not
bbf1f0e5
KB
144#define BEGIN_IID_TABLE(cname) const IID *cname::ms_aIids[] = {
145#define ADD_IID(iid) &IID_I##iid,
b8800bfe 146#define ADD_RAW_IID(iid) &##iid,
bbf1f0e5
KB
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 { \
9a83f860 154 wxLogQueryInterface(wxT(#classname), riid); \
bbf1f0e5 155 \
f6bcfd97 156 if ( IsIidFromList(riid, ms_aIids, WXSIZEOF(ms_aIids)) ) { \
bbf1f0e5
KB
157 *ppv = this; \
158 AddRef(); \
159 \
160 return S_OK; \
161 } \
162 else { \
163 *ppv = NULL; \
164 \
f6bcfd97 165 return (HRESULT) E_NOINTERFACE; \
bbf1f0e5
KB
166 } \
167 } \
168 \
169 STDMETHODIMP_(ULONG) classname::AddRef() \
170 { \
9a83f860 171 wxLogAddRef(wxT(#classname), m_cRef); \
bbf1f0e5
KB
172 \
173 return ++m_cRef; \
174 } \
175 \
176 STDMETHODIMP_(ULONG) classname::Release() \
177 { \
9a83f860 178 wxLogRelease(wxT(#classname), m_cRef); \
bbf1f0e5 179 \
56689e1b 180 if ( --m_cRef == wxAutoULong(0) ) { \
bbf1f0e5
KB
181 delete this; \
182 return 0; \
183 } \
184 else \
185 return m_cRef; \
186 }
187
188// ============================================================================
189// Debugging support
190// ============================================================================
191
3f4a0c5b
VZ
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.
ba14d986 195#if defined(__WXDEBUG__) && ( ( defined(__VISUALC__) && (__VISUALC__ >= 1000) ) || defined(__MWERKS__) )
bbf1f0e5
KB
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
d0400222 201WXDLLIMPEXP_CORE void wxLogQueryInterface(const wxChar *szInterface, REFIID riid);
bbf1f0e5
KB
202
203// these functions print out the new value of reference counter
d0400222
SL
204WXDLLIMPEXP_CORE void wxLogAddRef (const wxChar *szInterface, ULONG cRef);
205WXDLLIMPEXP_CORE void wxLogRelease(const wxChar *szInterface, ULONG cRef);
bbf1f0e5 206
e755eb67 207#else //!__WXDEBUG__
bbf1f0e5
KB
208 #define wxLogQueryInterface(szInterface, riid)
209 #define wxLogAddRef(szInterface, cRef)
210 #define wxLogRelease(szInterface, cRef)
e755eb67 211#endif //__WXDEBUG__
bbf1f0e5 212
45a959a3
JS
213// wrapper around BSTR type (by Vadim Zeitlin)
214
53a2db12 215class WXDLLIMPEXP_CORE wxBasicString
45a959a3
JS
216{
217public:
218 // ctors & dtor
45a959a3 219 wxBasicString(const wxString& str);
a518e508 220 wxBasicString(const wxBasicString& bstr);
45a959a3 221 ~wxBasicString();
0a0e6a5b 222
a518e508 223 wxBasicString& operator=(const wxBasicString& bstr);
0a0e6a5b 224
45a959a3 225 // accessors
a518e508
VZ
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); }
0a0e6a5b 230
45a959a3 231private:
a518e508
VZ
232 // actual string
233 BSTR m_bstrBuf;
45a959a3
JS
234};
235
ca5c6ac3 236#if wxUSE_VARIANT
45a959a3 237// Convert variants
b5dbe15d 238class WXDLLIMPEXP_FWD_BASE wxVariant;
45a959a3 239
53a2db12
FM
240WXDLLIMPEXP_CORE bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant);
241WXDLLIMPEXP_CORE bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant);
ca5c6ac3 242#endif // wxUSE_VARIANT
45a959a3
JS
243
244// Convert string to Unicode
53a2db12 245WXDLLIMPEXP_CORE BSTR wxConvertStringToOle(const wxString& str);
45a959a3
JS
246
247// Convert string from BSTR to wxString
53a2db12 248WXDLLIMPEXP_CORE wxString wxConvertStringFromOle(BSTR bStr);
45a959a3 249
360ae33f
VZ
250#else // !wxUSE_OLE
251
252// ----------------------------------------------------------------------------
253// stub functions to avoid #if wxUSE_OLE in the main code
254// ----------------------------------------------------------------------------
255
256inline bool wxOleInitialize() { return false; }
257inline void wxOleUninitialize() { }
258
259#endif // wxUSE_OLE/!wxUSE_OLE
45a959a3 260
3f4a0c5b 261#endif //_WX_OLEUTILS_H