//____________________________________________________________________________ // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: multisel.h // // Contents: // // Classes: // // Functions: // // History: 6/12/1997 RaviR Created //____________________________________________________________________________ // #ifndef _MULTISEL_H_ #define _MULTISEL_H_ class CSnapIn; class CNode; class CSnapInNode; class CMTSnapInNode; class CMultiSelection; class CComponent; class CComponentPtrArray; class CScopeTree; class CMMCClipBoardDataObject; // local classes class CSnapinSelData; class CSnapinSelDataList; class CMultiSelectDataObject; class CSnapinSelData { public: CSnapinSelData() : m_nNumOfItems(0), m_lCookie(111), // 0) m_bScopeItem(FALSE), m_ID(-1), m_pComponent(NULL), m_pSnapIn(NULL) { DEBUG_INCREMENT_INSTANCE_COUNTER(CSnapinSelData); } ~CSnapinSelData() { DEBUG_DECREMENT_INSTANCE_COUNTER(CSnapinSelData); } UINT GetNumOfItems() const { return m_nNumOfItems; } MMC_COOKIE GetCookie() const { return m_lCookie; } BOOL IsScopeItem() const { return m_bScopeItem; } void IncrementNumOfItems() { ++m_nNumOfItems; } void SetNumOfItems(UINT count) { m_nNumOfItems = count; } void SetCookie(MMC_COOKIE lCookie) { m_lCookie = lCookie; } void SetIsScopeItem(BOOL bScopeItem) { m_bScopeItem = bScopeItem; } void AddObjectType(GUID& guid) { m_objectTypeGuidList.AddHead(guid); } CList& GetObjectTypeGuidList() { return m_objectTypeGuidList; } void SetSnapIn(CSnapIn* pSnapIn) { m_pSnapIn = pSnapIn; } CSnapIn* GetSnapIn() { return m_pSnapIn; } COMPONENTID GetID() { return m_ID; } void SetID(COMPONENTID id) { m_ID = id; } void SetDataObject(IDataObject* pDO) { m_spDataObject = pDO; } IDataObject* GetDataObject() { ASSERT(m_spDataObject != NULL); return m_spDataObject; } void SetComponent(CComponent* pComponent) { ASSERT(m_pComponent == NULL); m_pComponent = pComponent; } CComponent* GetComponent() { ASSERT(m_pComponent != NULL); return m_pComponent; } void SetConsoleVerb(IConsoleVerb* pConsoleVerb) { m_spConsoleVerb = pConsoleVerb; } IConsoleVerb* GetConsoleVerb() { return m_spConsoleVerb; } // methods to access array of scope nodes included in multiselection // this data is particularly valuable, when data is put on clipboard // to be detect if contined data is affected by CNode being deleted typedef std::vector CNodePtrArray; void AddScopeNodes(const CNodePtrArray& nodes) { m_vecScopeNodes.insert( m_vecScopeNodes.end(), nodes.begin(), nodes.end() ); } const CNodePtrArray& GetScopeNodes() { return m_vecScopeNodes; } private: UINT m_nNumOfItems; BOOL m_bScopeItem; MMC_COOKIE m_lCookie; COMPONENTID m_ID; CSnapIn* m_pSnapIn; CComponent* m_pComponent; IConsoleVerbPtr m_spConsoleVerb; IDataObjectPtr m_spDataObject; CList m_objectTypeGuidList; CNodePtrArray m_vecScopeNodes; }; // class CSnapinSelData class CSnapinSelDataList : public CList { public: CSnapinSelDataList() { DEBUG_INCREMENT_INSTANCE_COUNTER(CSnapinSelDataList); } ~CSnapinSelDataList() { POSITION pos = GetHeadPosition(); while (pos) { delete GetNext(pos); } DEBUG_DECREMENT_INSTANCE_COUNTER(CSnapinSelDataList); } void Add(CSnapinSelData& snapinSelData, BOOL bStaticNode); }; class CMultiSelection { public: CMultiSelection(CNode* pNode); void AddRef() { ++m_cRef; } void Release() { ASSERT(m_cRef > 0); --m_cRef; if (m_cRef == 0) { ReleaseMultiSelDataObject(); delete this; } } HRESULT Init(); HRESULT GetMultiSelDataObject(IDataObject** ppDataObject); HRESULT GetExtensionSnapins(LPCTSTR pszExtensionTypeKey, CList& snapinGuidList); bool IsSingleSnapinSelection() { if (m_rgStaticNodes.size() > 0 || m_snapinSelDataList.GetCount() > 1) return false; return true; } IDataObject* GetSingleSnapinSelDataObject() { if (!IsSingleSnapinSelection()) return NULL; CSnapinSelData* pSnapinSelData = m_snapinSelDataList.GetHead(); ASSERT(pSnapinSelData != NULL); return pSnapinSelData->GetDataObject(); } CComponent* GetPrimarySnapinComponent() { if (!IsSingleSnapinSelection()) return NULL; CSnapinSelData* pSnapinSelData = m_snapinSelDataList.GetHead(); return pSnapinSelData->GetComponent(); } BOOL IsAnExtensionSnapIn(const CLSID& rclsid); BOOL HasNodes() { return m_bHasNodes; } BOOL HasStaticData() { return (m_rgStaticNodes.size() > 0); } BOOL HasSnapinData() { return (m_snapinSelDataList.IsEmpty() == FALSE); } BOOL HasData() { if (HasSnapinData() == FALSE) return HasStaticData(); return TRUE; } void SetScopeTree(CScopeTree* pCScopeTree) { m_pCScopeTree = pCScopeTree; } CScopeTree* GetScopeTree() { ASSERT(m_pCScopeTree != NULL); return m_pCScopeTree; } BOOL IsInUse() { return m_bInUse; } SC ScVerbInvoked(MMC_CONSOLE_VERB verb); bool RemoveStaticNode(CMTNode* pMTNode); void ReleaseMultiSelDataObject() { m_spDataObjectMultiSel = NULL; ASSERT(m_spDataObjectMultiSel == NULL); } SC ScIsVerbEnabledInclusively(MMC_CONSOLE_VERB mmcVerb, BOOL& bEnable); SC ScGetSnapinDataObjects(CMMCClipBoardDataObject *pResultObject); private: DWORD m_cRef; CNode* m_pNode; CSnapInNode* m_pSINode; CMTSnapInNode* m_pMTSINode; CScopeTree* m_pCScopeTree; CSnapinSelDataList m_snapinSelDataList; CMTNodePtrArray m_rgStaticNodes; IDataObjectPtr m_spDataObjectMultiSel; BOOL m_bHasNodes; BOOL m_bInUse; CMTSnapInNode* _GetStaticMasterNode() { return m_pMTSINode; } CSnapInNode* _GetStaticNode() { return m_pSINode; } void _SetInUse(BOOL b) { m_bInUse = b; } SC _ScVerbInvoked(MMC_CONSOLE_VERB verb); bool _IsTargetCut(); #ifdef DBG BOOL m_bInit; #endif HRESULT _ComputeSelectionDataList(); CComponent* _GetComponent(CSnapinSelData* pSnapinSelData); HRESULT _GetObjectTypeForSingleSel(CSnapinSelData* pSnapinSelData); HRESULT _GetObjectTypesForMultipleSel(CSnapinSelData* pSnapinSelData); HRESULT _FindSnapinsThatExtendObjectTypes(CSnapinSelDataList& snapinSelDataList, CList& snapinGuidList); ~CMultiSelection(); }; // class CMultiSelection class CMultiSelectDataObject : public IDataObject, public CComObjectRoot { public: // ATL Maps DECLARE_NOT_AGGREGATABLE(CMultiSelectDataObject) BEGIN_COM_MAP(CMultiSelectDataObject) COM_INTERFACE_ENTRY(IDataObject) END_COM_MAP() #ifdef DBG int dbg_cRef; ULONG InternalAddRef() { ++dbg_cRef; int tmp1 = dbg_cRef; int tmp2 = tmp1 * 4; return CComObjectRoot::InternalAddRef(); } ULONG InternalRelease() { --dbg_cRef; int tmp1 = dbg_cRef; int tmp2 = tmp1 * 4; return CComObjectRoot::InternalRelease(); } #endif // DBG // Construction/Destruction CMultiSelectDataObject() : m_ppDataObjects(NULL), m_count(0), m_ppMTNodes(NULL), m_nSize(0), m_pMS(NULL) { #ifdef DBG dbg_cRef = 0; #endif DEBUG_INCREMENT_INSTANCE_COUNTER(CMultiSelectDataObject); } ~CMultiSelectDataObject(); void SetDataObjects(LPDATAOBJECT* ppDataObjects, UINT count) { if (ppDataObjects != NULL) { ASSERT(m_ppDataObjects == NULL); ASSERT(m_count == 0); m_ppDataObjects = ppDataObjects; m_count = count; } else { ASSERT(count == 0); delete [] m_ppDataObjects; m_ppDataObjects = NULL; m_count = 0; } } void SetStaticNodes(CMTNodePtrArray &rgMTNodes, int nSize) { typedef CMTNode* _PMTNODE; ASSERT(m_ppMTNodes == NULL); ASSERT(m_nSize == 0); m_ppMTNodes = new _PMTNODE[nSize]; if(m_ppMTNodes != NULL) { m_nSize = nSize; for(int i=0; iAddRef(); } CMultiSelection* GetMultiSelection() { ASSERT(m_pMS != NULL); return m_pMS; } // Standard IDataObject methods public: // Implemented STDMETHOD(GetDataHere)(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium); STDMETHOD(GetData)(LPFORMATETC lpFormatetcIn, LPSTGMEDIUM lpMedium); STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC* ppEnumFormatEtc); STDMETHOD(QueryGetData)(LPFORMATETC lpFormatetc); // Not Implemented STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC lpFormatetcIn, LPFORMATETC lpFormatetcOut) { return E_NOTIMPL; }; STDMETHOD(SetData)(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium, BOOL bRelease) { return E_NOTIMPL; }; STDMETHOD(DAdvise)(LPFORMATETC lpFormatetc, DWORD advf,LPADVISESINK pAdvSink, LPDWORD pdwConnection) { return E_NOTIMPL; }; STDMETHOD(DUnadvise)(DWORD dwConnection) { return E_NOTIMPL; }; STDMETHOD(EnumDAdvise)(LPENUMSTATDATA* ppEnumAdvise) { return E_NOTIMPL; } private: LPDATAOBJECT* m_ppDataObjects; UINT m_count; CMTNode** m_ppMTNodes; int m_nSize; CMultiSelection* m_pMS; // To be used only for Drag-Drop }; // class CMultiSelectDataObject bool IsMultiSelectDataObject(IDataObject* pdtobjCBSelData); #endif // _MULTISEL_H_