C常用类整理(2)--文件复制、删除、移动

来源:互联网 发布:nginx 默认日志格式 编辑:程序博客网 时间:2024/06/06 10:02

//////////////////////////////类名CShellFileOp////////////////////////////////
/////////////////////////////////////////////////SHELLFILEOP.H//////////////////////////////////////////////
#if !defined(AFX_SHELLFILEOP_H__DA3A3661_1EF3_11D2_9E56_444553540000__INCLUDED_)
#define AFX_SHELLFILEOP_H__DA3A3661_1EF3_11D2_9E56_444553540000__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000


//constats for use in iSrcDest arguements
const int SH_SRC_FILE = 0;
const int SH_DEST_FILE = 1;

class CShellFileOp 
{
public:

 //
 //simple constructor
 //
 CShellFileOp();
 
 //
 //complex constructor - performs the operation straight away
 //
 CShellFileOp( const HWND phWnd,
      const UINT wFunc,
      const CString sFrom,
      const CString sTo,
      const FILEOP_FLAGS fFlags,
      const CString sProgressTitle);

 //
 //destructor
 //
 virtual ~CShellFileOp();

public: //operations

 //
 // Function to perform copy operation
 //
 long CopyFiles();
 
 //
 // Function to perform delete operation
 //
 long DeleteFiles();
 
 //
 // Function to perform move operation
 //
 long MoveFiles();
 
 //
 // Function to perform rename operation
 //
 long RenameFiles();
 
 //
 // Adds another filename to the end of the current string
 //
 void AddFile(const int iSrcDest, const CString sFile);
 
 //
 // Clears a list of files
 //
 void ClearFiles(const int iSrcDest);
 
 //
 // Function to pre-allocate string memory to prevent
 //  lots of re-allocations
 //
 void SetMaxCount(const int iSrcDest, const long lMax);
 
 //
 // Function to set the dialog title
 //  sTitle is a string to be used
 //  nTitle is a resource ID to get the string from
 void SetTitle(CString sTitle);
 void SetTitle(const int nTitle);
 
 //
 // Function to set the parent HWND of the dialog
 //
 void SetParent(const HWND phWnd);
 
 //
 // Function to get Abort flag
 //
 BOOL AnyOperationsAborted() const;
 
 //
 // Functions to get/set the operation flags
 //
 // Flags that control the file operation. This member can be a combination of the
 // following values:
 //
 // FOF_ALLOWUNDO   Preserves undo information, if possible.
 //
 // FOF_CONFIRMMOUSE  Not implemented.
 //
 // FOF_FILESONLY   Performs the operation only on files if a wildcard
 //       filename (*.*) is specified.
 //
 // FOF_MULTIDESTFILES  Indicates that the pTo member specifies multiple destination
 //       files (one for each source file) rather than one directory
 //       where all source files are to be deposited.
 //
 // FOF_NOCONFIRMATION  Responds with "yes to all" for any dialog box that is
 //       displayed.
 //
 // FOF_NOCONFIRMMKDIR  Does not confirm the creation of a new directory if the
 //       operation requires one to be created.
 //
 // FOF_RENAMEONCOLLISION Gives the file being operated on a new name (such as
 //       "Copy #1 of...") in a move, copy, or rename operation if a
 //       file of the target name already exists.
 //
 // FOF_SILENT    Does not display a progress dialog box.
 //
 // FOF_SIMPLEPROGRESS  Displays a progress dialog box, but does not show the
 //       filenames.
 FILEOP_FLAGS GetFlags() const;
 void SetFlags(const FILEOP_FLAGS fNewFlags);

private: //operations
 
 // function to grab some string space memory
 void GrabMem(const int iSrcDest, const long lNum);

private: //attributes
 
 //max no. char in source string
 long m_lMaxSrcCount;
 
 //max no. char in dest string
 long m_lMaxDestCount;
 
 //current no. char in source string
 long m_lCurSrcCount;
 
 //current no. char in dest string
 long m_lCurDestCount;
 
 //structure for shell call
 SHFILEOPSTRUCT m_FileOp;
 
 //pointer to start of source string
 char * m_pTo;
 
 //pointer to start of dest string
 char * m_pFrom;
 
