compilation fixes for OpenWatcom
[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 #ifdef __GNUG__
16 #pragma interface "oleutils.h"
17 #endif
18
19 #include "wx/defs.h"
20
21 // get IUnknown, REFIID &c
22 #include <ole2.h>
23
24 // ============================================================================
25 // General purpose functions and macros
26 // ============================================================================
27
28 // ----------------------------------------------------------------------------
29 // misc helper functions/macros
30 // ----------------------------------------------------------------------------
31
32 // release the interface pointer (if !NULL)
33 inline void ReleaseInterface(IUnknown *pIUnk)
34 {
35 if ( pIUnk != NULL )
36 pIUnk->Release();
37 }
38
39 // release the interface pointer (if !NULL) and make it NULL
40 #define RELEASE_AND_NULL(p) if ( (p) != NULL ) { p->Release(); p = NULL; };
41
42 // return TRUE if the iid is in the array
43 extern bool IsIidFromList(REFIID riid, const IID *aIids[], size_t nCount);
44
45 // ============================================================================
46 // IUnknown implementation helpers
47 // ============================================================================
48
49 /*
50 The most dumb implementation of IUnknown methods. We don't support
51 aggregation nor containment, but for 99% of cases this simple
52 implementation is quite enough.
53
54 Usage is trivial: here is all you should have
55 1) DECLARE_IUNKNOWN_METHODS in your (IUnknown derived!) class declaration
56 2) BEGIN/END_IID_TABLE with ADD_IID in between for all interfaces you
57 support (at least all for which you intent to return 'this' from QI,
58 i.e. you should derive from IFoo if you have ADD_IID(Foo)) somewhere else
59 3) IMPLEMENT_IUNKNOWN_METHODS somewhere also
60
61 These macros are quite simple: AddRef and Release are trivial and QI does
62 lookup in a static member array of IIDs and returns 'this' if it founds
63 the requested interface in it or E_NOINTERFACE if not.
64 */
65
66 /*
67 wxAutoULong: this class is used for automatically initalising m_cRef to 0
68 */
69 class wxAutoULong
70 {
71 public:
72 wxAutoULong(ULONG value = 0) : m_Value(value) { }
73
74 operator ULONG&() { return m_Value; }
75 ULONG& operator=(ULONG value) { return m_Value = value; }
76
77 wxAutoULong& operator++() { ++m_Value; return *this; }
78 const wxAutoULong operator++( int ) { wxAutoULong temp = *this; ++m_Value; return temp; }
79
80 wxAutoULong& operator--() { --m_Value; return *this; }
81 const wxAutoULong operator--( int ) { wxAutoULong temp = *this; --m_Value; return temp; }
82
83 private:
84 ULONG m_Value;
85 };
86
87 // declare the methods and the member variable containing reference count
88 // you must also define the ms_aIids array somewhere with BEGIN_IID_TABLE
89 // and friends (see below)
90
91 #define DECLARE_IUNKNOWN_METHODS \
92 public: \
93 STDMETHODIMP QueryInterface(REFIID, void **); \
94 STDMETHODIMP_(ULONG) AddRef(); \
95 STDMETHODIMP_(ULONG) Release(); \
96 private: \
97 static const IID *ms_aIids[]; \
98 wxAutoULong m_cRef
99
100 // macros for declaring supported interfaces
101 // NB: you should write ADD_INTERFACE(Foo) and not ADD_INTERFACE(IID_IFoo)!
102 #define BEGIN_IID_TABLE(cname) const IID *cname::ms_aIids[] = {
103 #define ADD_IID(iid) &IID_I##iid,
104 #define END_IID_TABLE }
105
106 // implementation is as straightforward as possible
107 // Parameter: classname - the name of the class
108 #define IMPLEMENT_IUNKNOWN_METHODS(classname) \
109 STDMETHODIMP classname::QueryInterface(REFIID riid, void **ppv) \
110 { \
111 wxLogQueryInterface(_T(#classname), riid); \
112 \
113 if ( IsIidFromList(riid, ms_aIids, WXSIZEOF(ms_aIids)) ) { \
114 *ppv = this; \
115 AddRef(); \
116 \
117 return S_OK; \
118 } \
119 else { \
120 *ppv = NULL; \
121 \
122 return (HRESULT) E_NOINTERFACE; \
123 } \
124 } \
125 \
126 STDMETHODIMP_(ULONG) classname::AddRef() \
127 { \
128 wxLogAddRef(_T(#classname), m_cRef); \
129 \
130 return ++m_cRef; \
131 } \
132 \
133 STDMETHODIMP_(ULONG) classname::Release() \
134 { \
135 wxLogRelease(_T(#classname), m_cRef); \
136 \
137 if ( --m_cRef == 0 ) { \
138 delete this; \
139 return 0; \
140 } \
141 else \
142 return m_cRef; \
143 }
144
145 // ============================================================================
146 // Debugging support
147 // ============================================================================
148
149 // VZ: I don't know it's not done for compilers other than VC++ but I leave it
150 // as is. Please note, though, that tracing OLE interface calls may be
151 // incredibly useful when debugging OLE programs.
152 #if defined(__WXDEBUG__) && ( ( defined(__VISUALC__) && (__VISUALC__ >= 1000) ) || defined(__MWERKS__) )
153 // ----------------------------------------------------------------------------
154 // All OLE specific log functions have DebugTrace level (as LogTrace)
155 // ----------------------------------------------------------------------------
156
157 // tries to translate riid into a symbolic name, if possible
158 void wxLogQueryInterface(const wxChar *szInterface, REFIID riid);
159
160 // these functions print out the new value of reference counter
161 void wxLogAddRef (const wxChar *szInterface, ULONG cRef);
162 void wxLogRelease(const wxChar *szInterface, ULONG cRef);
163
164 #else //!WXDEBUG
165 #define wxLogQueryInterface(szInterface, riid)
166 #define wxLogAddRef(szInterface, cRef)
167 #define wxLogRelease(szInterface, cRef)
168 #endif //WXDEBUG
169
170 #endif //_WX_OLEUTILS_H
171