Source code of Windows XP (NT5)
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.

337 lines
12 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File:
  4. // olecache.h
  5. //
  6. // Contents:
  7. // Better implementation of Ole presentation cache
  8. //
  9. // Classes:
  10. // COleCache - ole presentation cache
  11. // CCacheEnum - enumerator for COleCache
  12. //
  13. // Functions:
  14. //
  15. // History:
  16. // Gopalk Creation Aug 23, 1996
  17. //-----------------------------------------------------------------------------
  18. #ifndef _OLECACHE_H_
  19. #define _OLECACHE_H_
  20. #include <cachenod.h>
  21. #include <array.hxx>
  22. //+----------------------------------------------------------------------------
  23. //
  24. // Class:
  25. // COleCache
  26. //
  27. // Purpose:
  28. // Ole presentation cache maintains the presentations for
  29. // one embedding.
  30. //
  31. // For every unique FORMATETC, a cache node is created; cache
  32. // nodes encapsulate a presentation object and advise sink.
  33. //
  34. // COleCache handles persistence of cache nodes, saving (loading)
  35. // their presentation objects, format descriptions, and advise
  36. // options.
  37. //
  38. // Interface:
  39. // IUnknown (public IUnknown for aggregation purposes)
  40. // IOleCacheControl
  41. // IOleCache2
  42. // IPersistStorage
  43. // IViewObject2
  44. // IDataObject
  45. // m_UnkPrivate
  46. // the private IUnknown for aggregation purposes
  47. //
  48. // INTERNAL GetExtent(DWORD dwDrawAspect, LPSIZEL lpsizel);
  49. // returns the size of the aspect indicated
  50. //
  51. // Private Interface used by friend classes:
  52. // INTERNAL_(void) OnChange(DWORD dwAspect, LONG lindex,
  53. // BOOL fDirty);
  54. // CCacheNode instances use this to alert the cache to
  55. // changes to themselves so that the cache can be
  56. // marked dirty, if that is necessary
  57. // INTERNAL_(LPSTORAGE) GetStg(void);
  58. // CCacheNode uses this to obtain storage when cache
  59. // nodes are being saved
  60. //
  61. // INTERNAL_(void) DetachCacheEnum(CCacheEnum FAR* pCacheEnum);
  62. // When about to be destroyed, CCacheEnum instances
  63. // use this to request to be taken off
  64. // the list of cache enumerators that COleCache
  65. // maintains.
  66. //
  67. // Notes:
  68. // The constructor returns a pointer to the public IUnknown
  69. // of the object. The private one is available at m_UnkPrivate.
  70. //
  71. // The cache maintains its contents in an array. Ids of the
  72. // cache nodes, such as those returned from Cache(), start out
  73. // being the index of the node in the array. To detect
  74. // reuse of an array element, each id is incremented by the maximum
  75. // size of the array each time it is reused. To find an element by
  76. // id simply take (id % max_array_size). (id / max_array_size)
  77. // gives the number of times the array element has been used to
  78. // cache data. (We do not allocate all the array members at once,
  79. // but instead grow the array on demand, up to the maximum
  80. // compile-time array size, MAX_CACHELIST_ITEMS.)
  81. // If id's do not match
  82. // exactly, before taking the modulo value, we know that a
  83. // request has been made for an earlier generation of data that
  84. // no longer exists.
  85. //
  86. // The cache automatically maintains a "native format" node.
  87. // This node cannot be deleted by the user, and is always kept
  88. // up to date on disk. This node attempts to keep either a
  89. // CF_METAFILEPICT, or CF_DIB rendering, with preference in
  90. // this order.
  91. // REVIEW, it's not clear how this node ever gets loaded.
  92. //
  93. // History:
  94. // 31-Jan-95 t-ScottH add Dump method (_DEBUG only)
  95. // 11/15/93 - ChrisWe - file inspection and cleanup;
  96. // removed use of nested classes where possible;
  97. // got rid of obsolete declaration of GetOlePresStream;
  98. // moved presentation stream limits to ole2int.h;
  99. // coalesced many BOOL flags into a single unsigned
  100. // quantity
  101. //
  102. //-----------------------------------------------------------------------------
  103. // declare the array of cache node pointers
  104. // COleCache will maintain an array of these
  105. #define COLECACHEF_LOADEDSTATE 0x00000001
  106. #define COLECACHEF_NOSCRIBBLEMODE 0x00000002
  107. #define COLECACHEF_PBRUSHORMSDRAW 0x00000004
  108. #define COLECACHEF_STATIC 0x00000008
  109. #define COLECACHEF_FORMATKNOWN 0x00000010
  110. #define COLECACHEF_OUTOFMEMORY 0x00000020
  111. #define COLECACHEF_HANDSOFSTORAGE 0x00000040
  112. #define COLECACHEF_CLEANEDUP 0x00000080
  113. #define COLECACHEF_SAMEASLOAD 0x00000100
  114. #define COLECACHEF_APICREATE 0x00000200
  115. #ifdef _DEBUG
  116. // In debug builds, this flag is set if aggregated
  117. #define COLECACHEF_AGGREGATED 0x00001000
  118. #endif // _DEBUG
  119. // The following flag is used for clearing out native COLECACHE FLAGS.
  120. // Remember to update the following when native formats are either
  121. // added or removed
  122. #define COLECACHEF_NATIVEFLAGS (COLECACHEF_STATIC | \
  123. COLECACHEF_FORMATKNOWN | \
  124. COLECACHEF_PBRUSHORMSDRAW)
  125. // TOC signature
  126. #define TOCSIGNATURE 1229865294
  127. class COleCache : public IOleCacheControl, public IOleCache2,
  128. public IPersistStorage, public CRefExportCount,
  129. public CThreadCheck
  130. {
  131. public:
  132. COleCache(IUnknown* pUnkOuter, REFCLSID rclsid, DWORD dwCreateFlags=0);
  133. ~COleCache();
  134. // *** IUnknown methods ***
  135. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
  136. STDMETHOD_(ULONG,AddRef)(void) ;
  137. STDMETHOD_(ULONG,Release)(void);
  138. // *** IOleCacheControl methods ***
  139. STDMETHOD(OnRun)(LPDATAOBJECT pDataObject);
  140. STDMETHOD(OnStop)(void);
  141. // *** IOleCache methods ***
  142. STDMETHOD(Cache)(LPFORMATETC lpFormatetc, DWORD advf, LPDWORD lpdwCacheId);
  143. STDMETHOD(Uncache)(DWORD dwCacheId);
  144. STDMETHOD(EnumCache)(LPENUMSTATDATA* ppenumStatData);
  145. STDMETHOD(InitCache)(LPDATAOBJECT pDataObject);
  146. STDMETHOD(SetData)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium, BOOL fRelease);
  147. // *** IOleCache2 methods ***
  148. STDMETHOD(UpdateCache)(LPDATAOBJECT pDataObject, DWORD grfUpdf, LPVOID pReserved);
  149. STDMETHOD(DiscardCache)(DWORD dwDiscardOptions);
  150. // IPersist methods
  151. STDMETHOD(GetClassID)(LPCLSID pClassID);
  152. // IPersistStorage methods
  153. STDMETHOD(IsDirty)(void);
  154. STDMETHOD(InitNew)(LPSTORAGE pstg);
  155. STDMETHOD(Load)(LPSTORAGE pstg);
  156. STDMETHOD(Save)(LPSTORAGE pstgSave, BOOL fSameAsLoad);
  157. STDMETHOD(SaveCompleted)(LPSTORAGE pstgNew);
  158. STDMETHOD(HandsOffStorage)(void);
  159. // Other public methods, called by defhndlr and deflink
  160. HRESULT GetExtent(DWORD dwDrawAspect, LPSIZEL lpsizel);
  161. HRESULT Load(LPSTORAGE pstg, BOOL fCacheEmpty);
  162. HRESULT OnCrash();
  163. BOOL IsEmpty() {
  164. return(!m_pCacheArray->Length());
  165. }
  166. #ifdef _CHICAGO_
  167. static INTERNAL DrawStackSwitch(
  168. LPVOID *pCV,
  169. DWORD dwDrawAspect,
  170. LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd,
  171. HDC hicTargetDev, HDC hdcDraw,
  172. LPCRECTL lprcBounds,
  173. LPCRECTL lprcWBounds,
  174. BOOL (CALLBACK * pfnContinue)(ULONG_PTR),
  175. ULONG_PTR dwContinue);
  176. #endif
  177. // Private IUnknown used in aggregation.
  178. // This has been implemented as a nested class because of
  179. // the member name collisions with the outer IUnknown.
  180. class CCacheUnkImpl : public IUnknown
  181. {
  182. public:
  183. // *** IUnknown methods ***
  184. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
  185. STDMETHOD_(ULONG,AddRef)(void) ;
  186. STDMETHOD_(ULONG,Release)(void);
  187. };
  188. friend class CCacheUnkImpl;
  189. CCacheUnkImpl m_UnkPrivate; // vtable for private IUnknown
  190. // IDataObject implementation of the cache.
  191. // This has been implemented as a nested class because
  192. // IDataObject::SetData collides with IOleCache::SetData
  193. class CCacheDataImpl : public IDataObject
  194. {
  195. public:
  196. // IUnknown methods
  197. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
  198. STDMETHOD_(ULONG,AddRef)(void);
  199. STDMETHOD_(ULONG,Release)(void);
  200. // IDataObject methods
  201. STDMETHOD(GetData)(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium);
  202. STDMETHOD(GetDataHere)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium);
  203. STDMETHOD(QueryGetData)(LPFORMATETC pformatetc);
  204. STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pformatetc,
  205. LPFORMATETC pformatetcOut);
  206. STDMETHOD(SetData)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium, BOOL fRelease);
  207. STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC* ppenumFormatEtc);
  208. STDMETHOD(DAdvise)(FORMATETC* pFormatetc, DWORD advf, IAdviseSink* pAdvSink,
  209. DWORD* pdwConnection);
  210. STDMETHOD(DUnadvise)(DWORD dwConnection);
  211. STDMETHOD(EnumDAdvise)(LPENUMSTATDATA* ppenumAdvise);
  212. };
  213. friend class CCacheDataImpl;
  214. CCacheDataImpl m_Data; // vtable for IDataObject
  215. // Other public methods
  216. BOOL IsOutOfMemory() {
  217. return(m_ulFlags & COLECACHEF_OUTOFMEMORY);
  218. }
  219. private:
  220. // Private methods
  221. LPCACHENODE Locate(LPFORMATETC lpGivenForEtc, DWORD* lpdwCacheId=NULL);
  222. LPCACHENODE Locate(DWORD dwAspect, LONG lindex, DVTARGETDEVICE* ptd);
  223. LPCACHENODE UpdateCacheNodeForNative(void);
  224. void FindObjectFormat(LPSTORAGE pstg);
  225. HRESULT LoadTOC(LPSTREAM lpstream, LPSTORAGE pStg);
  226. HRESULT SaveTOC(LPSTORAGE pStg, BOOL fSameAsLoad);
  227. void AspectsUpdated(DWORD dwAspect);
  228. void CleanupFn(void);
  229. // IViewObject2 implementation of cache.
  230. // This has been implemented as a nested class because GetExtent
  231. // collides with the method on COleCache
  232. class CCacheViewImpl : public IViewObject2
  233. {
  234. public:
  235. // IUnknown methods
  236. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
  237. STDMETHOD_(ULONG,AddRef)(void);
  238. STDMETHOD_(ULONG,Release)(void);
  239. // IViewObject methods
  240. STDMETHOD(Draw)(DWORD dwDrawAspect, LONG lindex,
  241. void FAR* pvAspect, DVTARGETDEVICE FAR* ptd,
  242. HDC hicTargetDev, HDC hdcDraw,
  243. LPCRECTL lprcBounds,
  244. LPCRECTL lprcWBounds,
  245. BOOL(CALLBACK *pfnContinue)(ULONG_PTR),
  246. ULONG_PTR dwContinue);
  247. STDMETHOD(GetColorSet)(DWORD dwDrawAspect, LONG lindex, void* pvAspect,
  248. DVTARGETDEVICE* ptd, HDC hicTargetDev,
  249. LPLOGPALETTE* ppColorSet);
  250. STDMETHOD(Freeze)(DWORD dwDrawAspect, LONG lindex, void* pvAspect,
  251. DWORD* pdwFreeze);
  252. STDMETHOD(Unfreeze)(DWORD dwFreeze);
  253. STDMETHOD(SetAdvise)(DWORD aspects, DWORD advf, LPADVISESINK pAdvSink);
  254. STDMETHOD(GetAdvise)(DWORD* pAspects, DWORD* pAdvf, LPADVISESINK* ppAdvSink);
  255. // IViewObject2 methods
  256. STDMETHOD(GetExtent)(DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE* ptd,
  257. LPSIZEL lpsizel);
  258. #ifdef _CHICAGO_
  259. // private Draw method
  260. STDMETHOD(SSDraw)(DWORD dwDrawAspect, LONG lindex,
  261. void FAR* pvAspect, DVTARGETDEVICE FAR * ptd,
  262. HDC hicTargetDev, HDC hdcDraw,
  263. LPCRECTL lprcBounds,
  264. LPCRECTL lprcWBounds,
  265. BOOL (CALLBACK * pfnContinue)(ULONG_PTR),
  266. ULONG_PTR dwContinue);
  267. #endif
  268. };
  269. friend class CCacheViewImpl;
  270. CCacheViewImpl m_ViewObject; // vtable for IViewObject2
  271. // IAdviseSink implementation
  272. // This has been implemented as a nested class because of the need that
  273. // the QueryInterface method on the Advise Sink should not return
  274. // cache interfaces
  275. class CAdviseSinkImpl : public IAdviseSink
  276. {
  277. public:
  278. // IUnknown methods
  279. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
  280. STDMETHOD_(ULONG,AddRef)(void);
  281. STDMETHOD_(ULONG,Release)(void);
  282. // IAdviseSink methods
  283. STDMETHOD_(void,OnDataChange)(FORMATETC* pFormatetc, STGMEDIUM* pStgmed);
  284. STDMETHOD_(void,OnViewChange)(DWORD aspect, LONG lindex);
  285. STDMETHOD_(void,OnRename)(IMoniker* pmk);
  286. STDMETHOD_(void,OnSave)(void);
  287. STDMETHOD_(void,OnClose)(void);
  288. };
  289. friend class CAdviseSinkImpl;
  290. CAdviseSinkImpl m_AdviseSink;
  291. // Private member variables
  292. IUnknown* m_pUnkOuter; // Aggregating IUnknown
  293. LPSTORAGE m_pStg; // Storage for cache
  294. CLSID m_clsid; // CLSID of object
  295. CLIPFORMAT m_cfFormat; // Native clipformat of the object
  296. unsigned long m_ulFlags; // Cache flags
  297. CArray<CCacheNode>* m_pCacheArray; // Cache array
  298. IAdviseSink* m_pViewAdvSink; // IViewObject Advise Sink
  299. DWORD m_advfView; // IViewObject Advise control flags
  300. DWORD m_aspectsView; // Aspects notified for view changes
  301. DWORD m_dwFrozenAspects; // Frozen Aspects
  302. IDataObject* m_pDataObject; // non-NULL if running; not ref counted
  303. };
  304. #endif //_OLECACHE_H_