 //current pointer in source string
 char * m_pSrc;
 
 //current pointer in dest string
 char * m_pDest; 
 
 //title to be used on dialog
 char * m_pTitle;
};

#endif // !defined(AFX_SHELLFILEOP_H__DA3A3661_1EF3_11D2_9E56_444553540000__INCLUDED_)


//////////////////////////////////////////ShellFileOp.cpp//////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ShellFileOp.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//
// CShellFileOp ()
//
// Basic constructor
//
CShellFileOp::CShellFileOp()
{
 m_lMaxSrcCount = 0;
 m_lMaxDestCount = 0;
 m_lCurSrcCount = 0;
 m_lCurDestCount = 0;
 m_pSrc = NULL;
 m_pDest = NULL;
 m_pTo = NULL;
 m_pFrom = NULL;
 m_pTitle = NULL;

 m_FileOp.hwnd = NULL;
    m_FileOp.wFunc = 0;
    m_FileOp.pFrom = NULL;
    m_FileOp.pTo = NULL;
    m_FileOp.fFlags = 0;
    m_FileOp.fAnyOperationsAborted = FALSE;
    m_FileOp.hNameMappings = NULL;
    m_FileOp.lpszProgressTitle = NULL;
}

//
// CShellFileOp
//
// Complex constructor - performs the operation straight away
//
CShellFileOp::CShellFileOp( const HWND phWnd,
         const UINT wFunc,
         const CString sFrom,
         const CString sTo,
         const FILEOP_FLAGS fFlags,
         const CString sProgressTitle)
{
 m_lMaxSrcCount = 0;
 m_lMaxDestCount = 0;
 m_lCurSrcCount = 0;
 m_lCurDestCount = 0;
 m_pSrc = NULL;
 m_pDest = NULL;
 m_pTo = NULL;
 m_pFrom = NULL;
 m_pTitle = NULL;

 m_FileOp.hwnd = NULL;
    m_FileOp.wFunc = 0;
    m_FileOp.pFrom = NULL;
    m_FileOp.pTo = NULL;
    m_FileOp.fFlags = 0;
    m_FileOp.fAnyOperationsAborted = FALSE;
    m_FileOp.hNameMappings = NULL;
    m_FileOp.lpszProgressTitle = NULL;

 SetParent(phWnd);
 AddFile(SH_SRC_FILE, sFrom);
 AddFile(SH_DEST_FILE, sTo);
 SetFlags(fFlags);
 SetTitle(sProgressTitle);

 switch (wFunc)
 {
 case FO_COPY:
  CopyFiles();
  break;
 case FO_DELETE:
  DeleteFiles();
  break;
 case FO_MOVE:
  MoveFiles();
  break;
 case FO_RENAME:
  RenameFiles();
  break;
 default:
  break;
 }
}

//
// ~CShellFileOp()
//
// deconstructor - kill all memory before object destruction
//
CShellFileOp::~CShellFileOp()
{
 //free all malloc'd blocks
    if (m_pTo)
  free ((void *)m_pTo );
    if (m_pFrom)
  free ((void *)m_pFrom);
    if (m_pTitle)
  free ((void *)m_pTitle);
}

//
// long CopyFiles ( )
//
// Function to perform copy operation
//
long CShellFileOp::CopyFiles()
{
 m_FileOp.fAnyOperationsAborted = FALSE;
 m_FileOp.wFunc = FO_COPY;
 return SHFileOperation(&m_FileOp);
}

//
// long DeleteFiles ( )
//
// Function to perform delete operation
//
long CShellFileOp::DeleteFiles()
{
 m_FileOp.fAnyOperationsAborted = FALSE;
 m_FileOp.wFunc = FO_DELETE;
 return SHFileOperation(&m_FileOp);
}

//
// long MoveFiles ( )
//
// Function to perform move operation
//
long CShellFileOp::MoveFiles()
{
 m_FileOp.fAnyOperationsAborted = FALSE;
 m_FileOp.wFunc = FO_MOVE;
 return SHFileOperation(&m_FileOp);
}

//
// long RenameFiles ( )
//
// Function to perform rename operation
//
long CShellFileOp::RenameFiles()
{
 m_FileOp.fAnyOperationsAborted = FALSE;
 m_FileOp.wFunc = FO_RENAME;
 return SHFileOperation(&m_FileOp);
}

