EventsCP.h 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. #ifndef __EventsCP_h__
  2. #define __EventsCP_h__
  3. /////////////////////////////////////////////////////////////////////////////
  4. // EventsCP.h | Declaration of the TCComEventsCP class.
  5. #pragma warning(disable: 4786)
  6. #include <vector>
  7. #include <algorithm>
  8. #include "EventCall.h"
  9. #include <..\TCLib\WorkerThread.h>
  10. #include <..\TCLib\ObjectLock.h>
  11. /////////////////////////////////////////////////////////////////////////////
  12. // TCComEventsCP is the base class for a connection point that has an
  13. // *IUnknown* derived v-table sink interface.
  14. //
  15. // Consider the following IDL (Interface Definition Language) for a simple
  16. // event interface:
  17. //
  18. // // ISampleEvents Interface
  19. // [
  20. // object, oleautomation, pointer_default(unique),
  21. // uuid(098A9AF0-1C79-11d2-8519-00400536E6C1),
  22. // helpstring("ISampleEvents: Sample event interface.")
  23. // ]
  24. // interface ISampleEvents : IUnknown
  25. // {
  26. // HRESULT OnHello([in] VARIANT_BOOL IsHappy, [in] BSTR Text);
  27. // …
  28. // HRESULT OnGoodbye([in] VARIANT_BOOL IsHappy, [in] BSTR Text);
  29. // …
  30. // }; // End: interface ISampleEvents : IUnknown
  31. //
  32. // To declare a connection point class for this sample interface, use the
  33. // BEGIN_TCComEventsCP and END_TCComEventsCP macros along with the
  34. // TCComEventCP_Fn macros:
  35. //
  36. // BEGIN_TCComEventsCP(ISampleEventsCP, ISampleEvents)
  37. // TCComEventCP_Fn2(OnHello, VARIANT_BOOL, BSTR)
  38. // TCComEventCP_Fn2(OnGoodbye, VARIANT_BOOL, BSTR)
  39. // END_TCComEventsCP()
  40. //
  41. // Then, derive your component object from ISampleEventsCP and list the GUID
  42. // of the connection point in your *CONNECTION_POINT_MAP*. To actually fire
  43. // an event to all connected sinks, call the firing function, which is named
  44. // by prefixing *Fire_* to the event name:
  45. //
  46. // // Fire an 'OnHello' event
  47. // Fire_OnHello(bHappy, bstrText);
  48. //
  49. // Note: If you have a second event interface, derived from *IDispatch*, with
  50. // the same event methods as the v-table interface, you should use the
  51. // derived class, TCComDualEventsCP, to be able to fire both types of events
  52. // with a single *Fire_* method call.
  53. //
  54. // Parameters:
  55. // T - The class derived from TCComEventsCP.
  56. // IV - The v-table interface name.
  57. // piid - A constant pointer to the IID of the v-table interface, /IV/.
  58. //
  59. // See Also: BEGIN_TCComEventsCP, BEGIN_TCComEventsCP_IID,
  60. // TCComEventCP_Fn macros, TCComDualEventsCP
  61. template <class T, class IV, const IID* piid>
  62. class ATL_NO_VTABLE TCComEventsCP :
  63. public TCWorkerThread,
  64. public IConnectionPointImpl<T, piid>
  65. {
  66. // Group=Types
  67. public:
  68. // Declares a type used as an alias for the /IV/ template parameter.
  69. typedef IV TIV;
  70. // Declares a type used as an alias for an /IV/ interface pointer.
  71. typedef IV* PIV;
  72. // Declares a vector type of /IV/ interface pointers.
  73. typedef std::vector<IV*> vector_vtbl;
  74. // Declares a vector iterator type for vector_vtbl.
  75. typedef vector_vtbl::iterator it_vtbl;
  76. // Overrides
  77. protected:
  78. virtual IUnknown* OnGetUnknown();
  79. virtual TC_WorkItemRelProc OnGetWorkItemRelProc();
  80. virtual void OnMessage(UINT idMsg, int cParams, LPARAM* rgParams);
  81. static void WINAPI ReleaseArgs(UINT idMsg, int cParams, LPARAM* rgParams);
  82. // Implementation
  83. protected:
  84. void FireEvents(TCComEventCall<IV>& call);
  85. void GetEventSinks(vector_vtbl& vec_vtbl);
  86. void RemoveFailedSink(HRESULT hr, IV* pIfVtbl);
  87. // Enumerations
  88. protected:
  89. enum {e_idFireEvents};
  90. };
  91. /////////////////////////////////////////////////////////////////////////////
  92. // Group=Overrides
  93. /////////////////////////////////////////////////////////////////////////////
  94. // Returns the *IUnknown* of this connection point.
  95. template <class T, class IV, const IID* piid>
  96. IUnknown* TCComEventsCP<T, IV, piid>::OnGetUnknown()
  97. {
  98. return static_cast<T*>(this)->GetUnknown();
  99. }
  100. /////////////////////////////////////////////////////////////////////////////
  101. // Returns the address of the static ReleaseArgs method.
  102. template <class T, class IV, const IID* piid>
  103. TC_WorkItemRelProc TCComEventsCP<T, IV, piid>::OnGetWorkItemRelProc()
  104. {
  105. return ReleaseArgs;
  106. }
  107. /////////////////////////////////////////////////////////////////////////////
  108. // Uses the function call TCComEventCall::operator() of the class derived
  109. // from TCComEventCall.
  110. template <class T, class IV, const IID* piid>
  111. void TCComEventsCP<T, IV, piid>::OnMessage(UINT idMsg, int cParams,
  112. LPARAM* rgParams)
  113. {
  114. switch (idMsg)
  115. {
  116. case e_idFireEvents:
  117. {
  118. // Get the call pointer from the parameter list
  119. assert(1 == cParams);
  120. TCComEventCall<IV>* pCall = (TCComEventCall<IV>*)rgParams[0];
  121. // Call FireEvents in the context of the utility thread
  122. assert(pCall);
  123. FireEvents(*pCall);
  124. break;
  125. }
  126. }
  127. }
  128. /////////////////////////////////////////////////////////////////////////////
  129. // Deletes the object derived from TCComEventCall.
  130. template <class T, class IV, const IID* piid>
  131. void TCComEventsCP<T, IV, piid>::ReleaseArgs(UINT idMsg, int cParams,
  132. LPARAM* rgParams)
  133. {
  134. switch (idMsg)
  135. {
  136. case e_idFireEvents:
  137. {
  138. // Get the call pointer from the parameter list
  139. assert(1 == cParams);
  140. TCComEventCall<IV>* pCall = (TCComEventCall<IV>*)rgParams[0];
  141. // Delete the call pointer
  142. assert(pCall);
  143. delete pCall;
  144. break;
  145. }
  146. }
  147. }
  148. /////////////////////////////////////////////////////////////////////////////
  149. // Group=Implementation
  150. /////////////////////////////////////////////////////////////////////////////
  151. // Description: Fires the event to all connected sinks.
  152. //
  153. // Remarks: This method is used by the TCComEventCP_Fn macros to fire the
  154. // specified event to all connected sinks. The event is specified as a
  155. // reference to an TCComEventCall-derived class instance.
  156. //
  157. // Parameters:
  158. // call - A reference to an instance of a class derived from
  159. // TCComEventCall. This class is derived automatically by the
  160. // TCComEventCP_Fn macros.
  161. //
  162. // See Also: TCComEventCP_Fn macros, TCComEventCall,
  163. // TCComDualEventsCP::FireEvents
  164. template <class T, class IV, const IID* piid>
  165. void TCComEventsCP<T, IV, piid>::FireEvents(TCComEventCall<IV>& call)
  166. {
  167. // Copy all of the vtable sinks
  168. vector_vtbl vec_vtbl;
  169. GetEventSinks(vec_vtbl);
  170. // Notify all vtable event sinks
  171. HRESULT hr;
  172. for (it_vtbl it = vec_vtbl.begin(); it != vec_vtbl.end(); ++it)
  173. if (FAILED(hr = call(*it)))
  174. RemoveFailedSink(hr, *it);
  175. }
  176. /////////////////////////////////////////////////////////////////////////////
  177. // Description: Copies the derived-class's event sinks to the specified
  178. // vector.
  179. //
  180. // Remarks: Copies the derived-class's event sinks to the specified vector.
  181. // The derived-class instance is locked just long enough to copy the event
  182. // sinks. The instance does *not* remain locked for the duration of the event
  183. // calls.
  184. //
  185. // Parameters:
  186. // vec_vtbl - A reference to the vector where the v-table event sinks are
  187. // to be copied.
  188. //
  189. // See Also: TCComEventsCP::FireEvents, TCComDualEventsCP::GetEventSinks
  190. template <class T, class IV, const IID* piid>
  191. inline void TCComEventsCP<T, IV, piid>::GetEventSinks(
  192. TCComEventsCP<T, IV, piid>::vector_vtbl& vec_vtbl)
  193. {
  194. // Lock the object (just long enough to copy the event sinks)
  195. TCObjectLock<T> lock(static_cast<T*>(this));
  196. // Transform the vtable sinks to the specified vec_vtbl
  197. CComDynamicUnkArray& vec_v =
  198. static_cast<IConnectionPointImpl<T, piid>*>(this)->m_vec;
  199. vec_vtbl.resize(vec_v.end() - vec_v.begin(), NULL);
  200. it_vtbl itDest = vec_vtbl.begin();
  201. for (IUnknown** itSrc = vec_v.begin(); itSrc != vec_v.end(); ++itSrc, ++itDest)
  202. *itDest = static_cast<IV*>(*itSrc);
  203. }
  204. /////////////////////////////////////////////////////////////////////////////
  205. // Description: Removes an event sink if an event call failed.
  206. //
  207. // Remarks: This method removes an event sink from the derived-class object
  208. // if an event call failed. This prevents all further event calls to that
  209. // sink. Typically, the event call fails due to an RPC timeout error.
  210. //
  211. // Parameters:
  212. // hr - The HRESULT of the failed event call.
  213. // pIfVtbl - The v-table interface pointer of the sink that failed.
  214. //
  215. // See Also: TCComEventsCP::FireEvents, TCComDualEventsCP::RemoveFailedSink
  216. template <class T, class IV, const IID* piid>
  217. void TCComEventsCP<T, IV, piid>::RemoveFailedSink(HRESULT hr, IV* pIfVtbl)
  218. {
  219. // Cast to the appropriate connection point
  220. IConnectionPointImpl<T, piid>* pCP =
  221. static_cast<IConnectionPointImpl<T, piid>*>(this);
  222. // Use the CP vector to convert the specified interface pointer to a cookie
  223. DWORD dwCookie = pCP->m_vec.GetCookie((IUnknown**)&pIfVtbl);
  224. // Unadvise the failed connection point sink
  225. pCP->Unadvise(dwCookie);
  226. }
  227. /////////////////////////////////////////////////////////////////////////////
  228. // Group=
  229. /////////////////////////////////////////////////////////////////////////////
  230. // Sanity Macros
  231. /////////////////////////////////////////////////////////////////////////////
  232. // Macro Group: BEGIN_TCComEventsCP, BEGIN_TCComEventsCP_IID,
  233. // END_TCComEventsCP
  234. //
  235. // Declaration:
  236. // #define BEGIN_TCComEventsCP(className, IV) \
  237. // BEGIN_TCComEventsCP_IID(className, IV, IID_##IV)
  238. // …
  239. // #define BEGIN_TCComEventsCP_IID(className, IV, IID_vtbl) \
  240. // template <class T> \
  241. // class ATL_NO_VTABLE className : public TCComEventsCP<T, IV, &IID_vtbl> \
  242. // { \
  243. // protected: \
  244. // typedef TCComEventsCP<T, IV, &IID_vtbl>::TIV TIV; \
  245. // typedef TCComEventsCP<T, IV, &IID_vtbl>::PIV PIV;
  246. // …
  247. // #define END_TCComEventsCP() \
  248. // };
  249. //
  250. // Parameters:
  251. // className - The name of the connection point class that is being
  252. // declared.
  253. // IV - The name of the *interface* which the connection point represents.
  254. // IID_vtbl - The IID of the *interface* which the connection point
  255. // represents.
  256. //
  257. // Remarks: These macros declare a class derived from the TCComEventsCP
  258. // template. Their use is not mandatory, but does simplify the entire
  259. // declaration of such a connection point class. Either *BEGIN_* macro should
  260. // be followed by 0, 1, or more instances of the TCComEventCP_Fn macros,
  261. // followed by the END_TCComEventsCP macro. See the
  262. // TCComEventsCP class overview for an example and more details.
  263. //
  264. // See Also: TCComEventsCP, TCComEventCP_Fn macros
  265. #define BEGIN_TCComEventsCP(className, IV) \
  266. BEGIN_TCComEventsCP_IID(className, IV, IID_##IV)
  267. /////////////////////////////////////////////////////////////////////////////
  268. // {partof:BEGIN_TCComEventsCP}
  269. #define BEGIN_TCComEventsCP_IID(className, IV, IID_vtbl) \
  270. template <class T> \
  271. class ATL_NO_VTABLE className : public TCComEventsCP<T, IV, &IID_vtbl> \
  272. { \
  273. protected: \
  274. typedef TCComEventsCP<T, IV, &IID_vtbl>::TIV TIV; \
  275. typedef TCComEventsCP<T, IV, &IID_vtbl>::PIV PIV;
  276. /////////////////////////////////////////////////////////////////////////////
  277. // {partof:BEGIN_TCComEventsCP}
  278. #define END_TCComEventsCP() \
  279. };
  280. #ifdef _DOCJET_ONLY
  281. ///////////////////////////////////////////////////////////////////////////
  282. // Macro Group: TCComEventCP_Fn Group of Macros
  283. //
  284. // Declaration:
  285. // #define TCComEventCP_Fn0(fnName)
  286. // #define TCComEventCP_Fn1(fnName,t1)
  287. // #define TCComEventCP_Fn2(fnName,t1,t2)
  288. // #define TCComEventCP_Fn3(fnName,t1,t2,t3)
  289. // #define TCComEventCP_Fn4(fnName,t1,t2,t3,t4)
  290. // #define TCComEventCP_Fn5(fnName,t1,t2,t3,t4,t5)
  291. // #define TCComEventCP_Fn6(fnName,t1,t2,t3,t4,t5,t6)
  292. // #define TCComEventCP_Fn7(fnName,t1,t2,t3,t4,t5,t6,t7)
  293. // #define TCComEventCP_Fn8(fnName,t1,t2,t3,t4,t5,t6,t7,t8)
  294. // #define TCComEventCP_Fn9(fnName,t1,t2,t3,t4,t5,t6,t7,t8,t9)
  295. // #define TCComEventCP_Fn10(fnName,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
  296. // #define TCComEventCP_Fn11(fnName,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11)
  297. // #define TCComEventCP_Fn12(fnName,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12)
  298. //
  299. // Parameters:
  300. // fnName - The event name. This must match the name of the event in the
  301. // v-table *interface*.
  302. // t1_thru_t12 - The C++ parameter types of the event arguments. These
  303. // must match the parameter types of the event in the v-table *interface*.
  304. //
  305. // Remarks: These macros all perform the same function and are different
  306. // only in that they specify an event with a different number of arguments.
  307. //
  308. // An inline member function, named by prefixing *Fire_* to the
  309. // /fnName/ parameter, is declared by each of these macros. The member
  310. // function is prototyped to take the /t/ parameters, if any. The member
  311. // function will fire the event to all of the connected sinks. Actually,
  312. // the TCUtilityThread class is used to post the event firing process as an
  313. // element of work to be performed in the context of the shared utility
  314. // thread. As such, the *Fire_* methods are prototyped with a void return
  315. // type. Currently, receiving a result or an [out] parameter from a
  316. // connected sink is not supported.
  317. //
  318. // Internally, the macros derive a class from TCComEventCall, to hold the
  319. // arguments of the event call, if any. The /t1/ thru /t12/ macro
  320. // parameters are used to create and initialize this nested class
  321. // appropriately. The DECLARE_CTOR macros are used to declare appropriate
  322. // member variables and constructors that initialize those variables.
  323. #define TCComEventCP_Fn
  324. #endif // _DOCJET_ONLY
  325. /////////////////////////////////////////////////////////////////////////////
  326. // {partof:TCComEventCP_Fn}
  327. #define TCComEventCP_Fn0(name) \
  328. class CCall##name : public TCComEventCall<TIV> \
  329. { \
  330. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  331. { \
  332. return pvtbl->##name(); \
  333. } \
  334. }; \
  335. public: void Fire_##name() \
  336. { \
  337. CCall##name* pCall = new CCall##name; \
  338. pCall->SetEventName(#name); \
  339. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  340. }
  341. /////////////////////////////////////////////////////////////////////////////
  342. // {partof:TCComEventCP_Fn}
  343. #define TCComEventCP_Fn1(name, t1) \
  344. class CCall##name : public TCComEventCall<TIV> \
  345. { \
  346. DECLARE_CTOR_1(CCall##name, t1) \
  347. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  348. { \
  349. return pvtbl->##name(m_a1); \
  350. } \
  351. }; \
  352. public: void Fire_##name(t1 a1) \
  353. { \
  354. CCall##name* pCall = new CCall##name(a1); \
  355. pCall->SetEventName(#name); \
  356. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  357. }
  358. /////////////////////////////////////////////////////////////////////////////
  359. // {partof:TCComEventCP_Fn}
  360. #define TCComEventCP_Fn2(name, t1, t2) \
  361. class CCall##name : public TCComEventCall<TIV> \
  362. { \
  363. DECLARE_CTOR_2(CCall##name, t1, t2) \
  364. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  365. { \
  366. return pvtbl->##name(m_a1, m_a2); \
  367. } \
  368. }; \
  369. public: void Fire_##name(t1 a1, t2 a2) \
  370. { \
  371. CCall##name* pCall = new CCall##name(a1, a2); \
  372. pCall->SetEventName(#name); \
  373. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  374. }
  375. /////////////////////////////////////////////////////////////////////////////
  376. // {partof:TCComEventCP_Fn}
  377. #define TCComEventCP_Fn3(name, t1, t2, t3) \
  378. class CCall##name : public TCComEventCall<TIV> \
  379. { \
  380. DECLARE_CTOR_3(CCall##name, t1, t2, t3) \
  381. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  382. { \
  383. return pvtbl->##name(m_a1, m_a2, m_a3); \
  384. } \
  385. }; \
  386. public: void Fire_##name(t1 a1, t2 a2, t3 a3) \
  387. { \
  388. CCall##name* pCall = new CCall##name(a1, a2, a3); \
  389. pCall->SetEventName(#name); \
  390. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  391. }
  392. /////////////////////////////////////////////////////////////////////////////
  393. // {partof:TCComEventCP_Fn}
  394. #define TCComEventCP_Fn4(name, t1, t2, t3, t4) \
  395. class CCall##name : public TCComEventCall<TIV> \
  396. { \
  397. DECLARE_CTOR_4(CCall##name, t1, t2, t3, t4) \
  398. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  399. { \
  400. return pvtbl->##name(m_a1, m_a2, m_a3, m_a4); \
  401. } \
  402. }; \
  403. public: void Fire_##name(t1 a1, t2 a2, t3 a3, t4 a4) \
  404. { \
  405. CCall##name* pCall = new CCall##name(a1, a2, a3, a4); \
  406. pCall->SetEventName(#name); \
  407. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  408. }
  409. /////////////////////////////////////////////////////////////////////////////
  410. // {partof:TCComEventCP_Fn}
  411. #define TCComEventCP_Fn5(name, t1, t2, t3, t4, t5) \
  412. class CCall##name : public TCComEventCall<TIV> \
  413. { \
  414. DECLARE_CTOR_5(CCall##name, t1, t2, t3, t4, t5) \
  415. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  416. { \
  417. return pvtbl->##name(m_a1, m_a2, m_a3, m_a4, m_a5); \
  418. } \
  419. }; \
  420. public: void Fire_##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \
  421. { \
  422. CCall##name* pCall = new CCall##name(a1, a2, a3, a4, a5); \
  423. pCall->SetEventName(#name); \
  424. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  425. }
  426. /////////////////////////////////////////////////////////////////////////////
  427. // {partof:TCComEventCP_Fn}
  428. #define TCComEventCP_Fn6(name, t1, t2, t3, t4, t5, t6) \
  429. class CCall##name : public TCComEventCall<TIV> \
  430. { \
  431. DECLARE_CTOR_6(CCall##name, t1, t2, t3, t4, t5, t6) \
  432. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  433. { \
  434. return pvtbl->##name(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6); \
  435. } \
  436. }; \
  437. public: void Fire_##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
  438. { \
  439. CCall##name* pCall = new CCall##name(a1, a2, a3, a4, a5, a6); \
  440. pCall->SetEventName(#name); \
  441. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  442. }
  443. /////////////////////////////////////////////////////////////////////////////
  444. // {partof:TCComEventCP_Fn}
  445. #define TCComEventCP_Fn7(name, t1, t2, t3, t4, t5, t6, t7) \
  446. class CCall##name : public TCComEventCall<TIV> \
  447. { \
  448. DECLARE_CTOR_7(CCall##name, t1, t2, t3, t4, t5, t6, t7) \
  449. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  450. { \
  451. return pvtbl->##name(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7); \
  452. } \
  453. }; \
  454. public: void Fire_##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, \
  455. t7 a7) \
  456. { \
  457. CCall##name* pCall = new CCall##name(a1, a2, a3, a4, a5, a6, a7); \
  458. pCall->SetEventName(#name); \
  459. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  460. }
  461. /////////////////////////////////////////////////////////////////////////////
  462. // {partof:TCComEventCP_Fn}
  463. #define TCComEventCP_Fn8(name, t1, t2, t3, t4, t5, t6, t7, t8) \
  464. class CCall##name : public TCComEventCall<TIV> \
  465. { \
  466. DECLARE_CTOR_8(CCall##name, t1, t2, t3, t4, t5, t6, t7, t8) \
  467. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  468. { \
  469. return pvtbl->##name(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7, m_a8); \
  470. } \
  471. }; \
  472. public: void Fire_##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, \
  473. t7 a7, t8 a8) \
  474. { \
  475. CCall##name* pCall = new CCall##name(a1, a2, a3, a4, a5, a6, a7, a8); \
  476. pCall->SetEventName(#name); \
  477. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  478. }
  479. /////////////////////////////////////////////////////////////////////////////
  480. // {partof:TCComEventCP_Fn}
  481. #define TCComEventCP_Fn9(name, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
  482. class CCall##name : public TCComEventCall<TIV> \
  483. { \
  484. DECLARE_CTOR_9(CCall##name, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
  485. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  486. { \
  487. return pvtbl->##name(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7, m_a8, \
  488. m_a9); \
  489. } \
  490. }; \
  491. public: void Fire_##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, \
  492. t7 a7, t8 a8, t9 a9) \
  493. { \
  494. CCall##name* pCall = new CCall##name(a1, a2, a3, a4, a5, a6, a7, a8, \
  495. a9); \
  496. pCall->SetEventName(#name); \
  497. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  498. }
  499. /////////////////////////////////////////////////////////////////////////////
  500. // {partof:TCComEventCP_Fn}
  501. #define TCComEventCP_Fn10(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) \
  502. class CCall##name : public TCComEventCall<TIV> \
  503. { \
  504. DECLARE_CTOR_10(CCall##name, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) \
  505. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  506. { \
  507. return pvtbl->##name(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7, m_a8, \
  508. m_a9, m_a10); \
  509. } \
  510. }; \
  511. public: void Fire_##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, \
  512. t7 a7, t8 a8, t9 a9, t10 a10) \
  513. { \
  514. CCall##name* pCall = new CCall##name(a1, a2, a3, a4, a5, a6, a7, a8, \
  515. a9, a10); \
  516. pCall->SetEventName(#name); \
  517. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  518. }
  519. /////////////////////////////////////////////////////////////////////////////
  520. // {partof:TCComEventCP_Fn}
  521. #define TCComEventCP_Fn11(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, \
  522. t11) \
  523. class CCall##name : public TCComEventCall<TIV> \
  524. { \
  525. DECLARE_CTOR_11(CCall##name, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, \
  526. t11) \
  527. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  528. { \
  529. return pvtbl->##name(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7, m_a8, \
  530. m_a9, m_a10, m_a11); \
  531. } \
  532. }; \
  533. public: void Fire_##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, \
  534. t7 a7, t8 a8, t9 a9, t10 a10, t11 a11) \
  535. { \
  536. CCall##name* pCall = new CCall##name(a1, a2, a3, a4, a5, a6, a7, a8, \
  537. a9, a10, a11); \
  538. pCall->SetEventName(#name); \
  539. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  540. }
  541. /////////////////////////////////////////////////////////////////////////////
  542. // {partof:TCComEventCP_Fn}
  543. #define TCComEventCP_Fn12(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, \
  544. t11, t12) \
  545. class CCall##name : public TCComEventCall<TIV> \
  546. { \
  547. DECLARE_CTOR_12(CCall##name, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, \
  548. t11, t12) \
  549. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  550. { \
  551. return pvtbl->##name(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7, m_a8, \
  552. m_a9, m_a10, m_a11, m_a12); \
  553. } \
  554. }; \
  555. public: void Fire_##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, \
  556. t7 a7, t8 a8, t9 a9, t10 a10, t11 a11, t12 a12) \
  557. { \
  558. CCall##name* pCall = new CCall##name(a1, a2, a3, a4, a5, a6, a7, a8, \
  559. a9, a10, a11, a12); \
  560. pCall->SetEventName(#name); \
  561. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  562. }
  563. #ifdef _DOCJET_ONLY
  564. ///////////////////////////////////////////////////////////////////////////
  565. // Macro Group: DECLARE_CTOR Construction Macros
  566. //
  567. // Declaration:
  568. // #define DECLARE_CTOR_1(className, t1)
  569. // #define DECLARE_CTOR_2(className, t1, t2)
  570. // #define DECLARE_CTOR_3(className, t1, t2, t3)
  571. // #define DECLARE_CTOR_4(className, t1, t2, t3, t4)
  572. // #define DECLARE_CTOR_5(className, t1, t2, t3, t4, t5)
  573. // #define DECLARE_CTOR_6(className, t1, t2, t3, t4, t5, t6)
  574. // #define DECLARE_CTOR_7(className, t1, t2, t3, t4, t5, t6, t7)
  575. // #define DECLARE_CTOR_8(className, t1, t2, t3, t4, t5, t6, t7, t8)
  576. // #define DECLARE_CTOR_9(className, t1, t2, t3, t4, t5, t6, t7, t8, t9)
  577. // #define DECLARE_CTOR_10(className, \
  578. // t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)
  579. // #define DECLARE_CTOR_11(className, \
  580. // t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11)
  581. // #define DECLARE_CTOR_12(className, \
  582. // t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12)
  583. // #define DECLARE_CTOR_13(className, \
  584. // t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13)
  585. // #define DECLARE_CTOR_14(className, \
  586. // t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14)
  587. // #define DECLARE_CTOR_15(className, \
  588. // t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15)
  589. // #define DECLARE_CTOR_16(className, \
  590. // t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16)
  591. //
  592. // Parameters:
  593. // className - The name of the class for which a constructor is being
  594. // declared.
  595. // t1_thru_t16 - The data types of the member variables and constructor
  596. // arguments to be declared.
  597. //
  598. // Remarks: These macros all perform the same function and are different
  599. // only in that they specify a different number of arguments. For each
  600. // argument, a *protected* data member is declared of the type specified by
  601. // each /t/ parameter, and a constructor argument is declared of that same
  602. // type. The constructor is declared *public* and its initializer list
  603. // simply initializes the declared member variables to the values specified
  604. // in the constructor argument list.
  605. //
  606. // Note: These macros are currently only used by the TCComEventCP_Fn and
  607. // TCComDualEventCP_Fn macros. If their use is ever needed outside the
  608. // scope of connection point sinks, they should be moved into their own
  609. // header file and included in this one.
  610. //
  611. // See Also: TCComEventCP_Fn macros, TCComDualEventCP_Fn macros
  612. #define DECLARE_CTOR
  613. #endif // _DOCJET_ONLY
  614. /////////////////////////////////////////////////////////////////////////////
  615. // {partof:DECLARE_CTOR}
  616. #define DECLARE_CTOR_1(name, t1) \
  617. protected: t1 m_a1; \
  618. public: name(t1 a1) \
  619. : m_a1(a1) {}
  620. /////////////////////////////////////////////////////////////////////////////
  621. // {partof:DECLARE_CTOR}
  622. #define DECLARE_CTOR_2(name, t1, t2) \
  623. protected: t1 m_a1; t2 m_a2; \
  624. public: name(t1 a1, t2 a2) \
  625. : m_a1(a1), m_a2(a2) {}
  626. /////////////////////////////////////////////////////////////////////////////
  627. // {partof:DECLARE_CTOR}
  628. #define DECLARE_CTOR_3(name, t1, t2, t3) \
  629. protected: t1 m_a1; t2 m_a2; t3 m_a3; \
  630. public: name(t1 a1, t2 a2, t3 a3) \
  631. : m_a1(a1), m_a2(a2), m_a3(a3) {}
  632. /////////////////////////////////////////////////////////////////////////////
  633. // {partof:DECLARE_CTOR}
  634. #define DECLARE_CTOR_4(name, t1, t2, t3, t4) \
  635. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; \
  636. public: name(t1 a1, t2 a2, t3 a3, t4 a4) \
  637. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4) {}
  638. /////////////////////////////////////////////////////////////////////////////
  639. // {partof:DECLARE_CTOR}
  640. #define DECLARE_CTOR_5(name, t1, t2, t3, t4, t5) \
  641. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; \
  642. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \
  643. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5) {}
  644. /////////////////////////////////////////////////////////////////////////////
  645. // {partof:DECLARE_CTOR}
  646. #define DECLARE_CTOR_6(name, t1, t2, t3, t4, t5, t6) \
  647. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; \
  648. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
  649. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6) {}
  650. /////////////////////////////////////////////////////////////////////////////
  651. // {partof:DECLARE_CTOR}
  652. #define DECLARE_CTOR_7(name, t1, t2, t3, t4, t5, t6, t7) \
  653. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; t7 m_a7; \
  654. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \
  655. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6), m_a7(a7) {}
  656. /////////////////////////////////////////////////////////////////////////////
  657. // {partof:DECLARE_CTOR}
  658. #define DECLARE_CTOR_8(name, t1, t2, t3, t4, t5, t6, t7, t8) \
  659. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; t7 m_a7; \
  660. t8 m_a8; \
  661. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \
  662. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6), m_a7(a7), \
  663. m_a8(a8) {}
  664. /////////////////////////////////////////////////////////////////////////////
  665. // {partof:DECLARE_CTOR}
  666. #define DECLARE_CTOR_9(name, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
  667. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; t7 m_a7; \
  668. t8 m_a8; t9 m_a9; \
  669. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, \
  670. t9 a9) \
  671. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6), m_a7(a7), \
  672. m_a8(a8), m_a9(a9) {}
  673. /////////////////////////////////////////////////////////////////////////////
  674. // {partof:DECLARE_CTOR}
  675. #define DECLARE_CTOR_10(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) \
  676. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; t7 m_a7; \
  677. t8 m_a8; t9 m_a9; t10 m_a10; \
  678. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, \
  679. t9 a9, t10 a10) \
  680. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6), m_a7(a7), \
  681. m_a8(a8), m_a9(a9), m_a10(a10) {}
  682. /////////////////////////////////////////////////////////////////////////////
  683. // {partof:DECLARE_CTOR}
  684. #define DECLARE_CTOR_11(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) \
  685. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; t7 m_a7; \
  686. t8 m_a8; t9 m_a9; t10 m_a10; t11 m_a11; \
  687. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, \
  688. t9 a9, t10 a10, t11 a11) \
  689. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6), m_a7(a7), \
  690. m_a8(a8), m_a9(a9), m_a10(a10), m_a11(a11) {}
  691. /////////////////////////////////////////////////////////////////////////////
  692. // {partof:DECLARE_CTOR}
  693. #define DECLARE_CTOR_12(name, \
  694. t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) \
  695. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; t7 m_a7; \
  696. t8 m_a8; t9 m_a9; t10 m_a10; t11 m_a11; t12 m_a12; \
  697. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, \
  698. t9 a9, t10 a10, t11 a11, t12 a12) \
  699. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6), m_a7(a7), \
  700. m_a8(a8), m_a9(a9), m_a10(a10), m_a11(a11), m_a12(a12) {}
  701. /////////////////////////////////////////////////////////////////////////////
  702. // {partof:DECLARE_CTOR}
  703. #define DECLARE_CTOR_13(name, \
  704. t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13) \
  705. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; t7 m_a7; \
  706. t8 m_a8; t9 m_a9; t10 m_a10; t11 m_a11; t12 m_a12; t13 m_a13; \
  707. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, \
  708. t9 a9, t10 a10, t11 a11, t12 a12, t13 a13) \
  709. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6), m_a7(a7), \
  710. m_a8(a8), m_a9(a9), m_a10(a10), m_a11(a11), m_a12(a12), m_a13(a13) {}
  711. /////////////////////////////////////////////////////////////////////////////
  712. // {partof:DECLARE_CTOR}
  713. #define DECLARE_CTOR_14(name, \
  714. t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14) \
  715. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; t7 m_a7; \
  716. t8 m_a8; t9 m_a9; t10 m_a10; t11 m_a11; t12 m_a12; t13 m_a13; t14 m_a14; \
  717. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, \
  718. t9 a9, t10 a10, t11 a11, t12 a12, t13 a13, t14 a14) \
  719. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6), m_a7(a7), \
  720. m_a8(a8), m_a9(a9), m_a10(a10), m_a11(a11), m_a12(a12), m_a13(a13), \
  721. m_a14(a14) {}
  722. /////////////////////////////////////////////////////////////////////////////
  723. // {partof:DECLARE_CTOR}
  724. #define DECLARE_CTOR_15(name, \
  725. t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15) \
  726. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; t7 m_a7; \
  727. t8 m_a8; t9 m_a9; t10 m_a10; t11 m_a11; t12 m_a12; t13 m_a13; t14 m_a14; \
  728. t15 m_a15; \
  729. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, \
  730. t9 a9, t10 a10, t11 a11, t12 a12, t13 a13, t14 a14, t15 a15) \
  731. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6), m_a7(a7), \
  732. m_a8(a8), m_a9(a9), m_a10(a10), m_a11(a11), m_a12(a12), m_a13(a13), \
  733. m_a14(a14), m_a15(a15) {}
  734. /////////////////////////////////////////////////////////////////////////////
  735. // {partof:DECLARE_CTOR}
  736. #define DECLARE_CTOR_16(name, \
  737. t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16) \
  738. protected: t1 m_a1; t2 m_a2; t3 m_a3; t4 m_a4; t5 m_a5; t6 m_a6; t7 m_a7; \
  739. t8 m_a8; t9 m_a9; t10 m_a10; t11 m_a11; t12 m_a12; t13 m_a13; t14 m_a14; \
  740. t15 m_a15; t16 m_a16; \
  741. public: name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, \
  742. t9 a9, t10 a10, t11 a11, t12 a12, t13 a13, t14 a14, t15 a15, t16 a16) \
  743. : m_a1(a1), m_a2(a2), m_a3(a3), m_a4(a4), m_a5(a5), m_a6(a6), m_a7(a7), \
  744. m_a8(a8), m_a9(a9), m_a10(a10), m_a11(a11), m_a12(a12), m_a13(a13), \
  745. m_a14(a14), m_a15(a15), m_a16(a16) {}
  746. #ifdef _DOCJET_ONLY
  747. ///////////////////////////////////////////////////////////////////////////
  748. // TCComPropertyNotifySinkCP declares a connection point class for the
  749. // *IPropertyNotifySink* interface.
  750. //
  751. // Please refer to the TCComEventsCP class overview for more information on
  752. // how to use such a class.
  753. //
  754. // See Also: TCComEventsCP, BEGIN_TCComEventsCP, TCComFakeNotifySink,
  755. // TCComPropertyClass
  756. template <class T>
  757. class ATL_NO_VTABLE TCComPropertyNotifySinkCP :
  758. public TCComEventsCP<T, IPropertyNotifySink, &IID_IPropertyNotifySink>
  759. {
  760. void Fire_OnChanged(DISPID dispID); // {secret}
  761. void Fire_OnRequestEdit(DISPID dispID); // {secret}
  762. };
  763. #else // _DOCJET_ONLY
  764. BEGIN_TCComEventsCP(TCComPropertyNotifySinkCP, IPropertyNotifySink)
  765. TCComEventCP_Fn1(OnChanged, DISPID);
  766. TCComEventCP_Fn1(OnRequestEdit, DISPID);
  767. END_TCComEventsCP()
  768. #endif // _DOCJET_ONLY
  769. /////////////////////////////////////////////////////////////////////////////
  770. #endif // !__EventsCP_h__