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

📄 atlshellext.h

📁 remote debug and compile tools
💻 H
📖 第 1 页 / 共 4 页
字号:
#ifndef __ATLSHELLEXT_H__
#define __ATLSHELLEXT_H__

#pragma once
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2001 Bjarke Viksoe.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. 
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//

#ifndef __ATLSHELLEXTBASE_H__
   #error atlshellext.h requires atlshellextbase.h to be included first
#endif

#include <atlwin.h>
#include <prsht.h>
#include "resource.h"


//////////////////////////////////////////////////////////////////////////////
// CPidl

class CPidl
{
public:
   LPITEMIDLIST m_pidl;

public:
   CPidl() : m_pidl(NULL)
   {
   }

   virtual ~CPidl()
   {
      Delete();
   }

   BOOL IsEmpty() const
   {
      return PidlIsEmpty(m_pidl);
   }

   operator LPITEMIDLIST() const
   {
      return m_pidl;
   }

   LPITEMIDLIST* operator&()
   {
      ATLASSERT(m_pidl==NULL);
      return &m_pidl;
   }

   void Attach(LPITEMIDLIST pSrc)
   {
      Delete();
      m_pidl = pSrc;
   }

   LPITEMIDLIST Detach()
   {
      LPITEMIDLIST pidl = m_pidl;
      m_pidl = NULL;
      return pidl;
   }

   DWORD GetByteSize() const
   { 
      return PidlGetByteSize(m_pidl);
   }

   UINT GetCount() const
   { 
      return PidlGetCount(m_pidl);
   }

   LPCITEMIDLIST GetNextItem() const
   { 
      return PidlGetNextItem(m_pidl);
   }

   LPCITEMIDLIST GetLastItem() const
   { 
      return PidlGetLastItem(m_pidl);
   }

   LPITEMIDLIST CopyFirstItem() const
   { 
      return PidlCopyFirstItem(m_pidl);
   }
  
   LPITEMIDLIST Copy() const
   { 
      return PidlCopy(m_pidl);
   }

   void Delete()
   { 
      PidlDelete(m_pidl);
      m_pidl = NULL;
   }

   void Copy(LPCITEMIDLIST pidlSource) 
   { 
      Delete();
      m_pidl = PidlCopy(pidlSource);
   }  

   void Concatenate(LPCITEMIDLIST pidl2)
   {
      if( (m_pidl==NULL) && (pidl2==NULL) ) return;
      if( m_pidl==NULL ) {
         m_pidl = PidlCopy(pidl2);
         return;
      }
      if( pidl2==NULL ) return;

      DWORD cb1, cb2;
      cb1 = GetByteSize() - sizeof(USHORT);
      cb2 = PidlGetByteSize(pidl2);
      LPITEMIDLIST pidlNew = (LPITEMIDLIST)_Module.m_Allocator.Alloc(cb1 + cb2);
      if( pidlNew!=NULL ) {
         ::CopyMemory( pidlNew, m_pidl, cb1 );
         ::CopyMemory( ((LPBYTE)pidlNew) + cb1, pidl2, cb2 );
      }
      Attach(pidlNew);
   }

   void RemoveLast()
   {
      LPITEMIDLIST pidlLast = const_cast<LPITEMIDLIST>(PidlGetLastItem(m_pidl));
      if( pidlLast!=NULL ) pidlLast->mkid.cb = 0;
   }

   inline static BOOL PidlIsEmpty(LPCITEMIDLIST pidl)
   {
      return pidl==NULL || pidl->mkid.cb==0;
   }

   static LPCITEMIDLIST PidlGetLastItem(LPCITEMIDLIST pidl) 
   { 
      // Get the PIDL of the last item in the list 
      LPCITEMIDLIST pidlLast = NULL;  
      if( pidl!=NULL ) {    
         while( pidl->mkid.cb > 0 ) { 
            pidlLast = pidl;
            pidl = PidlGetNextItem(pidl);       
         }      
      }  
      return pidlLast; 
   } 