//
// void ClearFiles ( const int iSrcDest )
//
// Clears a list of files
//
void CShellFileOp::ClearFiles(const int iSrcDest)
{
 if (iSrcDest == SH_SRC_FILE)
 {
  if (m_pFrom)
  {
   free ((void *)m_pFrom);
   m_pFrom = NULL;
   m_FileOp.pFrom = m_pFrom;
   m_lMaxSrcCount = 0;
   m_lCurSrcCount = 0;
  } 
 }
 else
 {
  if (m_pTo)
  {
   free ((void *)m_pTo );
   m_pTo = NULL;
   m_FileOp.pTo = m_pTo;
   m_lMaxDestCount = 0;
   m_lCurDestCount = 0;
  }
 }
}

//
// void AddFile ( const int iSrcDest, CString sFile )
//
// Adds another filename to the end of the current string
//
void CShellFileOp::AddFile(const int iSrcDest, const CString sFile)
{
 int iLength = sFile.GetLength() + 1; //+1 for the null

 if (iSrcDest == SH_SRC_FILE)
 {
  //check enough allocated space...
  if ((m_lCurSrcCount + iLength + 1)> m_lMaxSrcCount) //+1 for the double null termination...
  {
   //have to get more mem.
   GrabMem(iSrcDest, (m_lCurSrcCount + iLength + 1));
  }
  //now theres enough memory!  yay.
  //now copy the filename in
  strcpy(m_pSrc, (LPCTSTR)sFile);

  //go to end of this files null term.
  m_pSrc += iLength;
  m_lCurSrcCount += iLength;

  //always keep it double null terminated, but don't
  // increment past it incase we want to add more files
  m_pSrc[0] = 0;
 }
 else
 {
  //check enough allocated space...
  if ((m_lCurDestCount + iLength + 1)> m_lMaxDestCount) //+1 for the double null termination...
  {
   //have to get more mem.
   GrabMem(iSrcDest, (m_lCurDestCount + iLength + 1));
  }
  //now theres enough memory!  yay.
  //now copy the filename in
  strcpy(m_pDest, (LPCTSTR)sFile);

  //go to end of this files null term.
  m_pDest += iLength;
  m_lCurDestCount += iLength;
  //always keep it double null terminated, but don't
  // increment past it incase we want to add more files
  m_pDest[0] = 0;
 }
}

//
// SetMaxCount( const int iSrcDest, long lMax )
//
// Function to pre-allocate string memory to prevent
//  lots of re-allocations
//
void CShellFileOp::SetMaxCount(const int iSrcDest, const long lMax)
{
 if (iSrcDest == SH_SRC_FILE)
 {
  m_lMaxSrcCount = lMax + 1; //+1 for double null term.
  GrabMem(iSrcDest, m_lMaxSrcCount);
 } else {
  m_lMaxDestCount = lMax + 1; //+1 for double null term.
  GrabMem(iSrcDest, m_lMaxDestCount);
 }
}

//
// SetTitle ( CString sTitle )
//
// Function to set the dialog title from a string
//
void CShellFileOp::SetTitle(CString sTitle)
{
 int iLength;
 char * pBuf;

 //free mem of current title
 if (m_pTitle)
 {
  free ((void *)m_pTitle);
  m_pTitle = NULL;
  m_FileOp.lpszProgressTitle = NULL;
 }

 iLength = sTitle.GetLength()+1;

 if (iLength > 1)
 {
  //grab more mem
  m_pTitle = (char *)malloc(iLength);
  //copy the title
  pBuf = sTitle.GetBuffer(iLength);
  strcpy(m_pTitle, pBuf);
  //now point the struct to the title
  m_FileOp.lpszProgressTitle = m_pTitle;
 }
}

//
// SetTitle ( const int nTitle )
//
// Function to set the dialog title from a resource identifier
//
void CShellFileOp::SetTitle( const int nTitle )
{
 CString sTitle;
 sTitle.LoadString(nTitle);
 SetTitle(sTitle);
}

