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

📄 shlfldr.cpp

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

#include "ShlFldr.h"
#include "ShlView.h"
#include "ExtrIcon.h"
#include "CtxtMenu.h"
#include "Guid.h"
#include "resource.h"


/*---------------------------------------------------------------*/
// Constructor and destructor
/*---------------------------------------------------------------*/
CShellFolder::CShellFolder(CShellFolder *pParent, LPCITEMIDLIST pidl)
{
    m_pSFParent = pParent;
    if( m_pSFParent )
       m_pSFParent->AddRef();

    // get the PIDL manager
	m_pPidlMgr = new CPidlMgr();
    if( !m_pPidlMgr )
    {
       delete this;
       return;
	}

	// get the shell's memory manager
    if( FAILED(SHGetMalloc(&m_pMalloc)) )
    {
      delete this;
      return;
    }

	// makes a copy of the PIDL and the HWND
    m_pidl = m_pPidlMgr->Copy( pidl );
    if( m_pidl )
    {
		HWND h = m_pPidlMgr->GetData( m_pidl );
		if( IsWindow(h) )
			m_hWnd = h;
    }

	// default sort mode
	m_uSortField = 3;  // by HWNDs

	m_ObjRefCount = 1;
	g_DllRefCount++;
}


CShellFolder::~CShellFolder()
{
	if( m_pidl )
	{
	   m_pPidlMgr->Delete( m_pidl );
	   m_pidl = NULL;
	}

	if( m_pSFParent )
	   m_pSFParent->Release();

	if( m_pMalloc )
	   m_pMalloc->Release();

	if( m_pPidlMgr )
	   delete m_pPidlMgr;

	g_DllRefCount--;
}



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

	if(IsEqualIID(riid, IID_IUnknown))
	   *ppReturn = this;
	else 
	if(IsEqualIID(riid, IID_IPersistFolder))
	   *ppReturn = (IPersistFolder*)this;
	else 
	if(IsEqualIID(riid, IID_IShellFolder))
	   *ppReturn = (IShellFolder*)this;
	
	if( *ppReturn )
    {
        LPUNKNOWN pUnk = (LPUNKNOWN)(*ppReturn);
		pUnk->AddRef();
		return S_OK;
    }

	return E_NOINTERFACE;
}                                             


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


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



/*---------------------------------------------------------------*/
// IPersistFolder methods
/*---------------------------------------------------------------*/
STDMETHODIMP CShellFolder::GetClassID(LPCLSID lpClassID)
{
	*lpClassID = CLSID_WinView;
	return S_OK;
}


STDMETHODIMP CShellFolder::Initialize(LPCITEMIDLIST pidl)
{
	return S_OK;
}



/*---------------------------------------------------------------*/
// IShellFolder methods
/*---------------------------------------------------------------*/

// BindToObject
STDMETHODIMP CShellFolder::BindToObject(
          LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID* ppvOut)
{
   CShellFolder* pShellFolder = new CShellFolder(this, pidl);
   if(!pShellFolder)
      return E_OUTOFMEMORY;

   HRESULT hr = pShellFolder->QueryInterface(riid, ppvOut);
   pShellFolder->Release();
   return hr;
}


// BindToStorage
STDMETHODIMP CShellFolder::BindToStorage( LPCITEMIDLIST pidl, 
     LPBC pbcReserved, REFIID riid, LPVOID *ppvOut )
{
	return E_NOTIMPL;
}


// CompareIDs
STDMETHODIMP CShellFolder::CompareIDs(
                    LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
   // This function is always called with lParam set to 0. By convention,
   //  this means "sort by name"; other non-zero values are usually meant to
   //  indicate specific folder-sorting rules. Note that here I'm using the
   //  m_uSortField data member as a 'replacement' for lParam.

   HWND hwnd1 = m_pPidlMgr->GetData(pidl1);
   HWND hwnd2 = m_pPidlMgr->GetData(pidl2);

   // Sorting by CHILDREN
   if(m_uSortField == 1 || m_uSortField == -1)
   {
      int fChildren1 = m_pPidlMgr->HasChildren(hwnd1);
      int fChildren2 = m_pPidlMgr->HasChildren(hwnd2);

      if(fChildren1 < fChildren2)
         return m_uSortField;
      else if(fChildren1 > fChildren2)
         return m_uSortField * -1;
      else
         return 0;
   }

   // Sorting by CLASS
   if(m_uSortField == 2 || m_uSortField == -2)
   {
      TCHAR szClass1[100];
      TCHAR szClass2[100];
      GetClassName(hwnd1, szClass1, 100);
      GetClassName(hwnd2, szClass2, 100);
      return m_uSortField * lstrcmpi(szClass1, szClass2);
   }

   // Sorting by TITLE
   if(m_uSortField == 4 || m_uSortField == -4)
   {
      TCHAR szTitle1[100];
      TCHAR szTitle2[100];
      GetWindowText(hwnd1, szTitle1, 100);
      GetWindowText(hwnd2, szTitle2, 100);
      return m_uSortField * lstrcmpi(szTitle1, szTitle2);
   }

   // sorting by HWND
   if(hwnd1 < hwnd2)
      return m_uSortField;
   else if(hwnd1 > hwnd2)
      return m_uSortField * -1;
   else
      return 0;
}