   inline static LPITEMIDLIST PidlGetNextItem(LPCITEMIDLIST pidl) 
   { 
      return pidl==NULL ? NULL : (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
   }  

   static UINT PidlGetCount(LPCITEMIDLIST pidlSource)
   {
      UINT cbTotal = 0; 
      if( pidlSource!=NULL ) {    
         while( pidlSource->mkid.cb > 0 ) {
            cbTotal++;
            pidlSource = PidlGetNextItem(pidlSource); 
         }       
      }  
      return cbTotal; 
   }

   static DWORD PidlGetByteSize(LPCITEMIDLIST pidlSource)
   { 
      DWORD cbTotal = 0; 
      if( pidlSource!=NULL ) {
         while( pidlSource->mkid.cb > 0 ) {
            cbTotal += pidlSource->mkid.cb;       
            pidlSource = PidlGetNextItem(pidlSource);       
         }       
         // Add the size of the NULL terminating ITEMIDLIST    
         cbTotal += sizeof(USHORT);    
      }  
      return cbTotal; 
   }

   static void PidlDelete(LPITEMIDLIST pidlSource)
   {
      if( pidlSource==NULL ) return;
      _Module.m_Allocator.Free( pidlSource ); 
   }

   static LPITEMIDLIST PidlCopy(LPCITEMIDLIST pidlSource) 
   { 
      LPITEMIDLIST pidlTarget = NULL; 
      DWORD cbSource = 0;  
      if( NULL==pidlSource ) return NULL;  
      // Allocate the new pidl 
      cbSource = PidlGetByteSize(pidlSource); 
      pidlTarget = (LPITEMIDLIST)_Module.m_Allocator.Alloc(cbSource); 
      if( pidlTarget==NULL ) return NULL;  // Copy the source to the target 
      ::CopyMemory( pidlTarget, pidlSource, cbSource );
      return pidlTarget; 
   }

   static LPITEMIDLIST PidlCopyFirstItem(LPCITEMIDLIST pidlSource) 
   { 
      LPITEMIDLIST pidlTarget = NULL; 
      DWORD cbSource = 0;  
      if( NULL==pidlSource ) return NULL;  
      // Allocate the new pidl 
      cbSource = pidlSource->mkid.cb + sizeof(USHORT); 
      pidlTarget = (LPITEMIDLIST)_Module.m_Allocator.Alloc(cbSource); 
      if( pidlTarget==NULL ) return NULL;  // Copy the source to the target 
      ::CopyMemory( pidlTarget, pidlSource, cbSource );
      // Terminate the IDList 
      *(WORD *)(((LPBYTE)pidlTarget)+pidlTarget->mkid.cb) = 0;  
      return pidlTarget;
   }

};


/////////////////////////////////////////////////////////////////////////////
// CPidlList

class CPidlList
{
public:
   CPidlList()
   {
      m_pidls = NULL;
      m_nCount = 0;
      m_bOwner = false;
   }
   
   CPidlList(HWND hwndList, DWORD dwListViewMask=LVNI_SELECTED)
   {
      ATLASSERT(::IsWindow(hwndList));

      m_pidls = NULL;
      m_nCount = 0;

      UINT nCount = ( dwListViewMask==LVNI_SELECTED ? ListView_GetSelectedCount(hwndList) : ListView_GetItemCount(hwndList) );
      if( nCount==0 ) return;

      LPITEMIDLIST *pidls = (LPITEMIDLIST *)_Module.m_Allocator.Alloc(nCount * sizeof(LPITEMIDLIST));   
      if( pidls==NULL ) return;
   
      int nItem = -1;
      UINT i = 0;
      while( (nItem = ListView_GetNextItem(hwndList, nItem, dwListViewMask))!=-1 )
      {
         LVITEM lvi = { 0 };
         lvi.mask = LVIF_PARAM;
         lvi.iItem = nItem;
         ListView_GetItem(hwndList, &lvi);
         pidls[i++] = (LPITEMIDLIST)lvi.lParam;
      }

      m_pidls = pidls;
      m_nCount = i;
      m_bOwner = false;
   }
   
   virtual ~CPidlList()
   {
      Delete();
   }

   operator LPCITEMIDLIST *() const 
   { 
      return const_cast<LPCITEMIDLIST *>(m_pidls); 
   }

   UINT GetCount() const 
   { 
      return m_nCount; 
   }

