Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

327 lines
13 KiB

  1. //=--------------------------------------------------------------------------=
  2. // AutomationObject.H
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // all of our objects will inherit from this class to share as much of the same
  13. // code as possible. this super-class contains the unknown and dispatch
  14. // implementations for them.
  15. //
  16. #ifndef _AUTOMATIONOBJECT_H_
  17. #include "Unknown.H" // for aggregating unknown
  18. #include <olectl.h> // for connection point stuff
  19. //=--------------------------------------------------------------------------=
  20. // the constants in this header file uniquely identify your automation objects.
  21. // make sure that for each object you have in the g_ObjectInfo table, you have
  22. // a constant in this header file.
  23. //
  24. #include "LocalSrv.H"
  25. //=--------------------------------------------------------------------------=
  26. // Misc constants
  27. //=--------------------------------------------------------------------------=
  28. // maximum number of arguments that can be sent to FireEvent()
  29. //
  30. #define MAX_ARGS 32
  31. // for the types of sinks that the COleControl class has. you shouldn't ever
  32. // need to use these
  33. //
  34. #define SINK_TYPE_EVENT 0
  35. #define SINK_TYPE_PROPNOTIFY 1
  36. //=--------------------------------------------------------------------------=
  37. // Structures
  38. //=--------------------------------------------------------------------------=
  39. // describes an event
  40. //
  41. typedef struct tagEVENTINFO {
  42. DISPID dispid; // dispid of the event
  43. int cParameters; // number of arguments to the event
  44. VARTYPE *rgTypes; // type of each argument
  45. } EVENTINFO;
  46. // This is a helper structure that you can use to help verify that the
  47. // Data1_ #define's match up with the interfaces they represent.
  48. // In your code declare an array as follows:
  49. //
  50. // #ifdef DEBUG
  51. //
  52. // GUIDDATA1_COMPARE g_gdMyControl [] = {
  53. // { Data1_MyControlInterface, &IID_IMyControlInterface.Data1 },
  54. // { Data1_MySubObject, &IID_IMySubObject.Data1 },
  55. // {0, 0}, // Mark the end of the array
  56. // };
  57. // #endif
  58. //
  59. // In your InternalQueryInterface function, make a call to the framework
  60. // helper function DebugVerifyData1Guids as follows:
  61. //
  62. // #ifdef DEBUG
  63. // DebugVerifyData1Guids(g_gdMyControl);
  64. // #endif
  65. //
  66. #ifdef DEBUG
  67. struct GUIDDATA1_COMPARE
  68. {
  69. DWORD dwData1a;
  70. DWORD *pdwData1b;
  71. };
  72. void DebugVerifyData1Guids(GUIDDATA1_COMPARE *pGuidData1_Compare);
  73. #endif
  74. //=--------------------------------------------------------------------------=
  75. // AUTOMATIONOBJECTINFO
  76. //=--------------------------------------------------------------------------=
  77. // for each automation object type you wish to expose to the programmer/user
  78. // that is not a control, you must fill out one of these structures. if the
  79. // object isn't CoCreatable, then the first four fields should be empty.
  80. // otherwise, they should be filled in with the appropriate information.
  81. // use the macro DEFINE_AUTOMATIONOBJECT to both declare and define your object.
  82. // make sure you have an entry in the global table of objects, g_ObjectInfo
  83. // in the main .Cpp file for your InProc server.
  84. //
  85. typedef struct {
  86. UNKNOWNOBJECTINFO unknowninfo; // fill in with 0's if we're not CoCreatable
  87. long lVersion; // Version number of Object. ONLY USE IF YOU'RE CoCreatable!
  88. long lVersionMinor; // minor version number
  89. const IID *riid; // object's type
  90. const IID *riidEvents; // if it has events
  91. LPCSTR pszHelpFile; // the helpfile for this automation object.
  92. ITypeInfo *pTypeInfo; // typeinfo for this object
  93. UINT cTypeInfo; // number of refs to the type info
  94. } AUTOMATIONOBJECTINFO;
  95. // macros to manipulate the AUTOMATIONOBJECTINFO in the global table table.
  96. //
  97. #define VERSIONOFOBJECT(index) ((AUTOMATIONOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->lVersion
  98. #define VERSIONMINOROFOBJECT(index) ((AUTOMATIONOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->lVersionMinor
  99. #define INTERFACEOFOBJECT(index) (*(((AUTOMATIONOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->riid))
  100. #define EVENTIIDOFOBJECT(index) (*(((AUTOMATIONOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->riidEvents))
  101. #define PPTYPEINFOOFOBJECT(index) &((((AUTOMATIONOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pTypeInfo))
  102. #define PTYPEINFOOFOBJECT(index) ((AUTOMATIONOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pTypeInfo
  103. #define CTYPEINFOOFOBJECT(index) ((AUTOMATIONOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->cTypeInfo
  104. #define HELPFILEOFOBJECT(index) ((AUTOMATIONOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pszHelpFile
  105. #define ISVALIDEVENTIID(index) (((AUTOMATIONOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->riidEvents != NULL)
  106. #ifndef INITOBJECTS
  107. #define DEFINE_AUTOMATIONOBJECT(name, clsid, objname, fn, ver, riid, pszh) \
  108. extern AUTOMATIONOBJECTINFO name##Object \
  109. #define DEFINE_AUTOMATIONOBJECTWEVENTS(name, clsid, objname, fn, ver, riid, piide, pszh) \
  110. extern AUTOMATIONOBJECTINFO name##Object \
  111. #define DEFINE_AUTOMATIONOBJECT2(name, clsid, objname, lblname, fn, ver, vermin, riid, pszh, fthreadsafe) \
  112. extern AUTOMATIONOBJECTINFO name##Object \
  113. #define DEFINE_AUTOMATIONOBJECTWEVENTS2(name, clsid, objname, lblname, fn, ver, vermin, riid, piide, pszh, fthreadsafe) \
  114. extern AUTOMATIONOBJECTINFO name##Object \
  115. #define DEFINE_AUTOMATIONOBJECT3(name, clsid, objname, lblname, precreatefn, fn, ver, vermin, riid, pszh, fthreadsafe) \
  116. extern AUTOMATIONOBJECTINFO name##Object \
  117. #define DEFINE_AUTOMATIONOBJECTWEVENTS3(name, clsid, objname, lblname, precreatefn, fn, ver, vermin, riid, piide, pszh, fthreadsafe) \
  118. extern AUTOMATIONOBJECTINFO name##Object \
  119. #else
  120. #define DEFINE_AUTOMATIONOBJECT(name, clsid, objname, fn, ver, riid, pszh) \
  121. AUTOMATIONOBJECTINFO name##Object = { { clsid, objname, NULL, TRUE, fn, NULL }, ver, 0, riid, NULL, pszh, NULL, 0} \
  122. #define DEFINE_AUTOMATIONOBJECTWEVENTS(name, clsid, objname, fn, ver, riid, piide, pszh) \
  123. AUTOMATIONOBJECTINFO name##Object = { { clsid, objname, NULL, TRUE, fn, NULL }, ver, 0, riid, piide, pszh, NULL, 0} \
  124. #define DEFINE_AUTOMATIONOBJECT2(name, clsid, objname, lblname, fn, ver, vermin, riid, pszh, fthreadsafe) \
  125. AUTOMATIONOBJECTINFO name##Object = { { clsid, objname, lblname, fthreadsafe, fn, NULL }, ver, vermin, riid, NULL, pszh, NULL, 0} \
  126. #define DEFINE_AUTOMATIONOBJECTWEVENTS2(name, clsid, objname, lblname, fn, ver, vermin, riid, piide, pszh, fthreadsafe) \
  127. AUTOMATIONOBJECTINFO name##Object = { { clsid, objname, lblname, fthreadsafe, fn, NULL }, ver, vermin, riid, piide, pszh, NULL, 0} \
  128. #define DEFINE_AUTOMATIONOBJECT3(name, clsid, objname, lblname, precreatefn, fn, ver, vermin, riid, pszh, fthreadsafe) \
  129. AUTOMATIONOBJECTINFO name##Object = { { clsid, objname, lblname, fthreadsafe, fn, precreatefn }, ver, vermin, riid, NULL, pszh, NULL, 0} \
  130. #define DEFINE_AUTOMATIONOBJECTWEVENTS3(name, clsid, objname, lblname, precreatefn, fn, ver, vermin, riid, piide, pszh, fthreadsafe) \
  131. AUTOMATIONOBJECTINFO name##Object = { { clsid, objname, lblname, fthreadsafe, fn, precreatefn }, ver, vermin, riid, piide, pszh, NULL, 0} \
  132. #endif // INITOBJECTS
  133. //=--------------------------------------------------------------------------=
  134. // Standard Dispatch and SupportErrorInfo
  135. //=--------------------------------------------------------------------------=
  136. // all objects should declare these in their class definitions so that they
  137. // get standard implementations of IDispatch and ISupportErrorInfo.
  138. //
  139. #define DECLARE_STANDARD_DISPATCH() \
  140. STDMETHOD(GetTypeInfoCount)(UINT *pctinfo) { \
  141. return CAutomationObject::GetTypeInfoCount(pctinfo); \
  142. } \
  143. STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo **ppTypeInfoOut) { \
  144. return CAutomationObject::GetTypeInfo(itinfo, lcid, ppTypeInfoOut); \
  145. } \
  146. STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR **rgszNames, UINT cnames, LCID lcid, DISPID *rgdispid) { \
  147. return CAutomationObject::GetIDsOfNames(riid, rgszNames, cnames, lcid, rgdispid); \
  148. } \
  149. STDMETHOD(Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pVarResult, EXCEPINFO *pexcepinfo, UINT *puArgErr) { \
  150. return CAutomationObject::Invoke(dispid, riid, lcid, wFlags, pdispparams, pVarResult, pexcepinfo, puArgErr); \
  151. } \
  152. #define DECLARE_STANDARD_SUPPORTERRORINFO() \
  153. STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) { \
  154. return CAutomationObject::InterfaceSupportsErrorInfo(riid); \
  155. } \
  156. //=--------------------------------------------------------------------------=
  157. // CAutomationObject
  158. //=--------------------------------------------------------------------------=
  159. // global class that all automation objects can inherit from to give them a
  160. // bunch of implementation for free, namely IDispatch and ISupportsErrorInfo
  161. //
  162. //
  163. class CAutomationObject : public CUnknownObject {
  164. public:
  165. // aggreation query interface support
  166. //
  167. virtual HRESULT InternalQueryInterface(REFIID riid, void **ppvObjOut);
  168. // IDispatch methods
  169. //
  170. STDMETHOD(GetTypeInfoCount)(UINT *);
  171. STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo **);
  172. STDMETHOD(GetIDsOfNames)(REFIID, OLECHAR **, UINT, LCID, DISPID *);
  173. STDMETHOD(Invoke)(DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *);
  174. // ISupportErrorInfo methods
  175. //
  176. STDMETHOD(InterfaceSupportsErrorInfo)(REFIID);
  177. CAutomationObject(IUnknown *, int , void *);
  178. virtual ~CAutomationObject();
  179. // callable functions -- things that most people will find useful.
  180. //
  181. virtual HINSTANCE GetResourceHandle(void);
  182. virtual HRESULT Exception(HRESULT hr, WORD idException, DWORD dwHelpContextID);
  183. virtual HRESULT Exception(HRESULT hr, LPWSTR wszException, DWORD dwHelpContextID);
  184. protected:
  185. // member variables that derived objects might need to get at information in the
  186. // global object table
  187. //
  188. int m_ObjectType;
  189. #ifdef MDAC_BUILD
  190. const CLSID *m_pTypeLibId;
  191. #endif
  192. private:
  193. // member variables we don't share.
  194. //
  195. BYTE m_fLoadedTypeInfo;
  196. };
  197. //=--------------------------------------------------------------------------=
  198. // CAutomationObjectWEvents
  199. //=--------------------------------------------------------------------------=
  200. // a slightly modified version of CAutomationObject that supports event
  201. // firing
  202. //
  203. class CAutomationObjectWEvents : public CAutomationObject,
  204. public IConnectionPointContainer {
  205. public:
  206. // aggreation query interface support
  207. //
  208. virtual HRESULT InternalQueryInterface(REFIID riid, void **ppvObjOut);
  209. // we have to declare this since IConnectionPointContainer inherits
  210. // from IUnknown
  211. //
  212. DECLARE_STANDARD_UNKNOWN();
  213. // IConnectionPointContainer methods
  214. //
  215. STDMETHOD(EnumConnectionPoints)(LPENUMCONNECTIONPOINTS FAR* ppEnum);
  216. STDMETHOD(FindConnectionPoint)(REFIID iid, LPCONNECTIONPOINT FAR* ppCP);
  217. // how everybody will fire an event
  218. //
  219. void __cdecl FireEvent(EVENTINFO * pEventInfo, ...);
  220. // whether it's necessary to fire the event
  221. BOOL FFireEvent() { return m_cpEvents.m_rgSinks != NULL; }
  222. CAutomationObjectWEvents(IUnknown *, int , void *);
  223. virtual ~CAutomationObjectWEvents();
  224. protected:
  225. // nested class that will handle all of the connection point stuff
  226. //
  227. class CConnectionPoint : public IConnectionPoint {
  228. public:
  229. IUnknown **m_rgSinks;
  230. // IUnknown methods
  231. //
  232. STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj) ;
  233. STDMETHOD_(ULONG,AddRef)(THIS) ;
  234. STDMETHOD_(ULONG,Release)(THIS) ;
  235. // IConnectionPoint methods
  236. //
  237. STDMETHOD(GetConnectionInterface)(IID FAR* pIID);
  238. STDMETHOD(GetConnectionPointContainer)(IConnectionPointContainer FAR* FAR* ppCPC);
  239. STDMETHOD(Advise)(LPUNKNOWN pUnkSink, DWORD FAR* pdwCookie);
  240. STDMETHOD(Unadvise)(DWORD dwCookie);
  241. STDMETHOD(EnumConnections)(LPENUMCONNECTIONS FAR* ppEnum);
  242. void DoInvoke(DISPID dispid, DISPPARAMS * pdispparam);
  243. void DoOnChanged(DISPID dispid);
  244. BOOL DoOnRequestEdit(DISPID dispid);
  245. HRESULT AddSink(void *, DWORD *);
  246. CAutomationObjectWEvents *m_pObject();
  247. CConnectionPoint(BYTE b){
  248. m_bType = b;
  249. m_rgSinks = NULL;
  250. m_cSinks = 0;
  251. }
  252. ~CConnectionPoint();
  253. private:
  254. BYTE m_bType;
  255. short m_cSinks;
  256. } m_cpEvents, m_cpPropNotify;
  257. // so they can get at some of our protected things, like AddRef, QI, etc.
  258. //
  259. friend CConnectionPoint;
  260. };
  261. #define _AUTOMATIONOBJECT_H_
  262. #endif // _AUTOMATIONOBJECT_H_