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.

329 lines
8.3 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1997 - 1999
  4. Module Name:
  5. CutAndPasteDataObject.h
  6. Abstract:
  7. Header file for the CCutAndPasteDataObject template class.
  8. This is an inline template class.
  9. Usage Notes:
  10. This template class can be used to enable cutting and pasting
  11. for a node.
  12. Override ATLsnap's CSnapInItem::GetDataObject and instead of
  13. passing back an IDataObject pointer on ATLsnap's CSnapInDataObjectImpl,
  14. pass back an IDataObject interface pointer on CCutAndPasteDataObject<CYourNode>.
  15. In order to use this template class, your node class must have the following:
  16. HRESULT FillText(LPSTGMEDIUM pSTM); // So our data can be pasted into any apps.
  17. HRESULT FillClipboardData(LPSTGMEDIUM pSTM);
  18. static CLIPFORMAT m_CCF_CUT_AND_PASTE_FORMAT;
  19. You should make sure that your static m_CCF_CUT_AND_PASTE_FORMAT is
  20. registered as a clipformat in some static function you call at snapin startup, e.g.
  21. static void InitClipboardFormat();
  22. Note that once you have these implemented, you will also need
  23. to set the MMC_VERB_COPY on your node.
  24. You must them set the MMC_VERB_PASTE node on the folder node into which
  25. you would like to paste the node you've copied. That folder node must
  26. also repond appropriately to the MMCN_QUERY_PASTE notification.
  27. To handle this notification properly, you may find it helpful to add
  28. a method to the copied node which will tell whether the IDataObject
  29. has a valid clipboard format, e.g.:
  30. static HRESULT IsClientClipboardData( IDataObject* pDataObj );
  31. Once you've told MMC your folder node can handle a paste, you will
  32. have to respond correctly to the MMCN_PASTE notification, and you
  33. may again find it helpful to implement a method on the copied node
  34. which can fill that node with data from the IDataObject, e.g.:
  35. HRESULT SetClientWithDataFromClipboard( IDataObject* pDataObject );
  36. Author:
  37. Michael A. Maguire 02/12/98
  38. Revision History:
  39. mmaguire 02/12/98 - abstracted from CClientDataObject
  40. --*/
  41. //////////////////////////////////////////////////////////////////////////////
  42. #if !defined(_IAS_CUT_AND_PASTE_DATA_OBJECT_H_)
  43. #define _IAS_CUT_AND_PASTE_DATA_OBJECT_H_
  44. //////////////////////////////////////////////////////////////////////////////
  45. // BEGIN INCLUDES
  46. //
  47. // where we can find what this class derives from:
  48. //
  49. //#include <atlctl.h> We've decided not to derive from ATL's IDataObjectImpl.
  50. //
  51. //
  52. // where we can find what this class has or uses:
  53. //
  54. //
  55. // END INCLUDES
  56. //////////////////////////////////////////////////////////////////////////////
  57. // Helper class used by class below.
  58. template <class NodeToBeCutAndPasted>
  59. class CCutAndPasteObjectData
  60. {
  61. public:
  62. NodeToBeCutAndPasted * m_pItem;
  63. DATA_OBJECT_TYPES m_type;
  64. };
  65. template <class NodeToBeCutAndPasted>
  66. class ATL_NO_VTABLE CCutAndPasteDataObject :
  67. public IDataObject
  68. , public CComObjectRoot
  69. {
  70. public:
  71. BEGIN_COM_MAP(CCutAndPasteDataObject<NodeToBeCutAndPasted>)
  72. COM_INTERFACE_ENTRY(IDataObject)
  73. END_COM_MAP()
  74. //////////////////////////////////////////////////////////////////////////////
  75. /*++
  76. CCutAndPasteDataObject::GetData
  77. This method is needed for spiffy clipboard functions.
  78. Purpose:
  79. Retrieves data described by a specific FormatEtc into a StgMedium
  80. allocated by this function. Used like GetClipboardData.
  81. Parameters:
  82. pFE LPFORMATETC describing the desired data.
  83. pSTM LPSTGMEDIUM in which to return the data.
  84. Return Value:
  85. HRESULT NOERROR or a general error value.
  86. --*/
  87. //////////////////////////////////////////////////////////////////////////////
  88. STDMETHOD(GetData)(FORMATETC *pFormatEtc, STGMEDIUM *pStorageMedium )
  89. {
  90. ATLTRACE(_T("CCutAndPasteDataObject::GetData\n"));
  91. HRESULT hr;
  92. UINT cf=pFormatEtc->cfFormat;
  93. // Check the aspects we support.
  94. // if (!(DVASPECT_CONTENT & pFE->dwAspect))
  95. // return ResultFromScode(DATA_E_FORMATETC);
  96. if( TYMED_HGLOBAL & pFormatEtc->tymed )
  97. {
  98. if( cf == CF_TEXT )
  99. {
  100. return hr = m_objectData.m_pItem->FillText( pStorageMedium );
  101. }
  102. if( cf == NodeToBeCutAndPasted::m_CCF_CUT_AND_PASTE_FORMAT )
  103. {
  104. return hr = m_objectData.m_pItem->FillClipboardData( pStorageMedium );
  105. }
  106. }
  107. return E_NOTIMPL;
  108. }
  109. //////////////////////////////////////////////////////////////////////////////
  110. /*++
  111. CCutAndPasteDataObject::GetDataHere
  112. This method is needed by MMC to do its usual work -- we are pretty much
  113. copying the ATLsnap.h implementation here.
  114. --*/
  115. //////////////////////////////////////////////////////////////////////////////
  116. STDMETHOD(GetDataHere)(FORMATETC* pformatetc, STGMEDIUM* pmedium)
  117. {
  118. ATLTRACE(_T("CCutAndPasteDataObject::GetDataHere\n"));
  119. if (pmedium == NULL)
  120. return E_POINTER;
  121. HRESULT hr = DV_E_TYMED;
  122. // Make sure the type medium is HGLOBAL
  123. if (pmedium->tymed == TYMED_HGLOBAL)
  124. {
  125. // Create the stream on the hGlobal passed in
  126. CComPtr<IStream> spStream;
  127. hr = CreateStreamOnHGlobal(pmedium->hGlobal, FALSE, &spStream);
  128. if (SUCCEEDED(hr))
  129. if (pformatetc->cfFormat == CSnapInItem::m_CCF_SNAPIN_GETOBJECTDATA)
  130. {
  131. hr = DV_E_CLIPFORMAT;
  132. ULONG uWritten;
  133. hr = spStream->Write(&m_objectData, sizeof(CObjectData), &uWritten);
  134. }
  135. else
  136. hr = m_objectData.m_pItem->FillData(pformatetc->cfFormat, spStream);
  137. }
  138. return hr;
  139. }
  140. STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */)
  141. {
  142. ATLTRACENOTIMPL(_T("CCutAndPasteDataObject::QueryGetData\n"));
  143. }
  144. STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */)
  145. {
  146. ATLTRACENOTIMPL(_T("CCutAndPasteDataObject::GetCanonicalFormatEtc\n"));
  147. }
  148. STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */)
  149. {
  150. ATLTRACENOTIMPL(_T("CCutAndPasteDataObject::SetData\n"));
  151. }
  152. //////////////////////////////////////////////////////////////////////////////
  153. /*++
  154. CCutAndPasteDataObject::GetDataHere
  155. For cut and paste, the OLE clipboard will ask us for an IEnumFORMATETC
  156. structure that lists the formats we support.
  157. We construct a enumerator which will say that we support the format
  158. indicated by the m_CCF_CUT_AND_PASTE_FORMAT class variable from
  159. the node as template parameter.
  160. You can use this template class for many nodes, each of which will
  161. have the m_CCF_CUT_AND_PASTE_FORMAT class variable, but just make sure
  162. that you use a different string for each of them in the RegisterClipboardFormat
  163. call.
  164. CClientNode::m_CCF_CUT_AND_PASTE_FORMAT = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_IAS_CLIENT_NODE"));
  165. CPolicyNode::m_CCF_CUT_AND_PASTE_FORMAT = (CLIPFORMAT) RegisterClipboardFormat(_T("CCF_NAP_POLICY_NODE"));
  166. Also, so that we can paste our data into any app, we support CF_TEXT.
  167. If you don't want this functionality, respond minimally in your node's
  168. FillText method.
  169. --*/
  170. //////////////////////////////////////////////////////////////////////////////
  171. STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc )
  172. {
  173. ATLTRACE(_T("CCutAndPasteDataObject::EnumFormatEtc\n"));
  174. static FORMATETC fetcFormat[2];
  175. fetcFormat[0].cfFormat=CF_TEXT;
  176. fetcFormat[0].dwAspect=DVASPECT_CONTENT;
  177. fetcFormat[0].ptd=NULL;
  178. fetcFormat[0].tymed=TYMED_HGLOBAL;
  179. fetcFormat[0].lindex=-1;
  180. fetcFormat[1].cfFormat= NodeToBeCutAndPasted::m_CCF_CUT_AND_PASTE_FORMAT;
  181. fetcFormat[1].dwAspect=DVASPECT_CONTENT;
  182. fetcFormat[1].ptd=NULL;
  183. fetcFormat[1].tymed=TYMED_HGLOBAL;
  184. fetcFormat[1].lindex=-1;
  185. switch (dwDirection)
  186. {
  187. case DATADIR_GET:
  188. *ppenumFormatEtc=new CEnumFormatEtc(2, fetcFormat);
  189. break;
  190. case DATADIR_SET:
  191. *ppenumFormatEtc=NULL;
  192. break;
  193. default:
  194. *ppenumFormatEtc=NULL;
  195. break;
  196. }
  197. if( NULL == *ppenumFormatEtc )
  198. {
  199. return E_FAIL;
  200. }
  201. else
  202. {
  203. (*ppenumFormatEtc)->AddRef();
  204. }
  205. return NOERROR;
  206. }
  207. STDMETHOD(DAdvise)(
  208. FORMATETC *pformatetc
  209. , DWORD advf
  210. , IAdviseSink *pAdvSink
  211. , DWORD *pdwConnection
  212. )
  213. {
  214. ATLTRACENOTIMPL(_T("CCutAndPasteDataObject::DAdvise\n"));
  215. }
  216. STDMETHOD(DUnadvise)(DWORD dwConnection)
  217. {
  218. ATLTRACENOTIMPL(_T("CCutAndPasteDataObject::DUnadvise\n"));
  219. }
  220. STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise)
  221. {
  222. ATLTRACENOTIMPL(_T("CCutAndPasteDataObject::EnumDAdvise\n"));
  223. }
  224. CCutAndPasteObjectData<NodeToBeCutAndPasted> m_objectData;
  225. };
  226. #endif // _IAS_CUT_AND_PASTE_DATA_OBJECT_H_