oleutils.h 13 KB

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