   LPITEMIDLIST *Detach()
   {
      LPITEMIDLIST *pidls = m_pidls;
      m_pidls = NULL;
      m_nCount = 0;
      m_bOwner = false;
      return pidls;
   }
   
   HRESULT Attach(LPITEMIDLIST *pidlSource, UINT nCount, BOOL bOwnItems=FALSE)
   {
      Delete();
      m_pidls = pidlSource;
      m_nCount = nCount;
      m_bOwner = (bOwnItems==TRUE);
      return S_OK;
   }
   
   HRESULT Copy(LPCITEMIDLIST *pidlSource, UINT nCount, BOOL bOwnItems=FALSE)
   {
      ATLASSERT(pidlSource);
      ATLASSERT(nCount>0);
      if( (pidlSource==NULL) || (nCount==0) ) return E_INVALIDARG;
      Delete();
      m_pidls = (LPITEMIDLIST *)_Module.m_Allocator.Alloc(nCount * sizeof(LPITEMIDLIST));
      if( m_pidls==NULL ) return E_OUTOFMEMORY;
      m_nCount = nCount;
      // If requested, we'll make a copy of each PIDL structure too, otherwise
      // simply copy memory (weak reference).
      if( bOwnItems ) {
         for( UINT i=0; i<nCount; i++ ) m_pidls[i] = CPidl::PidlCopy(pidlSource[i]);
         m_bOwner = true;
      }
      else {
         ::CopyMemory(m_pidls, pidlSource, nCount * sizeof(LPITEMIDLIST));
         m_bOwner = false;
      }
      return S_OK;
   }
   
   void Delete()
   {
      if( m_pidls!=NULL ) {
         if( m_bOwner ) for( UINT i=0; i<m_nCount; i++ ) _Module.m_Allocator.Free((LPVOID)m_pidls[i]);
         _Module.m_Allocator.Free(m_pidls);
         m_pidls = NULL;
         m_nCount = 0;
         m_bOwner = false;
      }
   }

   HRESULT Filter(IShellFolder *pFolder, DWORD dwItemMask)
   {
      ATLASSERT(pFolder);
      ATLASSERT(dwItemMask!=0);
      ATLASSERT(!m_bOwner);
      if( m_nCount==0 ) return S_OK;

      LPITEMIDLIST *pidls = (LPITEMIDLIST *)_Module.m_Allocator.Alloc(m_nCount * sizeof(LPITEMIDLIST));
      if( pidls==NULL ) return E_OUTOFMEMORY;

      UINT nCount=0;
      for( UINT i=0; i<m_nCount; i++ ) {
         DWORD dwAttr = dwItemMask;
         LPCITEMIDLIST pidl = m_pidls[i];
         pFolder->GetAttributesOf(1, &pidl, &dwAttr);
         if( (dwAttr & dwItemMask)==dwItemMask ) {
            pidls[nCount] = m_pidls[i];
            nCount++;
         }
      }
      // We've recreated a new PIDL list.
      // The allocated memory for the list may actually be too large, but
      // it doesn't matter for the PIDL functions.
      return Attach(pidls, nCount, FALSE);
   }

   LPITEMIDLIST *m_pidls;
   UINT m_nCount;
   bool m_bOwner;
};


#ifdef __ATLCOM_H__

/////////////////////////////////////////////////////////////////////////////
// CPidlEnum

class ATL_NO_VTABLE CPidlEnum : 
   public CComObjectRootEx<CComSingleThreadModel>,
   public IEnumIDList
{
public:
   CPidlEnum() : m_iCount(0), m_iPos(0), m_pCur(NULL)
   {
   }

DECLARE_NO_REGISTRY()
DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CPidlEnum)
   COM_INTERFACE_ENTRY_IID(IID_IEnumIDList,IEnumIDList)
END_COM_MAP()

public:
   HRESULT _Init(LPCITEMIDLIST pPidlArray, UINT nCount)
   {      
      m_pidl.Copy(pPidlArray);
      m_iCount = nCount;
      Reset();
      return S_OK;
   }

   STDMETHOD(Next)(ULONG /*celt*/, LPITEMIDLIST *rgelt, ULONG *pceltFetched)
   { 

⌨️ 快捷键说明

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