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.

462 lines
10 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 1999
  5. //
  6. // File: multisel.h
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 6/12/1997 RaviR Created
  15. //____________________________________________________________________________
  16. //
  17. #ifndef _MULTISEL_H_
  18. #define _MULTISEL_H_
  19. class CSnapIn;
  20. class CNode;
  21. class CSnapInNode;
  22. class CMTSnapInNode;
  23. class CMultiSelection;
  24. class CComponent;
  25. class CComponentPtrArray;
  26. class CScopeTree;
  27. class CMMCClipBoardDataObject;
  28. // local classes
  29. class CSnapinSelData;
  30. class CSnapinSelDataList;
  31. class CMultiSelectDataObject;
  32. class CSnapinSelData
  33. {
  34. public:
  35. CSnapinSelData()
  36. : m_nNumOfItems(0),
  37. m_lCookie(111), // 0)
  38. m_bScopeItem(FALSE),
  39. m_ID(-1),
  40. m_pComponent(NULL),
  41. m_pSnapIn(NULL)
  42. {
  43. DEBUG_INCREMENT_INSTANCE_COUNTER(CSnapinSelData);
  44. }
  45. ~CSnapinSelData()
  46. {
  47. DEBUG_DECREMENT_INSTANCE_COUNTER(CSnapinSelData);
  48. }
  49. UINT GetNumOfItems() const
  50. {
  51. return m_nNumOfItems;
  52. }
  53. MMC_COOKIE GetCookie() const
  54. {
  55. return m_lCookie;
  56. }
  57. BOOL IsScopeItem() const
  58. {
  59. return m_bScopeItem;
  60. }
  61. void IncrementNumOfItems()
  62. {
  63. ++m_nNumOfItems;
  64. }
  65. void SetNumOfItems(UINT count)
  66. {
  67. m_nNumOfItems = count;
  68. }
  69. void SetCookie(MMC_COOKIE lCookie)
  70. {
  71. m_lCookie = lCookie;
  72. }
  73. void SetIsScopeItem(BOOL bScopeItem)
  74. {
  75. m_bScopeItem = bScopeItem;
  76. }
  77. void AddObjectType(GUID& guid)
  78. {
  79. m_objectTypeGuidList.AddHead(guid);
  80. }
  81. CList<GUID, GUID&>& GetObjectTypeGuidList()
  82. {
  83. return m_objectTypeGuidList;
  84. }
  85. void SetSnapIn(CSnapIn* pSnapIn)
  86. {
  87. m_pSnapIn = pSnapIn;
  88. }
  89. CSnapIn* GetSnapIn()
  90. {
  91. return m_pSnapIn;
  92. }
  93. COMPONENTID GetID()
  94. {
  95. return m_ID;
  96. }
  97. void SetID(COMPONENTID id)
  98. {
  99. m_ID = id;
  100. }
  101. void SetDataObject(IDataObject* pDO)
  102. {
  103. m_spDataObject = pDO;
  104. }
  105. IDataObject* GetDataObject()
  106. {
  107. ASSERT(m_spDataObject != NULL);
  108. return m_spDataObject;
  109. }
  110. void SetComponent(CComponent* pComponent)
  111. {
  112. ASSERT(m_pComponent == NULL);
  113. m_pComponent = pComponent;
  114. }
  115. CComponent* GetComponent()
  116. {
  117. ASSERT(m_pComponent != NULL);
  118. return m_pComponent;
  119. }
  120. void SetConsoleVerb(IConsoleVerb* pConsoleVerb)
  121. {
  122. m_spConsoleVerb = pConsoleVerb;
  123. }
  124. IConsoleVerb* GetConsoleVerb()
  125. {
  126. return m_spConsoleVerb;
  127. }
  128. // methods to access array of scope nodes included in multiselection
  129. // this data is particularly valuable, when data is put on clipboard
  130. // to be detect if contined data is affected by CNode being deleted
  131. typedef std::vector<CNode *> CNodePtrArray;
  132. void AddScopeNodes(const CNodePtrArray& nodes) { m_vecScopeNodes.insert( m_vecScopeNodes.end(), nodes.begin(), nodes.end() ); }
  133. const CNodePtrArray& GetScopeNodes() { return m_vecScopeNodes; }
  134. private:
  135. UINT m_nNumOfItems;
  136. BOOL m_bScopeItem;
  137. MMC_COOKIE m_lCookie;
  138. COMPONENTID m_ID;
  139. CSnapIn* m_pSnapIn;
  140. CComponent* m_pComponent;
  141. IConsoleVerbPtr m_spConsoleVerb;
  142. IDataObjectPtr m_spDataObject;
  143. CList<GUID, GUID&> m_objectTypeGuidList;
  144. CNodePtrArray m_vecScopeNodes;
  145. }; // class CSnapinSelData
  146. class CSnapinSelDataList : public CList<CSnapinSelData*, CSnapinSelData*>
  147. {
  148. public:
  149. CSnapinSelDataList()
  150. {
  151. DEBUG_INCREMENT_INSTANCE_COUNTER(CSnapinSelDataList);
  152. }
  153. ~CSnapinSelDataList()
  154. {
  155. POSITION pos = GetHeadPosition();
  156. while (pos)
  157. {
  158. delete GetNext(pos);
  159. }
  160. DEBUG_DECREMENT_INSTANCE_COUNTER(CSnapinSelDataList);
  161. }
  162. void Add(CSnapinSelData& snapinSelData, BOOL bStaticNode);
  163. };
  164. class CMultiSelection
  165. {
  166. public:
  167. CMultiSelection(CNode* pNode);
  168. void AddRef()
  169. {
  170. ++m_cRef;
  171. }
  172. void Release()
  173. {
  174. ASSERT(m_cRef > 0);
  175. --m_cRef;
  176. if (m_cRef == 0)
  177. {
  178. ReleaseMultiSelDataObject();
  179. delete this;
  180. }
  181. }
  182. HRESULT Init();
  183. HRESULT GetMultiSelDataObject(IDataObject** ppDataObject);
  184. HRESULT GetExtensionSnapins(LPCTSTR pszExtensionTypeKey,
  185. CList<GUID, GUID&>& snapinGuidList);
  186. bool IsSingleSnapinSelection()
  187. {
  188. if (m_rgStaticNodes.size() > 0 || m_snapinSelDataList.GetCount() > 1)
  189. return false;
  190. return true;
  191. }
  192. IDataObject* GetSingleSnapinSelDataObject()
  193. {
  194. if (!IsSingleSnapinSelection())
  195. return NULL;
  196. CSnapinSelData* pSnapinSelData = m_snapinSelDataList.GetHead();
  197. ASSERT(pSnapinSelData != NULL);
  198. return pSnapinSelData->GetDataObject();
  199. }
  200. CComponent* GetPrimarySnapinComponent()
  201. {
  202. if (!IsSingleSnapinSelection())
  203. return NULL;
  204. CSnapinSelData* pSnapinSelData = m_snapinSelDataList.GetHead();
  205. return pSnapinSelData->GetComponent();
  206. }
  207. BOOL IsAnExtensionSnapIn(const CLSID& rclsid);
  208. BOOL HasNodes()
  209. {
  210. return m_bHasNodes;
  211. }
  212. BOOL HasStaticData()
  213. {
  214. return (m_rgStaticNodes.size() > 0);
  215. }
  216. BOOL HasSnapinData()
  217. {
  218. return (m_snapinSelDataList.IsEmpty() == FALSE);
  219. }
  220. BOOL HasData()
  221. {
  222. if (HasSnapinData() == FALSE)
  223. return HasStaticData();
  224. return TRUE;
  225. }
  226. void SetScopeTree(CScopeTree* pCScopeTree)
  227. {
  228. m_pCScopeTree = pCScopeTree;
  229. }
  230. CScopeTree* GetScopeTree()
  231. {
  232. ASSERT(m_pCScopeTree != NULL);
  233. return m_pCScopeTree;
  234. }
  235. BOOL IsInUse()
  236. {
  237. return m_bInUse;
  238. }
  239. SC ScVerbInvoked(MMC_CONSOLE_VERB verb);
  240. bool RemoveStaticNode(CMTNode* pMTNode);
  241. void ReleaseMultiSelDataObject()
  242. {
  243. m_spDataObjectMultiSel = NULL;
  244. ASSERT(m_spDataObjectMultiSel == NULL);
  245. }
  246. SC ScIsVerbEnabledInclusively(MMC_CONSOLE_VERB mmcVerb, BOOL& bEnable);
  247. SC ScGetSnapinDataObjects(CMMCClipBoardDataObject *pResultObject);
  248. private:
  249. DWORD m_cRef;
  250. CNode* m_pNode;
  251. CSnapInNode* m_pSINode;
  252. CMTSnapInNode* m_pMTSINode;
  253. CScopeTree* m_pCScopeTree;
  254. CSnapinSelDataList m_snapinSelDataList;
  255. CMTNodePtrArray m_rgStaticNodes;
  256. IDataObjectPtr m_spDataObjectMultiSel;
  257. BOOL m_bHasNodes;
  258. BOOL m_bInUse;
  259. CMTSnapInNode* _GetStaticMasterNode()
  260. {
  261. return m_pMTSINode;
  262. }
  263. CSnapInNode* _GetStaticNode()
  264. {
  265. return m_pSINode;
  266. }
  267. void _SetInUse(BOOL b)
  268. {
  269. m_bInUse = b;
  270. }
  271. SC _ScVerbInvoked(MMC_CONSOLE_VERB verb);
  272. bool _IsTargetCut();
  273. #ifdef DBG
  274. BOOL m_bInit;
  275. #endif
  276. HRESULT _ComputeSelectionDataList();
  277. CComponent* _GetComponent(CSnapinSelData* pSnapinSelData);
  278. HRESULT _GetObjectTypeForSingleSel(CSnapinSelData* pSnapinSelData);
  279. HRESULT _GetObjectTypesForMultipleSel(CSnapinSelData* pSnapinSelData);
  280. HRESULT _FindSnapinsThatExtendObjectTypes(CSnapinSelDataList& snapinSelDataList,
  281. CList<GUID, GUID&>& snapinGuidList);
  282. ~CMultiSelection();
  283. }; // class CMultiSelection
  284. class CMultiSelectDataObject : public IDataObject,
  285. public CComObjectRoot
  286. {
  287. public:
  288. // ATL Maps
  289. DECLARE_NOT_AGGREGATABLE(CMultiSelectDataObject)
  290. BEGIN_COM_MAP(CMultiSelectDataObject)
  291. COM_INTERFACE_ENTRY(IDataObject)
  292. END_COM_MAP()
  293. #ifdef DBG
  294. int dbg_cRef;
  295. ULONG InternalAddRef()
  296. {
  297. ++dbg_cRef;
  298. int tmp1 = dbg_cRef;
  299. int tmp2 = tmp1 * 4;
  300. return CComObjectRoot::InternalAddRef();
  301. }
  302. ULONG InternalRelease()
  303. {
  304. --dbg_cRef;
  305. int tmp1 = dbg_cRef;
  306. int tmp2 = tmp1 * 4;
  307. return CComObjectRoot::InternalRelease();
  308. }
  309. #endif // DBG
  310. // Construction/Destruction
  311. CMultiSelectDataObject() : m_ppDataObjects(NULL), m_count(0),
  312. m_ppMTNodes(NULL), m_nSize(0), m_pMS(NULL)
  313. {
  314. #ifdef DBG
  315. dbg_cRef = 0;
  316. #endif
  317. DEBUG_INCREMENT_INSTANCE_COUNTER(CMultiSelectDataObject);
  318. }
  319. ~CMultiSelectDataObject();
  320. void SetDataObjects(LPDATAOBJECT* ppDataObjects, UINT count)
  321. {
  322. if (ppDataObjects != NULL)
  323. {
  324. ASSERT(m_ppDataObjects == NULL);
  325. ASSERT(m_count == 0);
  326. m_ppDataObjects = ppDataObjects;
  327. m_count = count;
  328. }
  329. else
  330. {
  331. ASSERT(count == 0);
  332. delete [] m_ppDataObjects;
  333. m_ppDataObjects = NULL;
  334. m_count = 0;
  335. }
  336. }
  337. void SetStaticNodes(CMTNodePtrArray &rgMTNodes, int nSize)
  338. {
  339. typedef CMTNode* _PMTNODE;
  340. ASSERT(m_ppMTNodes == NULL);
  341. ASSERT(m_nSize == 0);
  342. m_ppMTNodes = new _PMTNODE[nSize];
  343. if(m_ppMTNodes != NULL)
  344. {
  345. m_nSize = nSize;
  346. for(int i=0; i<nSize; i++)
  347. m_ppMTNodes[i] = rgMTNodes[i];
  348. }
  349. }
  350. void SetMultiSelection(CMultiSelection* pMS)
  351. {
  352. ASSERT(pMS != NULL);
  353. m_pMS = pMS;
  354. m_pMS->AddRef();
  355. }
  356. CMultiSelection* GetMultiSelection()
  357. {
  358. ASSERT(m_pMS != NULL);
  359. return m_pMS;
  360. }
  361. // Standard IDataObject methods
  362. public:
  363. // Implemented
  364. STDMETHOD(GetDataHere)(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium);
  365. STDMETHOD(GetData)(LPFORMATETC lpFormatetcIn, LPSTGMEDIUM lpMedium);
  366. STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC* ppEnumFormatEtc);
  367. STDMETHOD(QueryGetData)(LPFORMATETC lpFormatetc);
  368. // Not Implemented
  369. STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC lpFormatetcIn, LPFORMATETC lpFormatetcOut) { return E_NOTIMPL; };
  370. STDMETHOD(SetData)(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium, BOOL bRelease) { return E_NOTIMPL; };
  371. STDMETHOD(DAdvise)(LPFORMATETC lpFormatetc, DWORD advf,LPADVISESINK pAdvSink, LPDWORD pdwConnection) { return E_NOTIMPL; };
  372. STDMETHOD(DUnadvise)(DWORD dwConnection) { return E_NOTIMPL; };
  373. STDMETHOD(EnumDAdvise)(LPENUMSTATDATA* ppEnumAdvise) { return E_NOTIMPL; }
  374. private:
  375. LPDATAOBJECT* m_ppDataObjects;
  376. UINT m_count;
  377. CMTNode** m_ppMTNodes;
  378. int m_nSize;
  379. CMultiSelection* m_pMS; // To be used only for Drag-Drop
  380. }; // class CMultiSelectDataObject
  381. bool IsMultiSelectDataObject(IDataObject* pdtobjCBSelData);
  382. #endif // _MULTISEL_H_