⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enumidl.cpp

📁 大量windows shell编程例子
💻 CPP
字号:
/******************************************************************
*
*  Project.....:  Windows View (Namespace Extension)
*
*  Application.:  WINVIEW.dll
*  Module......:  EnumIDL.cpp
*  Description.:  IEnumIDList implementation
*
*  Compiler....:  MS Visual C++ 
*  Written by..:  D. Esposito
*
*  Environment.:  Windows 9x/NT
*
*******************************/



/*---------------------------------------------------------------*/
//                        INCLUDE section
/*---------------------------------------------------------------*/
#include "EnumIDL.h"
#include "ShlFldr.h"



/*---------------------------------------------------------------*/
//  Class constructor and destructor
/*---------------------------------------------------------------*/
CEnumIDList::CEnumIDList(HWND hwnd, DWORD dwFlags, HRESULT* pResult)
{
   if(pResult)
      *pResult = S_OK;

   m_pFirst = NULL;
   m_pLast = NULL;
   m_pCurrent = NULL;

   // Creates the PIDL manager
   m_pPidlMgr = new CPidlMgr();
   if(!m_pPidlMgr)
   {
      if(pResult)
         *pResult = E_OUTOFMEMORY;
      delete this;
      return;
   }

   // Get the shell's memory manager
   if(FAILED(SHGetMalloc(&m_pMalloc)))
   {
      if(pResult)
         *pResult = E_OUTOFMEMORY;
      delete this;
      return;
   }

   // Creates the list of the items
   if(!CreateEnumList(hwnd, dwFlags))
   {
      if(pResult)
         *pResult = E_OUTOFMEMORY;
      delete this;
      return;
   }

   m_ObjRefCount = 1;
   g_DllRefCount++;
}


CEnumIDList::~CEnumIDList()
{
	DeleteList();

	if( m_pMalloc )
		m_pMalloc->Release();

	if( m_pPidlMgr )
		delete m_pPidlMgr;

	g_DllRefCount--;
}


/*---------------------------------------------------------------*/
// IUnknown methods
/*---------------------------------------------------------------*/
STDMETHODIMP CEnumIDList::QueryInterface( REFIID riid, LPVOID *ppReturn )
{
	*ppReturn = NULL;

	if(IsEqualIID(riid, IID_IUnknown))
	   *ppReturn = this;
	else 
	if(IsEqualIID(riid, IID_IEnumIDList))
	   *ppReturn = (IEnumIDList*)this;
	
	if( *ppReturn )
    {
        LPUNKNOWN pUnk = (LPUNKNOWN)(*ppReturn);
		pUnk->AddRef();
		return S_OK;
    }

	return E_NOINTERFACE;
}                                             


STDMETHODIMP_(DWORD) CEnumIDList::AddRef()
{
	return ++m_ObjRefCount;
}


STDMETHODIMP_(DWORD) CEnumIDList::Release()
{
	if(--m_ObjRefCount == 0)
    {
	   delete this;
	   return 0;
    }
   
	return m_ObjRefCount;
}



/*---------------------------------------------------------------*/
// IEnumIDList methods
/*---------------------------------------------------------------*/
STDMETHODIMP CEnumIDList::Next(DWORD dwElements, LPITEMIDLIST apidl[], LPDWORD pdwFetched)
{
   DWORD dwIndex;
   HRESULT hr = S_OK;

   if(dwElements > 1 && !pdwFetched)
      return E_INVALIDARG;

   for(dwIndex = 0 ; dwIndex < dwElements ; dwIndex++)
   {
      // Is this the last item in the list?
      if(!m_pCurrent)
      {
         hr = S_FALSE;
         break;
      }

      // Copy PIDLs
      apidl[dwIndex] = m_pPidlMgr->Copy(m_pCurrent->pidl);
      m_pCurrent = m_pCurrent->pNext;
   }

   // Returns the number of fetched items
   if(pdwFetched)
      *pdwFetched = dwIndex;
   return hr;
}


// Skip
STDMETHODIMP CEnumIDList::Skip(DWORD dwSkip)
{
	DWORD dwIndex;
	HRESULT hr = S_OK;

	for( dwIndex=0; dwIndex < dwSkip; dwIndex++ )
	{
	   // is this the last item in the list?
	   if( !m_pCurrent )
	   {
		  hr = S_FALSE;
		  break;
	   }

	   m_pCurrent = m_pCurrent->pNext;
	}

	return hr;
}


// Reset
STDMETHODIMP CEnumIDList::Reset( VOID )
{
    m_pCurrent = m_pFirst;
	return S_OK;
}


