EventCall.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #ifndef __EventCall_h__
  2. #define __EventCall_h__
  3. /////////////////////////////////////////////////////////////////////////////
  4. // EventsCall.h | Declaration of the classes used in the for_each statements
  5. // of the connection point sinks.
  6. /////////////////////////////////////////////////////////////////////////////
  7. // TCComEventCall is used internally by the TCComEventCP_Fn macros as a base
  8. // class for a function object that maintains the set of arguments passed to
  9. // a v-table connection point sink.
  10. //
  11. // The function call operator() of this class will be called for each
  12. // v-table connection point sink maintained by a connection point derived
  13. // from TCComEventCP.
  14. //
  15. // Since this class is used internally by the TCComEventCP_Fn macros, it is
  16. // unlikely that you will ever need to use it directly.
  17. //
  18. // Parameters:
  19. // If_vtbl - Specifies the interface name of the v-table connection point
  20. // sink.
  21. //
  22. // See Also: TCComEventCP_Fn macros, TCComEventsCP, TCComDualEventCall,
  23. // TCComDualEventsCP
  24. template <class If_vtbl>
  25. class ATL_NO_VTABLE TCComEventCall
  26. {
  27. // Construction / Destruction
  28. public:
  29. TCComEventCall();
  30. virtual ~TCComEventCall();
  31. // Disallow copy constructor
  32. private:
  33. TCComEventCall(const TCComEventCall&);
  34. // Attributes
  35. public:
  36. void SetEventName(LPCSTR pszName);
  37. LPCSTR GetEventName() const;
  38. // Operators
  39. public:
  40. HRESULT operator()(If_vtbl* pvtbl);
  41. // Overrides
  42. protected:
  43. virtual HRESULT OnCallEventSink(If_vtbl* pvtbl) = 0;
  44. // Implementation
  45. protected:
  46. void ResetErrorInfo();
  47. // Data Members
  48. protected:
  49. // A smart-pointer that maintains the *IErrorInfo* object of the thread for
  50. // each call to a connection point sink.
  51. //
  52. // See Also: TCComEventCall::ResetErrorInfo, TCComEventCall::operator()
  53. CComPtr<IErrorInfo> m_pei;
  54. // A pointer to the name of the event, used for diagnostic purposes.
  55. //
  56. // See Also: TCComEventCall::SetEventName, TCComEventCall::GetEventName,
  57. // TCComEventCall::operator()
  58. LPCSTR m_pszName;
  59. };
  60. /////////////////////////////////////////////////////////////////////////////
  61. // Group=Construction / Destruction
  62. /////////////////////////////////////////////////////////////////////////////
  63. // Initializes the instance by setting m_pszName to *NULL* and copying the
  64. // current *IErrorInfo* of the thread.
  65. //
  66. // See Also: TCComEventCall::ResetErrorInfo
  67. template <class If_vtbl>
  68. inline TCComEventCall<If_vtbl>::TCComEventCall() :
  69. m_pszName(NULL)
  70. {
  71. // Save the current error info object of this thread
  72. m_pei = NULL;
  73. _VERIFYE(SUCCEEDED(GetErrorInfo(0, &m_pei)));
  74. ResetErrorInfo();
  75. }
  76. template <class If_vtbl>
  77. inline TCComEventCall<If_vtbl>::~TCComEventCall()
  78. {
  79. }
  80. /////////////////////////////////////////////////////////////////////////////
  81. // Group=Attributes
  82. /////////////////////////////////////////////////////////////////////////////
  83. // Description: Sets the name of the event used for diagnostic purposes.
  84. //
  85. // The TCComEventCP_Fn macros call this with the name of the event. It is
  86. // used for diagnostic messages that indicate the success or failure of a
  87. // call to an event sink.
  88. //
  89. // Parameters:
  90. // pszName - Points to the name of the event. This should be a constant
  91. // string literal, since only the pointer is saved.
  92. //
  93. // See Also: TCComEventCall::GetEventName, TCComEventCall::m_pszName
  94. template <class If_vtbl>
  95. inline void TCComEventCall<If_vtbl>::SetEventName(LPCSTR pszName)
  96. {
  97. m_pszName = pszName;
  98. }
  99. /////////////////////////////////////////////////////////////////////////////
  100. // Description: Gets the name of the event used for diagnostic purposes.
  101. //
  102. // This is used for diagnostic messages that indicate the success or failure
  103. // of a call to an event sink.
  104. //
  105. // Return Value: Returns the same pointer specified in a previous call to
  106. // SetEventName, or *NULL* if the name has not been set.
  107. //
  108. // See Also: TCComEventCall::SetEventName, TCComEventCall::m_pszName
  109. template <class If_vtbl>
  110. inline LPCSTR TCComEventCall<If_vtbl>::GetEventName() const
  111. {
  112. return m_pszName;
  113. }
  114. /////////////////////////////////////////////////////////////////////////////
  115. // Group=Operators
  116. /////////////////////////////////////////////////////////////////////////////
  117. // Description: Function call operator.
  118. //
  119. // This function call operator calls the event method on the specified
  120. // v-table interface pointer by delegating to the virtual OnCallEventSink
  121. // override of the derived class. The derived class maintains the set of
  122. // arguments associated with the event call. Prior to each call, the
  123. // *IErrorInfo* of the current thread is reset to that of the thread that
  124. // initiated the event call.
  125. //
  126. // Parameters:
  127. // pvtbl - The interface pointer of the connected event sink.
  128. //
  129. // Return Value: The HRESULT of the event call is returned.
  130. //
  131. // See Also: TCComEventCall::OnCallEventSink, TCComEventCP_Fn macros
  132. template <class If_vtbl>
  133. HRESULT TCComEventCall<If_vtbl>::operator()(If_vtbl* pvtbl)
  134. {
  135. HRESULT hr = S_OK;
  136. if (NULL != pvtbl)
  137. {
  138. // Format the class::function name
  139. char szFn[_MAX_PATH] = "";
  140. #ifdef _DEBUG
  141. sprintf(szFn, "TCComEventCall<%hs>::operator()", TCTypeName(If_vtbl));
  142. #endif
  143. __try
  144. {
  145. // Reset the IErrorInfo* for this thread and call the event
  146. ResetErrorInfo();
  147. hr = OnCallEventSink(pvtbl);
  148. #ifdef _DEBUG
  149. char szMsg[_MAX_PATH];
  150. sprintf(szMsg, "Event call %hs", GetEventName());
  151. if (SUCCEEDED(hr))
  152. _TRACE2("%hs: %hs succeeded\n", szFn, szMsg);
  153. else
  154. {
  155. strcat(szMsg, " returned");
  156. TCReportHR(szFn, szMsg, hr);
  157. }
  158. #endif _DEBUG
  159. }
  160. __except(1)
  161. {
  162. _TRACE1("%hs: Caught an unknown exception\n", szFn);
  163. return E_UNEXPECTED;
  164. }
  165. }
  166. // Return the last HRESULT
  167. return hr;
  168. }
  169. /////////////////////////////////////////////////////////////////////////////
  170. // Group=Overrides
  171. #ifdef _DOCJET_ONLY
  172. ///////////////////////////////////////////////////////////////////////////
  173. // Description: Pure-virtual override that makes an event call to the
  174. // specified connection point sink.
  175. //
  176. // Overridden in derived classes to makes an event call to the specified
  177. // connection point sink. This is called by the function call operator()
  178. // for each connected event sink.
  179. //
  180. // Parameters:
  181. // pvtbl - The interface pointer of the connected event sink.
  182. //
  183. // Return Value: The HRESULT of the event call should be returned.
  184. //
  185. // See Also: TCComEventCall::operator(), TCComEventCP_Fn macros
  186. template <class If_vtbl>
  187. virtual HRESULT TCComEventCall<If_vtbl>::OnCallEventSink(If_vtbl* pvtbl);
  188. #endif // _DOCJET_ONLY
  189. /////////////////////////////////////////////////////////////////////////////
  190. // Group=Implementation
  191. /////////////////////////////////////////////////////////////////////////////
  192. // Description: Resets the *IErrorInfo* of the current thread.
  193. //
  194. // This method is called by the function call operator() to reset the
  195. // *IErrorInfo* of the current thread to that of the thread that initiated
  196. // the event call.
  197. //
  198. // See Also: TCComEventCall::operator(), TCComEventCall::m_pei
  199. template <class If_vtbl>
  200. inline void TCComEventCall<If_vtbl>::ResetErrorInfo()
  201. {
  202. _SVERIFYE(::SetErrorInfo(0, m_pei));
  203. }
  204. /////////////////////////////////////////////////////////////////////////////
  205. #endif // !__EventCall_h__