oleutils.h 14 KB

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