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.

480 lines
25 KiB

  1. /*
  2. * snapinitem.hxx
  3. *
  4. *
  5. * Copyright (c) 1998-1999 Microsoft Corporation
  6. *
  7. * PURPOSE: Defines the CBaseSnapinItem class.
  8. *
  9. *
  10. * OWNER: ptousig
  11. */
  12. #ifndef _SNAPINITEM_HXX_
  13. #define _SNAPINITEM_HXX_
  14. #pragma once
  15. // Forward declarations
  16. struct SnapinMenuItem;
  17. class CBaseSnapinItem;
  18. class CBaseMultiSelectSnapinItem;
  19. //
  20. // This is some arbitrary value. It's used as the maximum length of a
  21. // string in a column.
  22. //
  23. #define cchMaxField 1000
  24. // -----------------------------------------------------------------------------
  25. // Provides a standard interface for all snapin item types. This class
  26. // is not templated, so that a cookie can be converted to and from a
  27. // CBaseSnapinItem without knowing what the precise derived class is.
  28. //
  29. class CBaseSnapinItem: public CBaseDataObject
  30. {
  31. public:
  32. CBaseSnapinItem(void);
  33. virtual ~CBaseSnapinItem(void);
  34. //
  35. // Initializer
  36. //
  37. virtual SC ScInit(CBaseSnapin *pSnapin, CColumnInfoEx *pcolinfoex = NULL, INT ccolinfoex = 0, BOOL fIsRoot = FALSE);
  38. virtual SC ScInitializeChild(CBaseSnapinItem* pitem);
  39. virtual SC ScInitializeNamespaceExtension(LPDATAOBJECT lpDataObject, HSCOPEITEM item, CNodeType *pnodetype);
  40. //
  41. // Accessors
  42. //
  43. IConsole *IpConsole(void);
  44. IPropertySheetProvider *IpPropertySheetProvider(void);
  45. CBaseSnapin *Psnapin(void);
  46. CComponentData *PComponentData(void);
  47. BOOL FHasComponentData(void) { return m_pComponentData != NULL;}
  48. void SetComponentData(CComponentData *pComponentData);
  49. virtual void SetSnapin(CBaseSnapin * psnapin) { /*ASSERT(psnapin);*/ m_pSnapin = psnapin;}
  50. //
  51. // Information about this node
  52. //
  53. inline BOOL FIsGhostRoot(void) { return m_fIsGhostRoot;}
  54. inline void SetIsGhostRoot(BOOL f) { m_fIsGhostRoot = f;}
  55. inline BOOL FWasExpanded(void) { return m_fWasExpanded;}
  56. inline void SetWasExpanded(BOOL f) { m_fWasExpanded = f;}
  57. virtual BOOL FIsContainer(void) = 0;
  58. inline BOOL FIsRoot(void) { return m_fIsRoot;}
  59. inline IDataObject * Pdataobject(void) { return static_cast<IDataObject *>(this);}
  60. virtual inline LONG Cookie(void) { return reinterpret_cast<LONG>(static_cast<CBaseSnapinItem *>(this));}
  61. virtual tstring* PstrNodeID(void) { return NULL;}
  62. virtual const CNodeType*Pnodetype(void) = 0;
  63. inline BOOL FIsSnapinManager(void) { return m_type == CCT_SNAPIN_MANAGER;}
  64. inline void SetType(DATA_OBJECT_TYPES type) { m_type = type;}
  65. inline HSCOPEITEM Hscopeitem(void) { return m_hscopeitem;}
  66. void SetHscopeitem(HSCOPEITEM hscopeitem);
  67. inline BOOL FInserted(void) { return m_fInserted;}
  68. inline void SetInserted(BOOL f) { m_fInserted = f;}
  69. virtual BOOL FIsPolicy(void) { return FALSE;}
  70. virtual BOOL FUsesResultList(void) { return TRUE;}
  71. //
  72. // Display information
  73. //
  74. virtual tstring* PstrDescriptionBar(void) { return NULL;}
  75. virtual const tstring* PstrDisplayName(void) = 0;
  76. virtual SC ScGetDisplayInfo(LPSCOPEDATAITEM pScopeItem);
  77. virtual SC ScGetDisplayInfo(LPRESULTDATAITEM pResultItem);
  78. virtual SC ScGetVirtualDisplayInfo(LPRESULTDATAITEM pResultItem, IResultData *ipResultData);
  79. virtual SC ScGetField(DAT dat, tstring& strField) = 0;
  80. //
  81. // Icons
  82. //
  83. virtual LONG Iconid(void);
  84. virtual LONG OpenIconid(void);
  85. //
  86. // Context menu
  87. //
  88. virtual DWORD DwFlagsMenuDisable(void) { return dwMenuAlwaysEnable;}
  89. virtual DWORD DwFlagsMenuGray(void) { return dwMenuNeverGray;}
  90. virtual DWORD DwFlagsMenuChecked(void) { return dwMenuNeverChecked;}
  91. virtual SnapinMenuItem *Pmenuitem(void) { return NULL;}
  92. virtual INT CMenuItem(void) { return 0;}
  93. virtual BOOL FAddDebugMenus(void) { return TRUE;}
  94. virtual SC ScCommand(long nCommandID, CComponent *pComponent = NULL);
  95. //
  96. // Verb information
  97. //
  98. virtual SC ScGetVerbs(DWORD * pdwVerbs) { *pdwVerbs = vmProperties | vmRefresh; return S_OK;}
  99. virtual MMC_CONSOLE_VERB MmcverbDefault(void) { return FIsContainer() ? MMC_VERB_OPEN : MMC_VERB_PROPERTIES;}
  100. virtual BOOL FAllowPasteForResultItems() { return FALSE;}
  101. //
  102. // Result Pane
  103. //
  104. virtual BOOL FResultPaneIsOCX() { return FALSE;}
  105. virtual BOOL FResultPaneIsWeb() { return FALSE;}
  106. //
  107. // OCX result pane
  108. //
  109. virtual SC ScGetOCXCLSID(tstring& strclsidOCX) { strclsidOCX = TEXT(""); return S_FALSE;}
  110. virtual SC ScInitOCX(IUnknown* pUnkOCX, IConsole* pConsole) { return S_FALSE;}
  111. virtual BOOL FCacheOCX() { return FALSE; }
  112. virtual IUnknown* GetCachedOCX(IConsole* pConsole) { return NULL;}
  113. //
  114. // Web result pane
  115. //
  116. virtual SC ScGetWebURL(tstring& strURL) { strURL = TEXT(""); return S_FALSE;}
  117. // List View (Result pane)
  118. //
  119. virtual SC ScInitializeResultView(CComponent *pComponent);
  120. virtual SC ScInsertResultItem(CComponent *pComponent);
  121. virtual SC ScUpdateResultItem(IResultData *ipResultData);
  122. virtual SC ScRemoveResultItems(LPRESULTDATA ipResultData);
  123. virtual SC ScPostInsertResultItems(void) { return S_OK;} // do something after the item is inserted.
  124. virtual DAT DatPresort(void) { return datNil; } // The intrinsic relationship of the items in the linked list.
  125. virtual DAT DatSort(void) { return datNil; } // default sort criterion.
  126. //
  127. // Virtual result pane
  128. //
  129. virtual BOOL FVirtualResultsPane(void) { return FALSE;}
  130. virtual SC ScVirtualQueryDataObject(long cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject) { /*ASSERT("This function must be overridden when in virtual results mode!" && FALSE)*/; return S_OK;}
  131. virtual SC ScFindItem(LPRESULTFINDINFO pFindinfo, INT * pnFoundIndex) { return S_FALSE;}
  132. virtual SC ScCacheHint(INT nStartIndex, INT nEndIndex) { return S_FALSE;}
  133. virtual SC ScSortItems(INT nColumn, DWORD dwSortOptions, long lUserParam) { return S_FALSE;}
  134. virtual SC ScGetField(INT nIndex, DAT dat, tstring& strField, IResultData *ipResultData) { /*ASSERT("This function must be overridden" && FALSE)*/; return S_OK; }
  135. virtual LONG Iconid(INT nIndex) { /*ASSERT("This function must be overridden" && FALSE)*/; return 0;}
  136. //
  137. // Scope pane
  138. //
  139. virtual SC ScInsertScopeItem(CComponentData *pComponentData, BOOL fExpand, HSCOPEITEM item);
  140. virtual SC ScUpdateScopeItem(IConsoleNameSpace *ipConsoleNameSpace);
  141. //
  142. // Clipboard formats
  143. //
  144. virtual SC ScWriteDisplayName(IStream *pstream);
  145. virtual SC ScWriteAnsiName(IStream *pStream );
  146. virtual SC ScWriteNodeType(IStream *pstream);
  147. virtual SC ScWriteClsid(IStream *pstream);
  148. virtual SC ScWriteNodeID(IStream *pstream);
  149. virtual SC ScWriteColumnSetId(IStream *pstream);
  150. virtual SC ScWriteAdminHscopeitem(IStream *pstream);
  151. //
  152. // Multiselect (default: do not support multiselect)
  153. //
  154. virtual BOOL FAllowMultiSelectionForChildren() { return FALSE;}
  155. //
  156. // Notification handlers
  157. //
  158. virtual SC ScQueryDataObject(long cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject);
  159. virtual SC ScQueryDispatch(long cookie, DATA_OBJECT_TYPES type, LPDISPATCH* ppDispatch) { return S_FALSE;}
  160. virtual SC ScCompare(CBaseSnapinItem * psnapinitem) { return S_OK;}
  161. virtual SC ScOnRename(const tstring& strNewName) { return S_FALSE;}
  162. virtual SC ScOnDelete(BOOL *pfDeleted) { *pfDeleted = FALSE; return S_OK;}
  163. virtual SC ScOnQueryCutOrMove(DWORD *pdwCanCut) { *pdwCanCut = 0; return S_OK;}
  164. virtual SC ScOnCutOrMove(void) { return S_OK;}
  165. virtual SC ScOnQueryPaste(LPDATAOBJECT pDataObject, BOOL *pfCanPaste) { *pfCanPaste = FALSE; return S_OK;}
  166. virtual SC ScOnPaste(LPDATAOBJECT pDataObject, BOOL fMove, BOOL *pfPasted) { *pfPasted = FALSE; return S_OK;}
  167. virtual SC ScOnShow(CComponent *pComponent, BOOL fSelect);
  168. virtual SC ScOnSelect(CComponent * pComponent, LPDATAOBJECT lpDataObject, BOOL fScope, BOOL fSelect) { return S_OK;}
  169. virtual SC ScOnPropertyChange(void) { return S_OK;}
  170. virtual SC ScOnRefresh(void) { return S_OK;}
  171. virtual SC ScGetResultViewType(LPOLESTR* ppViewType, long* pViewOptions);
  172. virtual SC ScGetResultViewType2(IConsole *pConsole, PRESULT_VIEW_TYPE_INFO pResultViewType);
  173. virtual SC ScRestoreResultView(PRESULT_VIEW_TYPE_INFO pResultViewType);
  174. virtual SC ScOnAddImages(IImageList* ipResultImageList);
  175. virtual SC ScOnViewChangeHint(long hint, CComponent *pComponent) { return S_OK;}
  176. //
  177. // Context help function. The pstrHelpTopic parameter will contain the
  178. // full path to the CHM file, items can potentially append the name of
  179. // the HTML file to display and then return S_OK. If S_FALSE is returned
  180. // (the default) the TOC will be displayed.
  181. //
  182. virtual SC ScOnContextHelp(tstring& strHelpTopic) { return S_FALSE;}
  183. //
  184. // Shortcuts to information obtained from Psnapin() or Pnodetype()
  185. //
  186. virtual const tstring& StrClassName(void);
  187. virtual const CLSID * PclsidSnapin(void);
  188. virtual const tstring& StrClsidSnapin(void);
  189. virtual WTL::CBitmap* PbitmapImageListSmall(void);
  190. virtual WTL::CBitmap* PbitmapImageListLarge(void);
  191. virtual CCookieList * Pcookielist(void);
  192. virtual const tstring& StrClsidNodeType(void) { return Pnodetype()->StrClsidNodeType();}
  193. //
  194. // Linked list management
  195. //
  196. // $REVIEW (ptousig) It would be nice to get rid of the linked list and start
  197. // using STL to manage children, but that would be too
  198. // de-stabilizing at the moment.
  199. //
  200. BOOL FIncludesChild(CBaseSnapinItem *pitem);
  201. SC ScAddChild(CBaseSnapinItem *pitem);
  202. virtual BOOL FHasChildren(void) { return TRUE;}
  203. virtual SC ScCreateChildren(void);
  204. virtual SC ScDeleteSubTree(BOOL fDeleteRoot);
  205. virtual SC ScRefreshNode(void);
  206. CBaseSnapinItem * PitemRoot(void);
  207. CBaseSnapinItem * PitemParent(void) { return m_pitemParent;}
  208. CBaseSnapinItem * PitemNext(void) { return m_pitemNext;}
  209. CBaseSnapinItem * PitemPrevious(void) { return m_pitemPrevious;}
  210. CBaseSnapinItem * PitemChild(void) { return m_pitemChild;}
  211. void SetParent(CBaseSnapinItem *pitemParent);
  212. void SetNext(CBaseSnapinItem *pitemNext);
  213. void SetPrevious(CBaseSnapinItem *pitemPrevious);
  214. void SetChild(CBaseSnapinItem *pitemChild);
  215. void Unlink(void); // remove the item from the linked list.
  216. //
  217. // Property pages
  218. //
  219. virtual SC ScIsPropertySheetOpen(BOOL *pfPagesUp, IComponent *ipComponent = NULL);
  220. virtual SC ScQueryPagesFor(void) { return S_OK;}
  221. virtual SC ScCreatePropertyPages(LPPROPERTYSHEETCALLBACK ipPropertySheetCallback) { return S_FALSE;}
  222. virtual SC ScCreatePropertyPages(LPPROPERTYSHEETCALLBACK ipPropertySheetCallback, LONG hNotificationHandle) { return S_OK;};
  223. SC ScDisplayPropertySheet(void); // creating a new object.
  224. virtual SC ScDisplayPropertyPages(LPPROPERTYSHEETCALLBACK ipPropertySheetCallback, LONG handle) { return S_FALSE;}
  225. // Property pages for the snapin while in the node manager
  226. virtual SC ScCreateSnapinMgrPropertyPages(LPPROPERTYSHEETCALLBACK ipPropertySheetCallback) { return S_FALSE;}
  227. //
  228. // Persistence
  229. //
  230. virtual SC ScLoad(IStream *pstream) { return S_OK;}
  231. virtual SC ScSave(IStream *pstream, BOOL fClearDirty) { return S_OK;}
  232. virtual SC ScIsDirty(void) { return S_FALSE;}
  233. //
  234. // Column information
  235. //
  236. // Answers information about a specific column. This is the version used when
  237. // setting up the column headers for our children.
  238. virtual CColumnInfoEx * PcolinfoexHeaders(INT icolinfo=0) { return Psnapin()->Pcolinfoex(icolinfo);}
  239. virtual INT CcolinfoexHeaders(void) { return Psnapin()->Ccolinfoex();}
  240. // Answers information about a specific column. This is the version used when
  241. // displaying information in our parent's columns.
  242. // To maintain previous behavior, we will return the same columns as we used
  243. // for our children. This only works if the children has a superset of the
  244. // parent.
  245. virtual CColumnInfoEx * PcolinfoexDisplay(INT icolinfo=0) { return PcolinfoexHeaders(icolinfo);}
  246. virtual INT CcolinfoexDisplay(void) { return CcolinfoexHeaders();}
  247. private:
  248. // Linked-list pointers
  249. CBaseSnapinItem* m_pitemParent;
  250. CBaseSnapinItem* m_pitemPrevious; // The previous item at the same level
  251. CBaseSnapinItem* m_pitemNext; // The next item at the same level
  252. CBaseSnapinItem* m_pitemChild; // The first child item
  253. // We remember our "current" type and HSCOPEITEM
  254. DATA_OBJECT_TYPES m_type;
  255. HSCOPEITEM m_hscopeitem;
  256. // Information about this node
  257. BOOL m_fIsGhostRoot : 1;
  258. BOOL m_fWasExpanded : 1;
  259. BOOL m_fInserted : 1;
  260. BOOL m_fIsRoot : 1;
  261. // The "owners" of this node.
  262. CComponentData * m_pComponentData;
  263. CBaseSnapin * m_pSnapin;
  264. };
  265. // -----------------------------------------------------------------------------
  266. // Individual snapin item classes will be "wrapped" by this template class
  267. // This class used to do a lot more, all that is left now is the ATL stuff.
  268. // $REVIEW (ptousig) This could be changed to an itemcommon.hxx
  269. //
  270. template<class T>
  271. class CSnapinItem : public T
  272. {
  273. public:
  274. typedef CSnapinItem<T> t_snapinitem;
  275. BEGIN_COM_MAP(t_snapinitem)
  276. COM_INTERFACE_ENTRY(IDataObject)
  277. // Some items may expose specialized interfaces like IDispatch
  278. // So chain the templated object. This requires each template class
  279. // to have atleast an empty com-map.
  280. COM_INTERFACE_ENTRY_CHAIN(T)
  281. END_COM_MAP()
  282. DECLARE_NOT_AGGREGATABLE(t_snapinitem);
  283. virtual const char *SzGetSnapinItemClassName(void)
  284. {
  285. return typeid(T).name()+6; // +6 to remove "class "
  286. }
  287. };
  288. // -----------------------------------------------------------------------------
  289. // Creates a new CBaseSnapinItem object, initializes and AddRef's it.
  290. //
  291. template<class T>
  292. SC ScCreateItem(CBaseSnapinItem *pitemParent, CBaseSnapinItem *pitemPrevious, T **ppitemNew, BOOL fNew = FALSE)
  293. {
  294. SC sc = S_OK;
  295. T * pitem = NULL;
  296. T::CreateInstance(&pitem);
  297. if (!pitem)
  298. goto MemoryError;
  299. // Need to AddRef once.
  300. pitem->AddRef();
  301. // Set up the correct pointers.
  302. sc = pitemParent->ScInitializeChild(pitem);
  303. if (sc)
  304. {
  305. pitem->Release();
  306. pitem = NULL;
  307. goto Error;
  308. }
  309. if (!fNew)
  310. {
  311. // Link up the items.
  312. if (pitemPrevious)
  313. pitemPrevious->SetNext(pitem);
  314. else
  315. // First item, so make it a child of the parent.
  316. pitemParent->SetChild(pitem);
  317. }
  318. pitem->SetParent(pitemParent);
  319. pitem->SetComponentData(pitemParent->PComponentData());
  320. Cleanup:
  321. *ppitemNew = pitem;
  322. return sc;
  323. MemoryError:
  324. sc = E_OUTOFMEMORY;
  325. Error:
  326. TraceError(_T("::ScCreateItem()"), sc);
  327. goto Cleanup;
  328. }
  329. // -----------------------------------------------------------------------------
  330. // Creates a new CBaseSnapinItem object with no initialization and no addref.
  331. //
  332. template<class T>
  333. SC ScCreateItemQuick(T ** ppitemNew)
  334. {
  335. DECLARE_SC(sc, _T("ScCreateItemQuick"));
  336. sc = ScCheckPointers(ppitemNew);
  337. if (sc)
  338. return sc;
  339. T *pitem = NULL;
  340. // Create a new instance
  341. T::CreateInstance(&pitem);
  342. if (!pitem)
  343. return (sc = E_OUTOFMEMORY);
  344. // Need to add a reference count
  345. pitem->AddRef();
  346. // Assign the new item
  347. *ppitemNew = pitem;
  348. return sc;
  349. }
  350. // -----------------------------------------------------------------------------
  351. // Provides a standard interface for multiselect items. In short, an instance of this class
  352. // encapsulates N snapin items. Requests for multi-select operations are forwarded to each single instance in the default behaviour.
  353. // You may want to override this behaviour to provide bulk operation functionnality
  354. // (e.g. for a file copy, we would probably not forward a notification to each single object representing a file.)
  355. // We inherit from CBaseSnapinItem because we may want to provide bulk processing of events.
  356. //
  357. typedef CComObject<CSnapinItem<CBaseMultiSelectSnapinItem> > t_itemBaseMultiSelectSnapinItem; // for instanciation
  358. class CBaseMultiSelectSnapinItem : public CBaseSnapinItem
  359. {
  360. public:
  361. BEGIN_COM_MAP(CBaseMultiSelectSnapinItem)
  362. COM_INTERFACE_ENTRY(IDataObject)
  363. // Some items may expose specialized interfaces like IDispatch
  364. // So chain the templated object. This requires each template class
  365. // to have atleast an empty com-map.
  366. // COM_INTERFACE_ENTRY_CHAIN(T)
  367. END_COM_MAP()
  368. // Constructor and destructor
  369. CBaseMultiSelectSnapinItem(void);
  370. virtual ~CBaseMultiSelectSnapinItem(void);
  371. // Cookie information - only to follow MMC recommendations
  372. virtual inline LONG Cookie(void) { return MMC_MULTI_SELECT_COOKIE;}
  373. // Method to notify that we are for multiselect at the CBaseDataObject level
  374. virtual BOOL FIsMultiSelectDataObject() { return TRUE;}
  375. // Methods for clipboard format exchange specific to multiselect
  376. virtual SC ScWriteMultiSelectionItemTypes(IStream *pstream);
  377. // Method to access the list of selected snapin items
  378. virtual CItemVector * PivSelectedItems(void) { return &m_ivSelectedItems;}
  379. virtual CBaseSnapinItem * PivSelectedItemsFirst(void) { return m_ivSelectedItems[0];}
  380. // Method to access a list of snapin items in the selection which should get a cut notification
  381. virtual BOOL * PfPastedWithCut(void) { return m_pfPastedWithCut;}
  382. // Methods we have to implement but that we do not use in the default implementation
  383. virtual BOOL FIsContainer(void) { /*ASSERT("This method should not be called on a multi-select data object" && FALSE)*/; return FALSE;}
  384. virtual const tstring* PstrDisplayName(void) { /*ASSERT("This method should not be called on a multi-select data object" && FALSE)*/; return NULL;}
  385. virtual SC ScGetField(DAT dat, tstring& strField) { /*ASSERT("This method should not be called on a multi-select data object" && FALSE)*/; return NULL;}
  386. // Methods - node type (derived classes should not have to override this)
  387. virtual const CNodeType * Pnodetype() {return &nodetypeBaseMultiSelect;}
  388. // Methods - override for component
  389. virtual SC ScOnSelect(CComponent * pComponent, LPDATAOBJECT lpDataObject, BOOL fScope, BOOL fSelect);
  390. virtual SC ScCommand(CComponent * pComponent, long nCommandID, LPDATAOBJECT lpDataObject);
  391. virtual SC ScQueryPagesFor(CComponent * pComponent, LPDATAOBJECT lpDataObject);
  392. virtual SC ScCreatePropertyPages(CComponent * pComponent, LPPROPERTYSHEETCALLBACK ipPropertySheetCallback, long handle, LPDATAOBJECT lpDataObject);
  393. virtual SC ScOnDelete(CComponent * pComponent, LPDATAOBJECT lpDataObject);
  394. // Methods - override for snapin
  395. virtual SC ScAddMenuItems(CBaseSnapin * pSnapin, LPDATAOBJECT lpDataObject, LPCONTEXTMENUCALLBACK ipContextMenuCallback, long * pInsertionAllowed);
  396. virtual SC ScIsPastableDataObject(CBaseSnapin * pSnapin, CBaseSnapinItem * pitemTarget, LPDATAOBJECT lpDataObjectList, BOOL * pfPastable);
  397. virtual SC ScOnPaste(CBaseSnapin * pSnapin, CBaseSnapinItem * pitemTarget, LPDATAOBJECT lpDataObjectList, LPDATAOBJECT * ppDataObjectPasted, IConsole * ipConsole);
  398. virtual SC ScOnCutOrMove(CBaseSnapin * pSnapin, LPDATAOBJECT lpDataObjectList, IConsoleNameSpace * ipConsoleNameSpace, IConsole * ipConsole);
  399. // Methods - utility
  400. static SC ScExtractMultiSelectObjectFromCompositeMultiSelectObject(CBaseSnapin * psnapin, LPDATAOBJECT pDataObjectComposite, CBaseMultiSelectSnapinItem ** ppBaseMultiSelectSnapinItem);
  401. static SC ScGetMultiSelectDataObject(LPDATAOBJECT lpDataObject, CBaseMultiSelectSnapinItem ** ppMultiSelectSnapinItem);
  402. static SC ScExtractMultiSelectDataObject(CBaseSnapin * psnapin, LPDATAOBJECT lpDataObject, CBaseMultiSelectSnapinItem ** ppMultiSelectSnapinItem);
  403. virtual void MergeMenuItems(CSnapinContextMenuItemVectorWrapper * pcmivwForMerge, CSnapinContextMenuItemVectorWrapper * pcmivwToAdd);
  404. // Clipboard formats
  405. static UINT s_cfMultiSelectSnapins; // Multi select - list of multiselect snapin items in a composite data object
  406. static UINT s_cfCompositeDataObject; // Multi select - used to determine if an object is a composite data object
  407. private:
  408. // List of snapin items selected
  409. CItemVector m_ivSelectedItems;
  410. // Pointer to an array of booleans indicating the items pasted
  411. BOOL * m_pfPastedWithCut;
  412. };
  413. #endif // _SNAPINITEM_HXX_