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

//____________________________________________________________________________
//
// 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<GUID, GUID&>& 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<CNode *> 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<GUID, GUID&> m_objectTypeGuidList;
CNodePtrArray m_vecScopeNodes;
}; // class CSnapinSelData
class CSnapinSelDataList : public CList<CSnapinSelData*, CSnapinSelData*>
{
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<GUID, GUID&>& 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<GUID, GUID&>& 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; i<nSize; i++)
m_ppMTNodes[i] = rgMTNodes[i];
}
}
void SetMultiSelection(CMultiSelection* pMS)
{
ASSERT(pMS != NULL);
m_pMS = pMS;
m_pMS->AddRef();
}
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_