文件与文件夹的操作其实也就那几个函数,但是有些细节如果没有注意那可能是个大麻烦,比如路径正确与否、有些串后的空格、文件命名规则限制等。特此写个备忘呵呵
一 、以复制文件为例:其余操作可通过参数wFunc修改相关功能。
BOOL CopyFolder(LPCTSTR lpszFromPath,LPCTSTR lpszToPath)
{
int nLengthFrm = _tcslen(lpszFromPath);
TCHAR *NewPathFrm = new TCHAR[nLengthFrm+2];
_tcscpy(NewPathFrm,lpszFromPath);
NewPathFrm[nLengthFrm] = '\0';
NewPathFrm[nLengthFrm+1] = '\0';
SHFILEOPSTRUCT FileOp;
ZeroMemory((void*)&FileOp,sizeof(SHFILEOPSTRUCT));
FileOp.fFlags = FOF_NOCONFIRMATION ;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = NewPathFrm;
FileOp.pTo = lpszToPath;
FileOp.wFunc = FO_COPY;
return SHFileOperation(&FileOp) == 0;
}
通过上面的函数传入两个参数(原路径和复制路径)即可实现文件或文件夹的复制。但是我遇到了一个问题,当我欲复制的文件名字已经存在时我想获取系统自动创建的新的名字;折腾了一下找到了方法,通过修改参数fFlags 为FOF_RENAMEONCOLLISION|FOF_WANTMAPPINGHANDLE即可获取到hNameMappings参数的句柄,通过将此句柄转换为如下结构体类型便可获取文件名;结构体声明如下:
struct HANDLETOMAPPINGS
{
UINT uNumberOfMappings;
LPSHNAMEMAPPING lpSHNameMapping;
};
第一个参数为数组中mappings的总数,第二个参数为指向mappings数组的指针。通过查找资料我发现第二个参数又有四个成员分别为:cchOldPath、cchNewPath、pszOldPath、pszNewPath,具体我没有深究,但我晓得第三个和第四个分别为重名文件的名字和新名字;至此获得这个名字应该没有什么问题了,附上我修改后的函数供参考。其中返回值是我为了判定是否存在重复文件而设置的。
BOOL CopyFolder(LPCTSTR lpszFromPath,LPCTSTR lpszToPath)
{
CString l_str;
int nLengthFrm = _tcslen(lpszFromPath);
TCHAR *NewPathFrm = new TCHAR[nLengthFrm+2];
_tcscpy(NewPathFrm,lpszFromPath);
NewPathFrm[nLengthFrm] = '\0';
NewPathFrm[nLengthFrm+1] = '\0';
SHFILEOPSTRUCT FileOp;
ZeroMemory((void*)&FileOp,sizeof(SHFILEOPSTRUCT));
FileOp.fFlags = FOF_NOCONFIRMATION |FOF_RENAMEONCOLLISION|FOF_WANTMAPPINGHANDLE;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = NewPathFrm;
FileOp.pTo = lpszToPath;
FileOp.wFunc = FO_COPY;
int iReturn;
iReturn = SHFileOperation(&FileOp);
if (iReturn == 0)
{
HANDLETOMAPPINGS *phtm = NULL;
if (FileOp.hNameMappings!=NULL)
{
phtm = (HANDLETOMAPPINGS*)FileOp.hNameMappings;
l_str = phtm->lpSHNameMapping[0].pszNewPath;
m_strDragName=l_str.Right(l_str.GetLength()-l_str.ReverseFind( '\\')-1);
SHFreeNameMappings(FileOp.hNameMappings);
return true;
}
return false;
}
}
删除文件和文件夹,附个函数,大体和复制差不多。我还发现很多人使用的时候会被路径后面的'\0'卡住,导致总也
bool DeleteSelectFile(LPCTSTR lpszPath)
{
int nLength = _tcslen(lpszPath);
TCHAR *NewPath = new TCHAR[nLength+2];
_tcscpy(NewPath,lpszPath);
NewPath[nLength] = '\0';
NewPath[nLength+1] = '\0';
SHFILEOPSTRUCT FileOp;
ZeroMemory((void*)&FileOp,sizeof(SHFILEOPSTRUCT));
FileOp.fFlags = FOF_NOCONFIRMATION;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = NewPath;
FileOp.pTo = NULL;
FileOp.wFunc = FO_DELETE;
return SHFileOperation(&FileOp) == 0;
}
移动文件夹和文件
BOOL MoveFolder(LPCTSTR lpszFromPath,LPCTSTR lpszToPath)
{
int nLengthFrm = strlen(lpszFromPath);
char *NewPathFrm = new char[nLengthFrm+2];
strcpy(NewPathFrm,lpszFromPath);
NewPathFrm[nLengthFrm] = '\0';
NewPathFrm[nLengthFrm+1] = '\0';
SHFILEOPSTRUCT FileOp;
ZeroMemory((void*)&FileOp,sizeof(SHFILEOPSTRUCT));
FileOp.fFlags = FOF_NOCONFIRMATION ;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = NewPathFrm;
FileOp.pTo = lpszToPath;
FileOp.wFunc = FO_MOVE;
return SHFileOperation(&FileOp) == 0;
}
重命名文件或文件夹
BOOL ReNameFolder(LPCTSTR lpszFromPath,LPCTSTR lpszToPath)
{
int nLengthFrm = strlen(lpszFromPath);
char *NewPathFrm = new char[nLengthFrm+2];
strcpy(NewPathFrm,lpszFromPath);
NewPathFrm[nLengthFrm] = '\0';
NewPathFrm[nLengthFrm+1] = '\0';
SHFILEOPSTRUCT FileOp;
ZeroMemory((void*)&FileOp,sizeof(SHFILEOPSTRUCT));
FileOp.fFlags = FOF_NOCONFIRMATION ;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = NewPathFrm;
FileOp.pTo = lpszToPath;
FileOp.wFunc = FO_RENAME;
return SHFileOperation(&FileOp) == 0;
}