STDMETHODIMP CEnumIDList::Clone( LPENUMIDLIST *ppEnum )
{
	return E_NOTIMPL;
}



/*---------------------------------------------------------------*/
// PRIVATE methods: CreateEnumList
// Creates the list that renders the active windows
/*---------------------------------------------------------------*/
BOOL CEnumIDList::CreateEnumList(HWND hWndRoot, DWORD dwFlags)
{
   // Get the desktop window
   if(hWndRoot == NULL)
   {
      // If we must consider the root window (the desktop), we don't need to
      //  enumerate anything. Just get the desktop HWND and add a new
      //  element to the list. This is what's done by NewEnumItem().
      hWndRoot = GetDesktopWindow();
      NewEnumItem(hWndRoot);
      return TRUE;
   }

   // Enumerate the child windows of the specified window
   ENUMWND ew;
   ew.lParam = reinterpret_cast<LPARAM>(this);
   ew.hwndParent = hWndRoot;
   ew.dwFlags = dwFlags;

   // We need a function that only considers immediate children of the
   //  specified window. We're not interested in children of children. We'll
   //  correct this aspect of EnumChildWindows' behavior in callback code.
   EnumChildWindows(hWndRoot, AddToEnumList, reinterpret_cast<LPARAM>(&ew));
   return TRUE;
}


/*---------------------------------------------------------------*/
// PRIVATE methods: AddToEnumList
// Class static member adding a new window to the folder's list
/*---------------------------------------------------------------*/
BOOL CALLBACK CEnumIDList::AddToEnumList(HWND hwndChild, LPARAM lParam)
{
   LPENUMWND lpew = reinterpret_cast<LPENUMWND>(lParam);

   // Avoid windows that aren't children of the specified window's parent.
   // This test is meant to skip over all those windows that aren't
   //  immediate children of the window whose children we're enumerating.
   // This check is due to a feature of EnumChildWindows() that enumerates
   //  not just children but also grandchildren. We avoid grandchildren.
   HWND h = GetParent(hwndChild);
   if((h != NULL) && (h != lpew->hwndParent))
      return TRUE;

   // We stored the pointer to the class in the lParam argument
   CEnumIDList* pEnumIDList = reinterpret_cast<CEnumIDList*>(lpew->lParam);

   // IMPORTANT: This is where we decide what's a 'folder' and what's a
   // 'leaf'. For windows, this rests on whether they have children.

   // Explorer wants non-folder items
   if(lpew->dwFlags & SHCONTF_NONFOLDERS)
      return pEnumIDList->NewEnumItem(hwndChild);

   // Explorer wants folder items
   if(lpew->dwFlags & SHCONTF_FOLDERS)
   {
      // If it has no children, drop it because it has already been added.
      if(!pEnumIDList->m_pPidlMgr->HasChildren(hwndChild))
         return TRUE;
      else
         pEnumIDList->NewEnumItem(hwndChild);
   }
   return TRUE;
}


/*---------------------------------------------------------------*/
// PRIVATE methods: DeleteList
// Delete the previous list
/*---------------------------------------------------------------*/
BOOL CEnumIDList::DeleteList( VOID )
{
	LPENUMLIST  pDelete;

	while( m_pFirst )
    {
		pDelete = m_pFirst;
		m_pFirst = pDelete->pNext;

		// free the pidl
		m_pPidlMgr->Delete( pDelete->pidl );
   
	    //free the list item
	    m_pMalloc->Free( pDelete );
    }

	m_pFirst = m_pLast = m_pCurrent = NULL;
	return TRUE;
}


/*---------------------------------------------------------------*/
// PRIVATE methods: NewEnumItem
// Add a new item to the list.
/*---------------------------------------------------------------*/
BOOL CEnumIDList::NewEnumItem(HWND hwndChild)
{
   LPENUMLIST pNew = NULL;
   pNew = reinterpret_cast<LPENUMLIST>(m_pMalloc->Alloc(sizeof(ENUMLIST)));
   if(pNew)
   {
      // Create the new PIDL for the new element
      pNew->pNext = NULL;
      pNew->pidl = m_pPidlMgr->Create(hwndChild);

      // Is this the first item in the list?
      if(!m_pFirst)
      {
         m_pFirst = pNew;
         m_pCurrent = m_pFirst;
      }

      // Add the new item to the end of the list
      if(m_pLast)
         m_pLast->pNext = pNew;

      // Update the last item pointer
      m_pLast = pNew;
      return TRUE;
   }
   return FALSE;
}



/*  End of file: EnumIDL.cpp  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -