comptr.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/msw/private/comptr.h
  3. // Purpose: Smart pointer for COM interfaces.
  4. // Author: PB
  5. // Created: 2012-04-16
  6. // Copyright: (c) 2012 wxWidgets team
  7. // Licence: wxWindows licence
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #ifndef _WX_MSW_PRIVATE_COMPTR_H_
  10. #define _WX_MSW_PRIVATE_COMPTR_H_
  11. // ----------------------------------------------------------------------------
  12. // wxCOMPtr: A minimalistic smart pointer for use with COM interfaces.
  13. // ----------------------------------------------------------------------------
  14. template <class T>
  15. class wxCOMPtr
  16. {
  17. public:
  18. typedef T element_type;
  19. wxCOMPtr()
  20. : m_ptr(NULL)
  21. {
  22. }
  23. wxEXPLICIT wxCOMPtr(T* ptr)
  24. : m_ptr(ptr)
  25. {
  26. if ( m_ptr )
  27. m_ptr->AddRef();
  28. }
  29. wxCOMPtr(const wxCOMPtr& ptr)
  30. : m_ptr(ptr.get())
  31. {
  32. if ( m_ptr )
  33. m_ptr->AddRef();
  34. }
  35. ~wxCOMPtr()
  36. {
  37. if ( m_ptr )
  38. m_ptr->Release();
  39. }
  40. void reset(T* ptr = NULL)
  41. {
  42. if ( m_ptr != ptr)
  43. {
  44. if ( ptr )
  45. ptr->AddRef();
  46. if ( m_ptr )
  47. m_ptr->Release();
  48. m_ptr = ptr;
  49. }
  50. }
  51. wxCOMPtr& operator=(const wxCOMPtr& ptr)
  52. {
  53. reset(ptr.get());
  54. return *this;
  55. }
  56. wxCOMPtr& operator=(T* ptr)
  57. {
  58. reset(ptr);
  59. return *this;
  60. }
  61. operator T*() const
  62. {
  63. return m_ptr;
  64. }
  65. T& operator*() const
  66. {
  67. return *m_ptr;
  68. }
  69. T* operator->() const
  70. {
  71. return m_ptr;
  72. }
  73. // It would be better to forbid direct access completely but we do need
  74. // for QueryInterface() and similar functions, so provide it but it can
  75. // only be used to initialize the pointer, not to modify an existing one.
  76. T** operator&()
  77. {
  78. wxASSERT_MSG(!m_ptr,
  79. wxS("Can't get direct access to initialized pointer"));
  80. return &m_ptr;
  81. }
  82. T* get() const
  83. {
  84. return m_ptr;
  85. }
  86. bool operator<(T* ptr) const
  87. {
  88. return get() < ptr;
  89. }
  90. private:
  91. T* m_ptr;
  92. };
  93. // Define a helper for the macro below: we just need a function taking a
  94. // pointer and not returning anything to avoid warnings about unused return
  95. // value of the cast in the macro itself.
  96. namespace wxPrivate { inline void PPV_ARGS_CHECK(void*) { } }
  97. // Takes the interface name and a pointer to a pointer of the interface type
  98. // and expands into the IID of this interface and the same pointer but after a
  99. // type-safety check.
  100. //
  101. // This is similar to the standard IID_PPV_ARGS macro but takes the pointer
  102. // type instead of relying on the non-standard Microsoft __uuidof().
  103. #define wxIID_PPV_ARGS(IType, pType) \
  104. IID_##IType, \
  105. (wxPrivate::PPV_ARGS_CHECK(static_cast<IType*>(*pType)), \
  106. reinterpret_cast<void**>(pType))
  107. #endif // _WX_MSW_PRIVATE_COMPTR_H_