//
// SetParent ( const HWND phWnd )
//
// Function to set the parent dialog
//
void CShellFileOp::SetParent(const HWND phWnd)
{
 m_FileOp.hwnd = phWnd;
}

//
// BOOL AnyOperationsAborted ( ) const
//
// Function to get Abort flag
//
BOOL CShellFileOp::AnyOperationsAborted() const
{
 return m_FileOp.fAnyOperationsAborted;
}

//
// FILEOP_FLAGS GetFlags() const
//
// Function to return the operation flags
//
FILEOP_FLAGS CShellFileOp::GetFlags() const
{
 return m_FileOp.fFlags;
}

//
// SetFlags ( const FILEOP_FLAGS fNewFlags )
//
// Function to set the operation flags
//
void CShellFileOp::SetFlags(const FILEOP_FLAGS fNewFlags)
{
 m_FileOp.fFlags = fNewFlags;
}

//
// GrabMem( const int iSrcDest, const long lNum )
//
// function to grab some string space memory
//
void CShellFileOp::GrabMem(const int iSrcDest, const long lNum)
{
 char * pMem;
 long lOffset;

 //get current ptr
 if (iSrcDest == SH_SRC_FILE) {
  pMem = m_pFrom;
 } else {
  pMem = m_pTo;
 }

 if (pMem) //some mem is already allocated!
 {
  //have to make sure our offset ptrs dont get screwed up...
  if (iSrcDest == SH_SRC_FILE) {
   lOffset = (m_pSrc - pMem);
  } else {
   lOffset = (m_pDest - pMem);
  }

  //get more!
  pMem = (char *)realloc((void *)pMem, lNum);

  //reassign offset ptr, and max counts
  if (iSrcDest == SH_SRC_FILE) {
   m_pSrc = pMem + lOffset;
   m_lMaxSrcCount = lNum;
  } else {
   m_pDest = pMem + lOffset;
   m_lMaxDestCount = lNum;
  }
 }
 else
 {
  //get first block
  pMem = (char *)malloc(lNum);

  //assign offset ptr to start of block, and max counts
  if (iSrcDest == SH_SRC_FILE) {
   m_pSrc = pMem;
   m_lMaxSrcCount = lNum;
  } else {
   m_pDest = pMem;
   m_lMaxDestCount = lNum;
  }
  pMem[0] = 0; //ensure null terminated
 }
 //assign ptrs in sh structure.
 if (iSrcDest == SH_SRC_FILE) {
  m_pFrom = pMem;
  m_FileOp.pFrom = m_pFrom;

 } else {
  m_pTo = pMem;
  m_FileOp.pTo = m_pTo;
 }
 
}

 

////////////////////////////////////////////////////////////////////例子example///////////////////////////////////////////////////////////////

long CCopyMoveDlg::DoCopyMoveOp(CString sThisFolder)
{
 CShellFileOp shOp;
 long lNameLength;
 int i, iCount;
 CString sDestDir, sSrcDir;
 CString sCache;

 sSrcDir = sThisFolder;

 shOp.SetParent(m_hWnd);
 shOp.SetFlags(FOF_FILESONLY | FOF_RENAMEONCOLLISION | FOF_NOCONFIRMMKDIR | FOF_MULTIDESTFILES);

 iCount = m_lstFiles.GetItemCount();
  
 //create the string of filenames to do: fname + NULL +fname
 sCache = ((CCacheApp *)AfxGetApp())->sCacheDir;

 //calc number of chars in total string
 lNameLength = 0;
 for (i = 0; i < iCount; i++)
 {
  lNameLength += m_lstFiles.GetItemText(i, 1).GetLength() + 1; //+1 for null char
 }
 lNameLength += iCount * (sCache.GetLength() + 1); //+1 for the /
 //set max count to prevent lots of re'allocs
 shOp.SetMaxCount(SH_SRC_FILE, lNameLength);

 //now add in all the strings
 for (i = 0; i < iCount; i++)
 {
  shOp.AddFile(SH_SRC_FILE,
   sCache +
   "//" +
   m_lstFiles.GetItemText(i, 1));
 }

 //now add destination directory
 shOp.AddFile(SH_DEST_FILE,
  sThisFolder +
  "//";
  

 //now do the operation
 return shOp.CopyFiles();