// CreateViewObject
STDMETHODIMP CShellFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID* ppvOut)
{
   CShellView* pShellView = new CShellView(this, m_pidl);
   if(!pShellView)
      return E_OUTOFMEMORY;

   m_pShellView = pShellView;
   HRESULT hr = pShellView->QueryInterface(riid, ppvOut);
   pShellView->Release();
   return hr;
}


// EnumObjects
STDMETHODIMP CShellFolder::EnumObjects(
                  HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST* ppEnumIDList)
{
   // hwndOwner is just the HWND to use as the parent for any message box
   HRESULT hr;
   *ppEnumIDList = NULL;

   HWND hWnd = m_pPidlMgr->GetData(m_pidl);
   *ppEnumIDList = new CEnumIDList(hWnd, dwFlags, &hr);
   if(*ppEnumIDList == NULL)
      return hr;

   return S_OK;
}


// GetAttributesOf
STDMETHODIMP CShellFolder::GetAttributesOf(
                    UINT uCount, LPCITEMIDLIST aPidls[], LPDWORD pdwAttribs)
{
   *pdwAttribs = -1;

   for(UINT i = 0 ; i < uCount ; i++)
   {
      DWORD dwAttribs = 0;

      // Is this item a window?
      HWND hwnd = m_pPidlMgr->GetData(aPidls[i]);
      if(IsWindow(hwnd))
      {
         // Assign here all the styles you want the items to have in common
         // Of course, it's then up to you to manage them properly.
         if(m_pPidlMgr->HasChildren(hwnd))
         {
            dwAttribs |= SFGAO_FOLDER;
            if(m_pPidlMgr->HasChildrenOfChildren(hwnd))
               dwAttribs |= SFGAO_HASSUBFOLDER;
         }
      }
      *pdwAttribs = dwAttribs;
   }
   return S_OK;
}


// GetUIObjectOf
STDMETHODIMP CShellFolder::GetUIObjectOf( HWND hwndOwner, 
      UINT uCount, LPCITEMIDLIST *pPidl, REFIID riid, 
      LPUINT puReserved, LPVOID *ppvReturn )
{
	*ppvReturn = NULL;

	if( uCount != 1 )
	   return E_FAIL; 

	// IExtractIcon
	if( IsEqualIID(riid, IID_IExtractIcon) )
	{
	   CExtractIcon *pei;
	   pei = new CExtractIcon( (LPCITEMIDLIST)pPidl[0] );
	   if(pei)
	   {
		  *ppvReturn = pei;
		  return S_OK;
	   }
   
	   return E_OUTOFMEMORY; 
	}

	// IContextMenu
	if( IsEqualIID(riid, IID_IContextMenu) )
	{
	   CContextMenu *pcm;
	   pcm = new CContextMenu( (LPCITEMIDLIST)pPidl[0] );
	   if( pcm )
	   {
		   pcm->AddRef();
		   pcm->QueryInterface( riid, ppvReturn );
		   pcm->Release();
		   
		  return S_OK;
	   }
   
	   return E_OUTOFMEMORY;
	}

	return E_NOINTERFACE;
}


// GetDisplayNameOf
STDMETHODIMP CShellFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET lpName)
{
   TCHAR szText[MAX_PATH] = {0};

   // Get the name to display in the left pane, address bar, etc
   m_pPidlMgr->GetPidlPath(pidl, szText);

   // Must convert string to Unicode, so allocate a wide character string
   int cchOleStr = lstrlen(szText) + 1;
   lpName->pOleStr = reinterpret_cast<LPWSTR>(m_pMalloc->Alloc(cchOleStr * sizeof(WCHAR)));
   if(!lpName->pOleStr)
      return E_OUTOFMEMORY;

   lpName->uType = STRRET_WSTR;
   mbstowcs(lpName->pOleStr, szText, cchOleStr);
   return S_OK;
}


// ParseDisplayName
STDMETHODIMP CShellFolder::ParseDisplayName( HWND hwndOwner, 
       LPBC pbcReserved, LPOLESTR lpDisplayName, 
       LPDWORD pdwEaten, LPITEMIDLIST *pPidlNew, 
       LPDWORD pdwAttributes )
{
	return E_NOTIMPL;
}


// SetNameOf
STDMETHODIMP CShellFolder::SetNameOf(  HWND hwndOwner, 
       LPCITEMIDLIST pidl, LPCOLESTR lpName, 
       DWORD dw, LPITEMIDLIST *pPidlOut )
{
	return E_NOTIMPL;
}


/*  End of file:  ShlFldr.cpp  */

⌨️ 快捷键说明

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