DualEventsCP.h 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. #ifndef __DualEventsCP_h__
  2. #define __DualEventsCP_h__
  3. /////////////////////////////////////////////////////////////////////////////
  4. // DualEventsCP.h | Declaration of the TCComDualEventsCP class.
  5. #include "EventsCP.h"
  6. #include "DualEventCall.h"
  7. #include <..\TCLib\ObjectLock.h>
  8. /////////////////////////////////////////////////////////////////////////////
  9. // TCComDualEventsCP is the base class for a connection point that has both
  10. // *IDispatch* and v-table sink interfaces.
  11. //
  12. // Actually, two connection points exist in this case - one for the
  13. // *dispinterface* and one for the (v-table) *interface* implemented by the
  14. // *dispinterface*. The result is a sort of /dual/ connection point so that
  15. // sinks can easily be written in multiple environments. For example,
  16. // scripting and VB clients would connect to the *dispinterface* connection
  17. // point. However, a C or C++ client would probably want to connect to the
  18. // (v-table) *interface* connection point, since that would not require
  19. // unnecessary implementation of the *IDispatch* methods.
  20. //
  21. // The IDL (Interface Definition Language) for such a pair of corresponding
  22. // interfaces should be similar to the following:
  23. //
  24. // // ISampleEvents Interface
  25. // [
  26. // object, oleautomation, pointer_default(unique),
  27. // uuid(098A9AF0-1C79-11d2-8519-00400536E6C1),
  28. // helpstring("ISampleEvents: Sample event interface.")
  29. // ]
  30. // interface ISampleEvents : IUnknown
  31. // {
  32. // [id(DISPID_OnHello), helpstring("Indicates 'Hello'.")]
  33. // HRESULT OnHello([in] VARIANT_BOOL IsHappy, [in] BSTR Text);
  34. // …
  35. // [id(DISPID_OnGoodbye), helpstring("Indicates 'Goodbye'.")]
  36. // HRESULT OnGoodbye([in] VARIANT_BOOL IsHappy, [in] BSTR Text);
  37. // …
  38. // }; // End: interface ISampleEvents : IUnknown
  39. // …
  40. // …
  41. // // DISampleEvents Interface
  42. // [
  43. // oleautomation, uuid(098A9AF1-1C79-11d2-8519-00400536E6C1),
  44. // helpstring("DISampleEvents Interface")
  45. // ]
  46. // dispinterface DISampleEvents
  47. // {
  48. // interface ISampleEvents;
  49. // …
  50. // }; // End: dispinterface DISampleEvents
  51. //
  52. // Notice that the *interface* and the *dispinterface* must each have a
  53. // unique *GUID*. Also notice that the (v-table) *interface* is derived from
  54. // *IUnknown* and is *not* marked [dual]. The /dual/ nature is implemented by
  55. // the *dispinterface* declaring the (v-table) *interface*. This form of the
  56. // *dispinterface* indicates that all of the methods and properties of the
  57. // specified *interface* will be methods and properties of the
  58. // *dispinterface*, without having to code them twice.
  59. //
  60. // To declare a connection point class for the previous sample interfaces,
  61. // use the BEGIN_TCComDualEventsCP and END_TCComDualEventsCP macros along
  62. // with the TCComDualEventCP_Fn macros:
  63. //
  64. // BEGIN_TCComDualEventsCP(ISampleEventsCP, ISampleEvents, DIID_DISampleEvents)
  65. // TCComDualEventCP_Fn2(OnHello, DISPID_OnHello,
  66. // VARIANT_BOOL, VT_BOOL, BSTR, VT_BSTR)
  67. // TCComDualEventCP_Fn2(OnGoodbye, DISPID_OnGoodbye,
  68. // VARIANT_BOOL, VT_BOOL, BSTR, VT_BSTR)
  69. // END_TCComDualEventsCP()
  70. //
  71. // Then, derive your component object from ISampleEventsCP and list the GUIDs
  72. // of both connection points in your *CONNECTION_POINT_MAP*. To actually fire
  73. // an event to all connected sinks, call the firing function, which is named
  74. // by prefixing *Fire_* to the event name:
  75. //
  76. // // Fire an 'OnHello' event
  77. // Fire_OnHello(bHappy, bstrText);
  78. //
  79. // This class is derived from TCComEventsCP, which provides the functionality
  80. // for the (v-table) *interface* connection point. The additional
  81. // considerations for the *dispinterface* are included here and in the
  82. // TCComDualEventCall class. However, when firing an event using this class,
  83. // it will be fired to all of the *dispinterface* sinks /and/ to all of the
  84. // *interface* sinks.
  85. //
  86. // Parameters:
  87. // T - The class derived from TCComDualEventsCP.
  88. // IV - The v-table interface name.
  89. // piid - A constant pointer to the IID of the v-table interface, /IV/.
  90. // CPD - The dispatch connection point class which serves as a base class.
  91. //
  92. // See Also: BEGIN_TCComDualEventsCP, BEGIN_TCComDualEventsCP_IID,
  93. // END_TCComDualEventsCP, TCComDualEventCP_Fn macros, TCComEventsCP
  94. template <class T, class IV, const IID* piid, class CPD>
  95. class ATL_NO_VTABLE TCComDualEventsCP :
  96. public TCComEventsCP<T, IV, piid>, public CPD
  97. {
  98. // Group=Types
  99. protected:
  100. // Declares a vector type of *IDispatch* pointers.
  101. typedef std::vector<IDispatch*> vector_disp;
  102. // Declares a vector iterator type for vector_disp.
  103. typedef vector_disp::iterator it_disp;
  104. // Overrides
  105. protected:
  106. virtual TC_WorkItemRelProc OnGetWorkItemRelProc();
  107. virtual void OnMessage(UINT idMsg, int cParams, LPARAM* rgParams);
  108. static void WINAPI ReleaseArgs(UINT idMsg, int cParams, LPARAM* rgParams);
  109. // Implementation
  110. protected:
  111. void FireEvents(TCComDualEventCall<IV>& call);
  112. void GetEventSinks(vector_vtbl& vec_vtbl, vector_disp& vec_disp);
  113. void RemoveFailedSink(HRESULT hr, IDispatch* pdisp);
  114. };
  115. /////////////////////////////////////////////////////////////////////////////
  116. // Group=Overrides
  117. /////////////////////////////////////////////////////////////////////////////
  118. // Returns the address of the static ReleaseArgs method.
  119. template <class T, class IV, const IID* piid, class CPD>
  120. TC_WorkItemRelProc TCComDualEventsCP<T, IV, piid, CPD>::OnGetWorkItemRelProc()
  121. {
  122. return ReleaseArgs;
  123. }
  124. /////////////////////////////////////////////////////////////////////////////
  125. // Uses the function call TCComDualEventCall::operator() of the class
  126. // derived from TCComDualEventCall.
  127. template <class T, class IV, const IID* piid, class CPD>
  128. void TCComDualEventsCP<T, IV, piid, CPD>::OnMessage(UINT idMsg, int cParams,
  129. LPARAM* rgParams)
  130. {
  131. switch (idMsg)
  132. {
  133. case e_idFireEvents:
  134. {
  135. // Get the call pointer from the parameter list
  136. assert(1 == cParams);
  137. TCComDualEventCall<IV>* pCall = (TCComDualEventCall<IV>*)rgParams[0];
  138. // Call FireEvents in the context of the utility thread
  139. assert(pCall);
  140. FireEvents(*pCall);
  141. break;
  142. }
  143. }
  144. }
  145. /////////////////////////////////////////////////////////////////////////////
  146. // Deletes the object derived from TCComDualEventCall.
  147. template <class T, class IV, const IID* piid, class CPD>
  148. void TCComDualEventsCP<T, IV, piid, CPD>::ReleaseArgs(UINT idMsg,
  149. int cParams, LPARAM* rgParams)
  150. {
  151. switch (idMsg)
  152. {
  153. case e_idFireEvents:
  154. {
  155. // Get the call pointer from the parameter list
  156. assert(1 == cParams);
  157. TCComDualEventCall<IV>* pCall = (TCComDualEventCall<IV>*)rgParams[0];
  158. // Delete the call pointer
  159. assert(pCall);
  160. delete pCall;
  161. break;
  162. }
  163. }
  164. }
  165. /////////////////////////////////////////////////////////////////////////////
  166. // Group=Implementation
  167. /////////////////////////////////////////////////////////////////////////////
  168. // Description: Fires the event to all connected sinks.
  169. //
  170. // Remarks: This method is used by the TCComDualEventCP_Fn macros to fire
  171. // the specified event to all connected sinks. The event is specified as a
  172. // reference to an TCComDualEventCall-derived class instance.
  173. //
  174. // Parameters:
  175. // call - A reference to an instance of a class derived from
  176. // TCComDualEventCall. This class is derived automatically by the
  177. // TCComDualEventCP_Fn macros.
  178. //
  179. // See Also: TCComDualEventCP_Fn macros, TCComDualEventCall,
  180. // TCComEventsCP::FireEvents
  181. template <class T, class IV, const IID* piid, class CPD>
  182. void TCComDualEventsCP<T, IV, piid, CPD>::FireEvents(
  183. TCComDualEventCall<IV>& call)
  184. {
  185. // Copy all of the vtable and IDispatch sinks
  186. vector_vtbl vec_vtbl;
  187. vector_disp vec_disp;
  188. GetEventSinks(vec_vtbl, vec_disp);
  189. // Typedef the call object base classes
  190. typedef TCComEventCall<IV> EC;
  191. typedef TCComDualEventCall<IV> DEC;
  192. // Notify all vtable event sinks
  193. HRESULT hr;
  194. for (it_vtbl it_v = vec_vtbl.begin(); it_v != vec_vtbl.end(); ++it_v)
  195. if (FAILED(hr = static_cast<EC&>(call)(*it_v)))
  196. TCComEventsCP<T, IV, piid>::RemoveFailedSink(hr, *it_v);
  197. // Notify all IDispatch event sinks
  198. for (it_disp it_d = vec_disp.begin(); it_d != vec_disp.end(); ++it_d)
  199. if (FAILED(hr = static_cast<DEC&>(call)(*it_d)))
  200. RemoveFailedSink(hr, *it_d);
  201. }
  202. /////////////////////////////////////////////////////////////////////////////
  203. // Description: Copies the derived-class's event sinks to the specified
  204. // vectors.
  205. //
  206. // Parameters:
  207. // vec_vtbl - A reference to the vector where the v-table event sinks are
  208. // to be copied.
  209. // vec_disp - A reference to the vector where the *IDispatch* event sinks
  210. // are to be copied.
  211. //
  212. // See Also: TCComDualEventsCP::FireEvents, TCComEventsCP::GetEventSinks,
  213. // TCComEventsCP::GetEventSinks
  214. template <class T, class IV, const IID* piid, class CPD>
  215. inline void TCComDualEventsCP<T, IV, piid, CPD>::GetEventSinks(
  216. TCComDualEventsCP<T, IV, piid, CPD>::vector_vtbl& vec_vtbl,
  217. TCComDualEventsCP<T, IV, piid, CPD>::vector_disp& vec_disp)
  218. {
  219. // Lock the object (just long enough to copy the event sinks)
  220. TCObjectLock<T> lock(static_cast<T*>(this));
  221. // Copy the vtable sinks to the specified vec_vtbl
  222. TCComEventsCP<T, IV, piid>::GetEventSinks(vec_vtbl);
  223. // Transform the IDispatch sinks to the specified vec_disp
  224. CComDynamicUnkArray& vec_d = static_cast<CPD*>(this)->m_vec;
  225. vec_disp.resize(vec_d.end() - vec_d.begin(), NULL);
  226. it_disp itDest = vec_disp.begin();
  227. for (IUnknown** itSrc = vec_d.begin(); itSrc != vec_d.end(); ++itSrc, ++itDest)
  228. *itDest = static_cast<IDispatch*>(*itSrc);
  229. }
  230. /////////////////////////////////////////////////////////////////////////////
  231. // Description: Removes an event sink if an event call failed.
  232. //
  233. // Parameters:
  234. // hr - The HRESULT of the failed event call.
  235. // pdisp - The *IDispatch* pointer of the sink that failed.
  236. //
  237. // See Also: TCComDualEventsCP::FireEvents, TCComEventsCP::RemoveFailedSink,
  238. // TCComEventsCP::RemoveFailedSink
  239. template <class T, class IV, const IID* piid, class CPD>
  240. void TCComDualEventsCP<T, IV, piid, CPD>::RemoveFailedSink(HRESULT hr,
  241. IDispatch* pdisp)
  242. {
  243. // Cast to the appropriate connection point
  244. CPD* pCP = static_cast<CPD*>(this);
  245. // Use the CP vector to convert the interface pointer to a cookie
  246. DWORD dwCookie = pCP->m_vec.GetCookie((IUnknown**)&pdisp);
  247. // Unadvise the failed connection point sink
  248. pCP->Unadvise(dwCookie);
  249. }
  250. /////////////////////////////////////////////////////////////////////////////
  251. // Group=
  252. /////////////////////////////////////////////////////////////////////////////
  253. // Sanity Macros
  254. /////////////////////////////////////////////////////////////////////////////
  255. // Macro Group: BEGIN_TCComDualEventsCP, BEGIN_TCComDualEventsCP_IID,
  256. // END_TCComDualEventsCP
  257. //
  258. // Declaration:
  259. // #define BEGIN_TCComDualEventsCP(className, IV, IID_disp) \
  260. // BEGIN_TCComDualEventsCP_IID(className, IV, IID_##IV, IID_disp)
  261. // …
  262. // #define BEGIN_TCComDualEventsCP_IID(className, IV, IID_vtbl, IID_disp) \
  263. // template <class T> class ATL_NO_VTABLE className : \
  264. // public TCComDualEventsCP<T, IV, &IID_vtbl, \
  265. // IConnectionPointImpl<T, &IID_disp> > \
  266. // { \
  267. // protected: \
  268. // typedef TCComDualEventsCP<T, IV, &IID_vtbl, \
  269. // IConnectionPointImpl<T, &IID_disp> >::TIV TIV; \
  270. // typedef TCComDualEventsCP<T, IV, &IID_vtbl, \
  271. // IConnectionPointImpl<T, &IID_disp> >::PIV PIV;
  272. // …
  273. // #define END_TCComDualEventsCP() \
  274. // };
  275. //
  276. // Parameters:
  277. // className - The name of the connection point class that is being
  278. // declared.
  279. // IV - The name of the v-table *interface* which the connection point
  280. // represents.
  281. // IID_vtbl - The IID of the v-table *interface* which the connection point
  282. // represents.
  283. // IID_disp - The IID of the *dispinterface* which the connection point
  284. // represents.
  285. //
  286. // Remarks: These macros declare a class derived from the TCComDualEventsCP
  287. // template. Their use is not mandatory, but does simplify the entire
  288. // declaration of such a connection point class. Either macro should be
  289. // followed by 0, 1, or more instances of the TCComDualEventCP_Fn macros,
  290. // followed by an ending brace (}) and semi-colon (;). See the
  291. // TCComDualEventsCP class overview for an example and more details.
  292. //
  293. // See Also: TCComDualEventsCP, TCComDualEventCP_Fn macros
  294. #define BEGIN_TCComDualEventsCP(className, IV, IID_disp) \
  295. BEGIN_TCComDualEventsCP_IID(className, IV, IID_##IV, IID_disp)
  296. /////////////////////////////////////////////////////////////////////////////
  297. // {partof:BEGIN_TCComDualEventsCP}
  298. #define BEGIN_TCComDualEventsCP_IID(className, IV, IID_vtbl, IID_disp) \
  299. template <class T> class ATL_NO_VTABLE className : \
  300. public TCComDualEventsCP<T, IV, &IID_vtbl, \
  301. IConnectionPointImpl<T, &IID_disp> > \
  302. { \
  303. protected: \
  304. typedef TCComDualEventsCP<T, IV, &IID_vtbl, \
  305. IConnectionPointImpl<T, &IID_disp> >::TIV TIV; \
  306. typedef TCComDualEventsCP<T, IV, &IID_vtbl, \
  307. IConnectionPointImpl<T, &IID_disp> >::PIV PIV;
  308. /////////////////////////////////////////////////////////////////////////////
  309. // {partof:BEGIN_TCComDualEventsCP}
  310. #define END_TCComDualEventsCP() \
  311. };
  312. #ifdef _DOCJET_ONLY
  313. ///////////////////////////////////////////////////////////////////////////
  314. // Macro Group: TCComDualEventCP_Fn Group of Macros
  315. //
  316. // Declaration:
  317. // #define TCComDualEventCP_Fn0(fnName, dispid)
  318. // #define TCComDualEventCP_Fn1(fnName, dispid, t1,vt1)
  319. // #define TCComDualEventCP_Fn2(fnName, dispid, t1,vt1, t2,vt2)
  320. // #define TCComDualEventCP_Fn3(fnName, dispid, t1,vt1, t2,vt2, t3,vt3)
  321. // #define TCComDualEventCP_Fn4(fnName, dispid, t1,vt1, t2,vt2, t3,vt3,
  322. // t4,vt4)
  323. // #define TCComDualEventCP_Fn5(fnName, dispid, t1,vt1, t2,vt2, t3,vt3,
  324. // t4,vt4, t5,vt5)
  325. // #define TCComDualEventCP_Fn6(fnName, dispid, t1,vt1, t2,vt2, t3,vt3,
  326. // t4,vt4, t5,vt5, t6,vt6)
  327. // #define TCComDualEventCP_Fn7(fnName, dispid, t1,vt1, t2,vt2, t3,vt3,
  328. // t4,vt4, t5,vt5, t6,vt6, t7,vt7)
  329. // #define TCComDualEventCP_Fn8(fnName, dispid, t1,vt1, t2,vt2, t3,vt3,
  330. // t4,vt4, t5,vt5, t6,vt6, t7,vt7, t8,vt8)
  331. // #define TCComDualEventCP_Fn9(fnName, dispid, t1,vt1, t2,vt2, t3,vt3,
  332. // t4,vt4, t5,vt5, t6,vt6, t7,vt7, t8,vt8, t9,vt9)
  333. // #define TCComDualEventCP_Fn10(fnName, dispid, t1,vt1, t2,vt2, t3,vt3,
  334. // t4,vt4, t5,vt5, t6,vt6, t7,vt7, t8,vt8, t9,vt9, t10,vt10)
  335. // #define TCComDualEventCP_Fn11(fnName, dispid, t1,vt1, t2,vt2, t3,vt3,
  336. // t4,vt4, t5,vt5, t6,vt6, t7,vt7, t8,vt8, t9,vt9, t10,vt10,
  337. // t11,vt11)
  338. // #define TCComDualEventCP_Fn12(fnName, dispid, t1,vt1, t2,vt2, t3,vt3,
  339. // t4,vt4, t5,vt5, t6,vt6, t7,vt7, t8,vt8, t9,vt9, t10,vt10,
  340. // t11,vt11, t12,vt12)
  341. //
  342. // Parameters:
  343. // fnName - The event name. This must match the name of the event in the
  344. // v-table *interface*.
  345. // dispid - The dispatch ID of the event in the *dispinterface*.
  346. // t1_thru_t12 - The C++ parameter types of the event arguments. These
  347. // must match the parameter types of the event in the v-table *interface*.
  348. // These must be the C++ equivalents of [oleautomation] compatible types.
  349. // vt1_thru_vt12 - The *VT_* variant types of the event arguments. These
  350. // must be the variant type of the associated /t1/ thru /t12/ argument.
  351. // These must be [oleautomation] compatible variant types.
  352. //
  353. // Remarks: These macros all perform the same function and are different
  354. // only in that they specify an event with a different number of arguments.
  355. // For each event argument, both the C++ type and the *VT_* variant type
  356. // must be specified, in that order.
  357. //
  358. // An inline member function, named by prefixing *Fire_* to the
  359. // /fnName/ parameter, is declared by each of these macros. The member
  360. // function is prototyped to take the /t/ parameters, if any. The member
  361. // function will fire the event to all of the connected sinks of both the
  362. // *dispinterface* and the v-table *interface* connection points. Actually,
  363. // the TCUtilityThread class is used to post the event firing process as an
  364. // element of work to be performed in the context of the shared utility
  365. // thread. As such, the *Fire_* methods are prototyped with a void return
  366. // type. Currently, receiving a result or an [out] parameter from a
  367. // connected sink is not supported.
  368. //
  369. // Internally, the macros derive a class from TCComDualEventCall, to hold
  370. // the arguments of the event call, if any. The /t1/ thru /t12/ and
  371. // /p1/ thru /p12/ macro parameters are used to create and initialize this
  372. // nested class appropriately. The DECLARE_CTOR macros are used to declare
  373. // appropriate member variables and constructors that initialize those
  374. // variables.
  375. #define TCComDualEventCP_Fn
  376. #endif // _DOCJET_ONLY
  377. /////////////////////////////////////////////////////////////////////////////
  378. // {partof:TCComDualEventCP_Fn}
  379. #define TCComDualEventCP_Fn0(fnName, dispid) \
  380. class CCall##fnName : public TCComDualEventCall<TIV> \
  381. { \
  382. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  383. { \
  384. return pvtbl->##fnName(); \
  385. } \
  386. public: virtual void OnCreateDispParams() \
  387. { \
  388. SetDispParams(dispid, 0); \
  389. } \
  390. }; \
  391. public: inline void Fire_##fnName() \
  392. { \
  393. CCall##fnName* pCall = new CCall##fnName; \
  394. pCall->SetEventName(#fnName); \
  395. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  396. }
  397. /////////////////////////////////////////////////////////////////////////////
  398. // {partof:TCComDualEventCP_Fn}
  399. #define TCComDualEventCP_Fn1(fnName, dispid, t1, vt1) \
  400. class CCall##fnName : public TCComDualEventCall<TIV> \
  401. { \
  402. DECLARE_CTOR_1(CCall##fnName, t1) \
  403. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  404. { \
  405. return pvtbl->##fnName(m_a1); \
  406. } \
  407. public: virtual void OnCreateDispParams() \
  408. { \
  409. SetDispParams(dispid, 1, vt1, m_a1); \
  410. } \
  411. }; \
  412. public: inline void Fire_##fnName(t1 a1) \
  413. { \
  414. CCall##fnName* pCall = new CCall##fnName(a1); \
  415. pCall->SetEventName(#fnName); \
  416. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  417. }
  418. /////////////////////////////////////////////////////////////////////////////
  419. // {partof:TCComDualEventCP_Fn}
  420. #define TCComDualEventCP_Fn2(fnName, dispid, t1, vt1, t2, vt2) \
  421. class CCall##fnName : public TCComDualEventCall<TIV> \
  422. { \
  423. DECLARE_CTOR_2(CCall##fnName, t1, t2) \
  424. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  425. { \
  426. return pvtbl->##fnName(m_a1, m_a2); \
  427. } \
  428. public: virtual void OnCreateDispParams() \
  429. { \
  430. SetDispParams(dispid, 2, vt1, m_a1, vt2, m_a2); \
  431. } \
  432. }; \
  433. public: inline void Fire_##fnName(t1 a1, t2 a2) \
  434. { \
  435. CCall##fnName* pCall = new CCall##fnName(a1, a2); \
  436. pCall->SetEventName(#fnName); \
  437. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  438. }
  439. /////////////////////////////////////////////////////////////////////////////
  440. // {partof:TCComDualEventCP_Fn}
  441. #define TCComDualEventCP_Fn3(fnName, dispid, t1, vt1, t2, vt2, t3, vt3) \
  442. class CCall##fnName : public TCComDualEventCall<TIV> \
  443. { \
  444. DECLARE_CTOR_3(CCall##fnName, t1, t2, t3) \
  445. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  446. { \
  447. return pvtbl->##fnName(m_a1, m_a2, m_a3); \
  448. } \
  449. public: virtual void OnCreateDispParams() \
  450. { \
  451. SetDispParams(dispid, 3, vt1, m_a1, vt2, m_a2, vt3, m_a3); \
  452. } \
  453. }; \
  454. public: inline void Fire_##fnName(t1 a1, t2 a2, t3 a3) \
  455. { \
  456. CCall##fnName* pCall = new CCall##fnName(a1, a2, a3); \
  457. pCall->SetEventName(#fnName); \
  458. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  459. }
  460. /////////////////////////////////////////////////////////////////////////////
  461. // {partof:TCComDualEventCP_Fn}
  462. #define TCComDualEventCP_Fn4(fnName, dispid, t1, vt1, t2, vt2, t3, vt3, \
  463. t4, vt4) \
  464. class CCall##fnName : public TCComDualEventCall<TIV> \
  465. { \
  466. DECLARE_CTOR_4(CCall##fnName, t1, t2, t3, t4) \
  467. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  468. { \
  469. return pvtbl->##fnName(m_a1, m_a2, m_a3, m_a4); \
  470. } \
  471. public: virtual void OnCreateDispParams() \
  472. { \
  473. SetDispParams(dispid, 4, vt1, m_a1, vt2, m_a2, vt3, m_a3, \
  474. vt4, m_a4); \
  475. } \
  476. }; \
  477. public: inline void Fire_##fnName(t1 a1, t2 a2, t3 a3, t4 a4) \
  478. { \
  479. CCall##fnName* pCall = new CCall##fnName(a1, a2, a3, a4); \
  480. pCall->SetEventName(#fnName); \
  481. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  482. }
  483. /////////////////////////////////////////////////////////////////////////////
  484. // {partof:TCComDualEventCP_Fn}
  485. #define TCComDualEventCP_Fn5(fnName, dispid, t1, vt1, t2, vt2, t3, vt3, \
  486. t4, vt4, t5, vt5) \
  487. class CCall##fnName : public TCComDualEventCall<TIV> \
  488. { \
  489. DECLARE_CTOR_5(CCall##fnName, t1, t2, t3, t4, t5) \
  490. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  491. { \
  492. return pvtbl->##fnName(m_a1, m_a2, m_a3, m_a4, m_a5); \
  493. } \
  494. public: virtual void OnCreateDispParams() \
  495. { \
  496. SetDispParams(dispid, 5, vt1, m_a1, vt2, m_a2, vt3, m_a3, \
  497. vt4, m_a4, vt5, m_a5); \
  498. } \
  499. }; \
  500. public: inline void Fire_##fnName(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \
  501. { \
  502. CCall##fnName* pCall = new CCall##fnName(a1, a2, a3, a4, a5); \
  503. pCall->SetEventName(#fnName); \
  504. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  505. }
  506. /////////////////////////////////////////////////////////////////////////////
  507. // {partof:TCComDualEventCP_Fn}
  508. #define TCComDualEventCP_Fn6(fnName, dispid, t1, vt1, t2, vt2, t3, vt3, \
  509. t4, vt4, t5, vt5, t6, vt6) \
  510. class CCall##fnName : public TCComDualEventCall<TIV> \
  511. { \
  512. DECLARE_CTOR_6(CCall##fnName, t1, t2, t3, t4, t5, t6) \
  513. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  514. { \
  515. return pvtbl->##fnName(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6); \
  516. } \
  517. public: virtual void OnCreateDispParams() \
  518. { \
  519. SetDispParams(dispid, 6, vt1, m_a1, vt2, m_a2, vt3, m_a3, \
  520. vt4, m_a4, vt5, m_a5, vt6, m_a6); \
  521. } \
  522. }; \
  523. public: inline void Fire_##fnName(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, \
  524. t6 a6) \
  525. { \
  526. CCall##fnName* pCall = new CCall##fnName(a1, a2, a3, a4, a5, a6); \
  527. pCall->SetEventName(#fnName); \
  528. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  529. }
  530. /////////////////////////////////////////////////////////////////////////////
  531. // {partof:TCComDualEventCP_Fn}
  532. #define TCComDualEventCP_Fn7(fnName, dispid, t1, vt1, t2, vt2, t3, vt3, \
  533. t4, vt4, t5, vt5, t6, vt6, t7, vt7) \
  534. class CCall##fnName : public TCComDualEventCall<TIV> \
  535. { \
  536. DECLARE_CTOR_7(CCall##fnName, t1, t2, t3, t4, t5, t6, t7) \
  537. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  538. { \
  539. return pvtbl->##fnName(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7); \
  540. } \
  541. public: virtual void OnCreateDispParams() \
  542. { \
  543. SetDispParams(dispid, 7, vt1, m_a1, vt2, m_a2, vt3, m_a3, \
  544. vt4, m_a4, vt5, m_a5, vt6, m_a6, vt7, m_a7); \
  545. } \
  546. }; \
  547. public: inline void Fire_##fnName(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, \
  548. t6 a6, t7 a7) \
  549. { \
  550. CCall##fnName* pCall = new CCall##fnName(a1, a2, a3, a4, a5, a6, a7); \
  551. pCall->SetEventName(#fnName); \
  552. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  553. }
  554. /////////////////////////////////////////////////////////////////////////////
  555. // {partof:TCComDualEventCP_Fn}
  556. #define TCComDualEventCP_Fn8(fnName, dispid, t1, vt1, t2, vt2, t3, vt3, \
  557. t4, vt4, t5, vt5, t6, vt6, t7, vt7, t8, vt8) \
  558. class CCall##fnName : public TCComDualEventCall<TIV> \
  559. { \
  560. DECLARE_CTOR_8(CCall##fnName, t1, t2, t3, t4, t5, t6, t7, t8) \
  561. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  562. { \
  563. return pvtbl->##fnName(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7, \
  564. m_a8); \
  565. } \
  566. public: virtual void OnCreateDispParams() \
  567. { \
  568. SetDispParams(dispid, 8, vt1, m_a1, vt2, m_a2, vt3, m_a3, \
  569. vt4, m_a4, vt5, m_a5, vt6, m_a6, vt7, m_a7, vt8, m_a8); \
  570. } \
  571. }; \
  572. public: inline void Fire_##fnName(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, \
  573. t6 a6, t7 a7, t8 a8) \
  574. { \
  575. CCall##fnName* pCall = new CCall##fnName(a1, a2, a3, a4, a5, a6, a7, \
  576. a8); \
  577. pCall->SetEventName(#fnName); \
  578. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  579. }
  580. /////////////////////////////////////////////////////////////////////////////
  581. // {partof:TCComDualEventCP_Fn}
  582. #define TCComDualEventCP_Fn9(fnName, dispid, t1, vt1, t2, vt2, t3, vt3, \
  583. t4, vt4, t5, vt5, t6, vt6, t7, vt7, t8, vt8, t9, vt9) \
  584. class CCall##fnName : public TCComDualEventCall<TIV> \
  585. { \
  586. DECLARE_CTOR_9(CCall##fnName, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
  587. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  588. { \
  589. return pvtbl->##fnName(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7, \
  590. m_a8, m_a9); \
  591. } \
  592. public: virtual void OnCreateDispParams() \
  593. { \
  594. SetDispParams(dispid, 9, vt1, m_a1, vt2, m_a2, vt3, m_a3, \
  595. vt4, m_a4, vt5, m_a5, vt6, m_a6, vt7, m_a7, vt8, m_a8, vt9, m_a9); \
  596. } \
  597. }; \
  598. public: inline void Fire_##fnName(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, \
  599. t6 a6, t7 a7, t8 a8, t9 a9) \
  600. { \
  601. CCall##fnName* pCall = new CCall##fnName(a1, a2, a3, a4, a5, a6, a7, \
  602. a8, a9); \
  603. pCall->SetEventName(#fnName); \
  604. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  605. }
  606. /////////////////////////////////////////////////////////////////////////////
  607. // {partof:TCComDualEventCP_Fn}
  608. #define TCComDualEventCP_Fn10(fnName, dispid, t1, vt1, t2, vt2, t3, vt3, \
  609. t4, vt4, t5, vt5, t6, vt6, t7, vt7, t8, vt8, t9, vt9, t10, vt10) \
  610. class CCall##fnName : public TCComDualEventCall<TIV> \
  611. { \
  612. DECLARE_CTOR_10(CCall##fnName, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) \
  613. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  614. { \
  615. return pvtbl->##fnName(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7, \
  616. m_a8, m_a9, m_a10); \
  617. } \
  618. public: virtual void OnCreateDispParams() \
  619. { \
  620. SetDispParams(dispid, 10, vt1, m_a1, vt2, m_a2, vt3, m_a3, \
  621. vt4, m_a4, vt5, m_a5, vt6, m_a6, vt7, m_a7, vt8, m_a8, vt9, m_a9, \
  622. vt10, m_a10); \
  623. } \
  624. }; \
  625. public: inline void Fire_##fnName(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, \
  626. t6 a6, t7 a7, t8 a8, t9 a9, t10 a10) \
  627. { \
  628. CCall##fnName* pCall = new CCall##fnName(a1, a2, a3, a4, a5, a6, a7, \
  629. a8, a9, a10); \
  630. pCall->SetEventName(#fnName); \
  631. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  632. }
  633. /////////////////////////////////////////////////////////////////////////////
  634. // {partof:TCComDualEventCP_Fn}
  635. #define TCComDualEventCP_Fn11(fnName, dispid, t1, vt1, t2, vt2, t3, vt3, \
  636. t4, vt4, t5, vt5, t6, vt6, t7, vt7, t8, vt8, t9, vt9, t10, vt10, \
  637. t11, vt11) \
  638. class CCall##fnName : public TCComDualEventCall<TIV> \
  639. { \
  640. DECLARE_CTOR_11(CCall##fnName, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, \
  641. t11) \
  642. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  643. { \
  644. return pvtbl->##fnName(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7, \
  645. m_a8, m_a9, m_a10, m_a11); \
  646. } \
  647. public: virtual void OnCreateDispParams() \
  648. { \
  649. SetDispParams(dispid, 11, vt1, m_a1, vt2, m_a2, vt3, m_a3, \
  650. vt4, m_a4, vt5, m_a5, vt6, m_a6, vt7, m_a7, vt8, m_a8, vt9, m_a9, \
  651. vt10, m_a10, vt11, m_a11); \
  652. } \
  653. }; \
  654. public: inline void Fire_##fnName(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, \
  655. t6 a6, t7 a7, t8 a8, t9 a9, t10 a10, t11 a11) \
  656. { \
  657. CCall##fnName* pCall = new CCall##fnName(a1, a2, a3, a4, a5, a6, a7, \
  658. a8, a9, a10, a11); \
  659. pCall->SetEventName(#fnName); \
  660. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  661. }
  662. /////////////////////////////////////////////////////////////////////////////
  663. // {partof:TCComDualEventCP_Fn}
  664. #define TCComDualEventCP_Fn12(fnName, dispid, t1, vt1, t2, vt2, t3, vt3, \
  665. t4, vt4, t5, vt5, t6, vt6, t7, vt7, t8, vt8, t9, vt9, t10, vt10, \
  666. t11, vt11, t12, vt12) \
  667. class CCall##fnName : public TCComDualEventCall<TIV> \
  668. { \
  669. DECLARE_CTOR_12(CCall##fnName, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, \
  670. t11, t12) \
  671. public: virtual HRESULT OnCallEventSink(PIV pvtbl) \
  672. { \
  673. return pvtbl->##fnName(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6, m_a7, \
  674. m_a8, m_a9, m_a10, m_a11, m_a12); \
  675. } \
  676. public: virtual void OnCreateDispParams() \
  677. { \
  678. SetDispParams(dispid, 12, vt1, m_a1, vt2, m_a2, vt3, m_a3, \
  679. vt4, m_a4, vt5, m_a5, vt6, m_a6, vt7, m_a7, vt8, m_a8, vt9, m_a9, \
  680. vt10, m_a10, vt11, m_a11, vt12, m_a12); \
  681. } \
  682. }; \
  683. public: inline void Fire_##fnName(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, \
  684. t6 a6, t7 a7, t8 a8, t9 a9, t10 a10, t11 a11, t12 a12) \
  685. { \
  686. CCall##fnName* pCall = new CCall##fnName(a1, a2, a3, a4, a5, a6, a7, \
  687. a8, a9, a10, a11, a12); \
  688. pCall->SetEventName(#fnName); \
  689. PostMessage(e_idFireEvents, 1, LPARAM(pCall)); \
  690. }
  691. /////////////////////////////////////////////////////////////////////////////
  692. #endif // !__DualEventsCP_h__