MFC文件操作

CFile

CFile 类

Microsoft 基础类文件类的基类。

cpp 复制代码
class CFile : public CObject
名称 描述
CFile::Abort 关闭文件并忽略所有警告和错误。
CFile::Close 关闭文件并删除对象。
CFile::D uplicate 基于此文件构造一个重复对象。
CFile::Flush 刷新任何尚未写入的数据。
CFile::GetFileName 检索所选文件的文件名。
CFile::GetFilePath 检索所选文件的完整文件路径。
CFile::GetFileTitle 检索所选文件的标题。
CFile::GetLength 检索文件的长度。
CFile::GetPosition 检索当前文件指针。
CFile::GetStatus 检索打开的文件的状态,或者在静态版本中检索指定文件的状态(静态、虚拟函数)。
CFile::LockRange 锁定文件中的字节范围。
CFile::Open 使用错误测试选项安全打开文件。
CFile::Read 从位于当前文件位置的文件中读取(未缓冲)数据。
CFile::Remove 删除指定的文件(静态函数)。
CFile::Rename 重命名指定的文件(静态函数)。
CFile::Seek 定位当前文件指针。
CFile::SeekToBegin 将当前文件指针定位在文件的开头。
CFile::SeekToEnd 将当前文件指针定位在文件的末尾。
CFile::SetFilePath 设置所选文件的完整文件路径。
CFile::SetLength 更改文件的长度。
CFile::SetStatus 设置指定文件的状态(静态、虚拟函数)。
CFile::UnlockRange 解锁文件中的字节范围。
CFile::Write 将文件中的(未缓冲)数据写入当前文件位置。
名称 描述
CFile::operator HANDLE CFile 对象的句柄。
描述
CFile::hFileNull 确定 CFile 对象是否具有有效句柄。
CFile::m_hFile 通常包含操作系统文件句柄。
名称 描述
CFile::m_pTM 指向 CAtlTransactionManager 对象的指针。

常用函数

范例

cpp 复制代码
void CFileRW::OnSource()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilter;
	strFilter = "All Files(*.*)|*.*|";
	//TRUE,文件>打开;
	//OFN_EXPLORER,使用资源管理器样式的自定义方法。OFN_HIDEREADONLY,隐藏只读复选框。
	//OFN_ENABLESIZING,允许使用鼠标或键盘调整资源管理器样式对话框的大小。OFN_FILEMUSTEXIST,用户只能在 文件名 输入字段中键入现有文件的名称。 
	CFileDialog dlg(TRUE, NULL, NULL, OFN_EXPLORER | OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_FILEMUSTEXIST, strFilter);
	dlg.m_ofn.lStructSize = sizeof(OPENASINFO);
	if (dlg.DoModal() == IDOK)
	{
		m_source_path = dlg.GetPathName();//返回选定文件的完整路径。
	}
	UpdateData(FALSE);//更新数据到UI
}


void CFileRW::OnDestination()
{
	// TODO: 在此添加控件通知处理程序代码
	LPBROWSEINFO lpbi = new BROWSEINFOW();//包含 SHBrowseForFolder 函数的参数,并接收有关用户选择的文件夹的信息
	lpbi->hwndOwner = GetSafeHwnd();//对话框的所有者窗口的句柄。
	lpbi->pidlRoot = NULL;//一个 PIDL,指定要从中开始浏览的根文件夹的位置。
	lpbi->pszDisplayName = NULL;//指向缓冲区的指针,用于接收用户选择的文件夹的显示名称。
	lpbi->lpszTitle = L"请选择要写的文件位置";//指向对话框中树视图控件上方显示的以 null 结尾的字符串的指针。 
	lpbi->ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;//指定对话框选项的标志。BIF_RETURNONLYFSDIRS,仅返回文件系统目录。 BIF_STATUSTEXT, 在对话框中包括状态区域。 回调函数可以通过将消息发送到对话框来设置状态文本。
	lpbi->lpfn = NULL;//指向对话框在事件发生时调用的应用程序定义的函数的指针。 
	
	//SHBrowseForFolder:显示一个对话框,使用户能够选择 Shell文件夹。返回一个 PIDL,该值指定所选文件夹相对于命名空间根目录的位置。
	LPITEMIDLIST lpitemdlist = SHBrowseForFolder(lpbi);
	if (lpitemdlist == NULL)
	{
		delete lpbi;
		lpbi = NULL;
		return;
	}
	char path[MAX_PATH];
	int len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);//将字符串映射到 UTF-16(宽字符)字符串。 返回写入缓冲区的字符数.
	LPWSTR widePath = new wchar_t[len];
	MultiByteToWideChar(CP_ACP, 0, path, -1, widePath, len);
	SHGetPathFromIDList(lpitemdlist, widePath);//将项标识符列表转换为文件系统路径。
	delete lpbi;
	m_destination_path = widePath;
	UpdateData(FALSE);//更新数据到UI
}
cpp 复制代码
void CMFCTest9View::OnCfile()
{
	// TODO: 在此添加命令处理程序代码
	HLOCAL hMen;//本地内存块的句柄。
	char* pByte;
	CString strHint;//提示信息
	CFileRW file;//对话框
	if (file.DoModal() != IDOK)
	{
		return;
	}
	CFile strFileR, strFileW;	
	LPTSTR pstrBack = (LPTSTR)_tcsrchr(file.m_source_path, '\\');//_tcsrchr,该函数返回一个指针,指向字符串中最后一次出现 ch 的位置;
	CString strFile, strDesFullPath;
	strFile.Format(L"%s", pstrBack);//获取\文件名.扩展名
	strDesFullPath = file.m_destination_path + strFile;//目标完整路径 + \文件名.扩展名
	strFileR.Open(file.m_source_path, CFile::modeRead | CFile::shareDenyWrite);//打开文档
	hMen = LocalAlloc(LHND, strFileR.GetLength() + 1);//分配内存,从堆中分配指定的字节数。
	if (hMen == NULL)
	{
		return;
	}
	pByte = (char*)LocalLock(hMen);//锁定内存,管理本地内存对象锁定的函数,它通过递减锁计数来释放对内存对象的锁定,确保内存可被移动或释放。
	memset(pByte, (BYTE)0, strFileW.GetLength() + 1);//初始化内存,将缓冲区设置为指定的字符(0)。
	strHint.Format(L"开始读取文件%s", file.m_source_path);//格式化字符串
	AfxMessageBox(strHint);
	strFileR.Read(pByte, strFileR.GetLength());//将与 CFile 对象关联的文件中的数据读入缓冲区。ReadHuge()已被Read()代替。
	strFileW.Open(strDesFullPath, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite);//打开文档
	strFileW.Write(pByte, strFileR.GetLength());//将文件中的(未缓冲)数据写入当前文件位置。WriteHuge()已被Write()代替。
	strHint.Format(L"文件写到%s完毕", strDesFullPath);
	AfxMessageBox(strHint);

	LocalUnlock(pByte);//递减与分配有 LMEM_MOVEABLE的内存对象关联的锁计数。
	LocalFree(hMen);//释放内存,释放指定的本地内存对象并使其句柄失效。
	strFileR.Close();//关闭文档
	strFileW.Close();
}

CStdioFile

CStdioFile类

cpp 复制代码
class CStdioFile : public CFile
名称 描述
CStdioFile::Open 已重载。 Open 旨在与默认 CStdioFile 构造函数结合使用(替代 CFile::Open)。
CStdioFile::ReadString 读取单行文本。
CStdioFile::Seek 定位当前文件指针。
CStdioFile::WriteString 写入单行文本。
名称 描述
CStdioFile::m_pStream 包含指向已打开文件的指针。

常用函数

范例

在前一例子的基础上。

cpp 复制代码
#define nColumns 20	//列表框控件的列数
#define nRows 50	//列表框控件的行数
#define STR_LEN 20	//字符串固定长度,用在MakeStr函数中
cpp 复制代码
void CMFCTest9View::OnInitialUpdate()
{
	CListCtrl* listCtrl = &GetListCtrl();//获取对与视图相关联的列表控件的引用。
	listCtrl->SetTextBkColor(RGB(192, 192, 192));//列表视图控件中的文本的背景色。
	listCtrl->InsertColumn(0, _T("#"), LVCFMT_LEFT, 20, -1);//在列表视图控件中插入新列。LVCFMT_LEFT,左对齐。
	//插入列头
	for (int nColumn = 1; nColumn < nColumns - 1; nColumn++)
	{
		listCtrl->InsertColumn(nColumn, CString((TCHAR)(_T('A') + nColumn - 1)), LVCFMT_LEFT, 70);//在列表视图控件中插入新列。
	}
	//插入列表记录
	for (int i = 0; i < nRows; i++)
	{
		CString str;
		str.Format(L"%d", i);
		listCtrl->InsertItem(i, str);//在列表视图控件中插入项。i行
		listCtrl->SetItemData(i, i);//设置与 nItem 指定的项的值。
		for (int nColumn = 1; nColumn < nColumns - 1; nColumn++)
		{
			str.Format(L"Item (%d, %d)", nColumn - 1, i);
			listCtrl->SetItemText(i, nColumn, str);//更改列表视图项或子项的文本。i行的nColumn列
		}
	}
	DWORD dwStyle;
	dwStyle = ::GetWindowLong(listCtrl->m_hWnd, GWL_STYLE);//检索有关指定窗口的检索窗口样式(GWL_STYLE)。	m_hWnd,附加到此 CWnd 的 HWND。
	dwStyle |= LVS_REPORT | LVS_SHOWSELALWAYS | LVS_EDITLABELS;
	::SetWindowLong(listCtrl->m_hWnd, GWL_STYLE, dwStyle);//更改指定窗口的检索窗口样式(GWL_STYLE)。
	dwStyle = listCtrl->GetExtendedStyle();//检索列表视图控件当前的扩展样式。
	dwStyle |= LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP | LVS_EX_TRACKSELECT;
	listCtrl->SetExtendedStyle(dwStyle);//	设置列表视图控件当前的扩展样式。

	CListView::OnInitialUpdate();
}
cpp 复制代码
#include <locale.h>
cpp 复制代码
void CMFCTest9View::OnCstdiofile()
{
	// TODO: 在此添加命令处理程序代码
	CListCtrl* listCtrl = &GetListCtrl();//获取对与视图相关联的列表控件的引用。
		
	//获取文件
	CFileDialog myFileDlg(FALSE, L"txt", _T("CStdioFile写文件"), NULL, L"Text(*.txt)|*.txt|All Files(*.*)|*.*||", NULL, 0, TRUE);//构造CFileDialog
	myFileDlg.m_ofn.lpstrTitle = _T("请选择保存路径:");//要放置在对话框标题栏中的字符串。 
	CString strFileName;//文件名
	if (myFileDlg.DoModal() != IDOK)
	{
		return;
	}
	strFileName = myFileDlg.GetFileName();//返回所选文件的文件名。	

	//CStdioFile写文件
	CStdioFile exportFile;//CStdioFile对象
	exportFile.Open(strFileName, CFile::modeCreate | CFile::modeWrite, NULL);//打开文档
	//_strdup:复制字符串。
	//setlocale用于‌设置或查询程序的本地化环境‌,其主要作用是‌影响程序中数字、货币、日期时间、字符串比较等格式的显示和处理方式‌,以适应不同地区的需求
	char* oldLocale = _strdup(setlocale(LC_CTYPE, NULL)); //保存原区域
	setlocale(LC_CTYPE, "chs"); //设置为简体中文

	int iHdrItemCount, iListItemCount;//字段数、记录数
	//CHeaderCtrl:标题控件是一个窗口,通常位于一组文本或数字列上方。 它包含每列的标题,可以分为多个部分。
	CHeaderCtrl* pHdrCtl = listCtrl->GetHeaderCtrl();//检索列表视图控件的标头控件。
	iHdrItemCount = pHdrCtl->GetItemCount();//检索列表视图控件中的项数(列数)。
	iListItemCount = listCtrl->GetItemCount();//行数

	CString strCount;//记录条数	
	strCount.Format(L"共有记录:%d条。", iListItemCount);	
	CTime t = CTime::GetCurrentTime();//返回表示当前时间的 CTime 对象
	CString strTime = L"CStdioFile 文件建立于: 20%y-%m-%d %H:%M:%S ";
	//CString time;
	strTime = t.Format(strTime);
	strTime += strCount;
	exportFile.WriteString(strTime + "\n\n");//	写入单行文本。

	CString strHint;//提示信息
	strHint.Format(L"开始写文件%s", strFileName);
	AfxMessageBox(strHint);

	LVCOLUMN lvcom;//包含有关报表视图中的列的信息。
	lvcom.mask = LVCF_TEXT;//指定哪些成员包含有效信息的变量。LVCF_TEXT,pszText成员有效。
	lvcom.cchTextMax = MAX_PATH;

	WCHAR strCaption[MAX_PATH];
	lvcom.pszText = strCaption;//指定接收列标题文本的缓冲区的地址。

	//char strCaption[MAX_PATH] = {0};
	////int len = MultiByteToWideChar(CP_ACP, 0, strCaption, MAX_PATH, NULL, 0);//将字符串映射到 UTF-16(宽字符)字符串。 返回写入缓冲区的字符数.
	//LPWSTR wStrCaption = new wchar_t[MAX_PATH];
	//MultiByteToWideChar(CP_ACP, 0, strCaption, -1, wStrCaption, MAX_PATH);
	//lvcom.pszText = wStrCaption;

	CString strSub, str1;//行和单元信息
	//遍历记录数
	for (int k = 0; k < iHdrItemCount; k++)
	{
		listCtrl->GetColumn(k, &lvcom);//检索控件的列的属性。
		str1.Format(L"%s", lvcom.pszText);//格式化列信息
		strSub += MakeStr(str1, 14);//格式化记录
	}
	exportFile.WriteString(strSub + "\n");//写入单行文本。

	strSub = "";
	int j = listCtrl->GetItemCount();//检索列表视图控件中的项数(行数)。
	int jj = listCtrl->GetHeaderCtrl()->GetItemCount();//检索标题控件中的项计数(列数)。

	for (int i = 0; i < j; i++)
	{
		for (int k = 0; k < jj; k++)
		{
			str1 = listCtrl->GetItemText(i, k);//检索列表视图项或子项的文本。
			strSub += MakeStr(str1, 14);//格式化记录
		}
		exportFile.WriteString(strSub + "\n");//写入单行文本。
		strSub = "";
	}
    setlocale(LC_CTYPE, oldLocale); //恢复原区域
	free(oldLocale); //释放资源
	exportFile.Close();//关闭文档
	strHint.Format(L"文件写到%s完毕", strFileName);//格式化意识
	AfxMessageBox(strHint);
}
cpp 复制代码
CString CMFCTest9View::MakeStr(CString& str, short size)
{
	WCHAR buf[STR_LEN];
	//根据size,填充 ' '
	for (int i = 0; i < size; ++i)
	{
		buf[i] = L' ';
	}
	CString str1;
	str1.Format(L"%s", buf);
	str += str1;
	return str.Left(size);//提取字符串的左侧部分。多于部分不要。
}

CFileFind

CFileFind类

cpp 复制代码
class CFileFind : public CObject
名称 描述
CFileFind::Close 关闭搜索请求。
CFileFind::FindFile 搜索目录以获取指定文件名。
CFileFind::FindNextFile 从上一次对 FindFile 的调用继续文件搜索。
CFileFind::GetCreationTime 获取文件的创建时间。
CFileFind::GetFileName 获取所找到文件的名称(包括扩展名)
CFileFind::GetFilePath 获取所找到文件的完整路径。
CFileFind::GetFileTitle 获取所找到文件的标题。 标题不包括扩展名。
CFileFind::GetFileURL 获取所找到文件的 URL,包括文件路径。
CFileFind::GetLastAccessTime 获取上次访问文件的时间。
CFileFind::GetLastWriteTime 获取上次更改并保存文件的时间。
CFileFind::GetLength 获取所找到文件的长度(以字节为单位)。
CFileFind::GetRoot 获取所找到文件的根目录。
CFileFind::IsArchived 确定所找到文件是否已存档。
CFileFind::IsCompressed 确定所找到文件是否已压缩。
CFileFind::IsDirectory 确定所找到文件是否为目录。
CFileFind::IsDots 确定所找到文件的名称是否具有名称"."或"..",指示该名称实际上是一个目录。
CFileFind::IsHidden 确定所找到文件是否已隐藏。
CFileFind::IsNormal 确定所找到文件是否正常(换言之,没有其他属性)。
CFileFind::IsReadOnly 确定所找到文件是否为只读文件。
CFileFind::IsSystem 确定所找到文件是否为系统文件。
CFileFind::IsTemporary 确定所找到文件是否为临时文件。
CFileFind::MatchesMask 指示要找到的文件的所需文件属性。
名称 描述
CFileFind::CloseContext 关闭当前搜索句柄指定的文件。
名称 描述
CFileFind::m_pTM 指向 CAtlTransactionManager 对象的指针。

常用函数

范例

cpp 复制代码
class CFleFd : public CDialogEx
{
public:
	CString strDirFile;//当前路径信息
	long lFileCount, lDirCount;//文件夹、文件计数
	CStdioFile exportFile;//CStdioFile文件
}
cpp 复制代码
void CFleFd::OnDirSel()
{
	// TODO: 在此添加控件通知处理程序代码
	LPBROWSEINFO lpbi = new BROWSEINFOW();//文件夹的信息
	lpbi->hwndOwner = GetSafeHwnd();//对话框的所有者窗口的句柄。CWnd::GetSafeHwnd返回m_hWnd;
	lpbi->pidlRoot = NULL;//一个 PIDL,指定要从中开始浏览的根文件夹的位置。
	lpbi->pszDisplayName = NULL;//指向缓冲区的指针,用于接收用户选择的文件夹的显示名称。 
	lpbi->lpszTitle = L"请选择要遍历的目录位置:";
	lpbi->ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;//BIF_RETURNONLYFSDIRS,仅返回文件系统目录。BIF_STATUSTEXT,在对话框中包括状态区域。
	lpbi->lpfn = NULL;//指向对话框在事件发生时调用的应用程序定义的函数的指针。 

	LPITEMIDLIST lpitemdlist = SHBrowseForFolder(lpbi);//显示一个对话框,使用户能够选择 Shell 文件夹。返回一个 PIDL,该值指定所选文件夹相对于命名空间根目录的位置。
	if (lpitemdlist == NULL)
	{
		delete lpbi;
		lpbi = NULL;
		return;
	}
	WCHAR path[MAX_PATH];
	SHGetPathFromIDList(lpitemdlist, path);//将项标识符列表转换为文件系统路径。
	delete lpbi;
	CWnd* pWnd = (CWnd*)GetDlgItem(IDC_DIR);//从指定对话框中检索具有指定 ID 的控件。
	pWnd->SetWindowText(path);//将窗口文本或标题(如果有)设置为指定文本。
	UpdateData(FALSE);//更新UI
}
cpp 复制代码
void CFleFd::OnSaveFile()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilter;
	strFilter = "Txt Files(*.txt)|*.txt||";
	CFileDialog dlg(TRUE, NULL, NULL, OFN_EXPLORER | OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_FILEMUSTEXIST, strFilter);
	dlg.m_ofn.lStructSize = sizeof(OPENFILENAME);
	if (dlg.DoModal() == IDOK)
	{
		strDirFile = dlg.GetPathName();//返回选定文件的完整路径。
	}
	UpdateData(FALSE);//更新UI
}
cpp 复制代码
#include <locale.h>
cpp 复制代码
void CFleFd::OnStart()
{
	// TODO: 在此添加控件通知处理程序代码
	CWnd* pWnd = (CWnd*)GetDlgItem(IDC_DIR);//从指定对话框中检索具有指定 ID 的控件。
	CString path, strHint;
	pWnd->GetWindowText(path);//将窗口文本或标题(如果有)设置为指定文本。
	if (path.IsEmpty())
	{
		AfxMessageBox(L"目录不能为空");
		return;
	}
	exportFile.Open(strDirFile, CFile::modeCreate | CFile::modeWrite, NULL);
	//setlocale用于‌设置或查询程序的本地化环境‌,其主要作用是‌影响程序中数字、货币、日期时间、字符串比较等格式的显示和处理方式‌,以适应不同地区的需求
	char* oldLocale = _strdup(setlocale(LC_CTYPE, NULL)); //保存原区域
	setlocale(LC_CTYPE, "chs"); //设置为简体中文
	lFileCount = 0;
	lDirCount = 0;
	BrowseDir(path);//遍历文件路径
	strHint.Format(L"共有文件夹%d 文件%d个", lDirCount, lFileCount);//提示信息
	AfxMessageBox(strHint);
	setlocale(LC_CTYPE, oldLocale); //恢复原区域
	free(oldLocale); //释放资源
	exportFile.Close();//关闭
}
cpp 复制代码
class CFleFd : public CDialogEx
{
    ...
public:
	...
	void BrowseDir(CString& strDir);
};
cpp 复制代码
//遍历文件路径
void CFleFd::BrowseDir(CString& strDir)
{
	CString serachFile = strDir;//搜索的文件	
	if (serachFile.Right(1) != "\\")//末尾字符不是\(不是目录)
	{
		serachFile += "\\";//末尾字符+"\"
	}
	serachFile += "*.*";

	CFileFind cff;
	BOOL bResult = cff.FindFile(serachFile);//打开文件搜索,如果成功,则不为 0
	CString str;
	while (bResult)
	{
		bResult = cff.FindNextFile();//继续从上一次对 FindFile 的调用继续文件搜索.
		if (cff.IsDirectory() && !cff.IsDots())//当前是目录,且文件的名称不为"."或".."
		{
			CString strPath = cff.GetFilePath();//获取指定文件的完整路径。
			BrowseDir(strPath);//递归
			lDirCount++;//文件夹数量递增
		}
		else if (!cff.IsDirectory() && !cff.IsDots())//当前不是目录,且文件的名称不为"."或".."
		{
			CWnd* pWnd = (CWnd*)GetDlgItem(IDC_DIR);
			str.Format(L"%s", cff.GetFilePath());//获取指定文件的完整路径。
			pWnd->SetWindowTextW(str);//更改指定窗口标题栏的文本
			exportFile.WriteString(str + "\n");//写
			lFileCount++;//数量计数递增
			Sleep(10);
		}
		str = "";
	}
	cff.Close();
}
cpp 复制代码
BOOL CFleFd::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	// TODO:  在此添加额外的初始化
	lFileCount = 0;//初始化
	lDirCount = 0;//初始化
	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}
cpp 复制代码
void CMFCTest9View::OnCfindfile()
{
	// TODO: 在此添加命令处理程序代码
	CFleFd ffd;
	if (ffd.DoModal() != IDOK)
	{
		return;
	}
}

CMemFile

CMemFile 类

cpp 复制代码
class CMemFile : public CFile
名称 描述
CMemFile::Attach 将内存块附加到 CMemFile
CMemFile::D etach CMemFile 中分离内存块,并返回指向已分离的内存块的指针。
CMemFile::GetBufferPtr 获取或写入用于备份内存文件的内存缓冲区。
名称 描述
CMemFile::Alloc 进行替代以修改内存分配行为。
CMemFile::Free 进行替代以修改内存解除分配行为。
CMemFile::GrowFile 进行替代以修改文件扩展时的行为。
CMemFile::Memcpy 进行替代,以修改读取和写入文件时的内存复制行为。
CMemFile::Realloc 进行替代以修改内存重新分配行为。

CSharedFile

CSharedFile 类

cpp 复制代码
class CSharedFile : public CMemFile
名称 描述
CSharedFile::Detach 关闭共享内存文件并返回其内存块的句柄。
CSharedFile::SetHandle 将共享内存文件附加到内存块。

MFC Shell

SHFileOperation

cpp 复制代码
int SHFileOperation( [in, out] LPSHFILEOPSTRUCTA lpFileOp);

[in, out] lpFileOp

类型:LPSHFILEOPSTRUCT

指向 SHFILEOPSTRUCT 结构的指针,该结构包含此函数执行指定操作所需的信息。 此参数必须包含无效值,该值不 NULL。 你负责验证该值。 如果未验证,将遇到意外结果。

如果成功,则返回零;否则为非零。 应用程序通常应只检查零个或非零。

实例

cpp 复制代码
class CShellOperation : public CDialogEx
{
public:
	SHFILEOPSTRUCT fileOpStruct;
	int iIndex;

	...
};
cpp 复制代码
BOOL CShellOperation::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	CComboBox* pCbx = (CComboBox*)GetDlgItem(IDC_FUNCTION);
	if (pCbx)
	{
		pCbx->AddString(L"复制");
		pCbx->AddString(L"删除");
		pCbx->AddString(L"移动");
	}
	iIndex = 0;
	pCbx->SetCurSel(iIndex);
	fileOpStruct.hwnd = GetSafeHwnd();
	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}
cpp 复制代码
void CShellOperation::OnShellSource()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilter;
	strFilter = "All Files(*.*)|*.*|";
	//TRUE,文件>打开;
	//OFN_EXPLORER,使用资源管理器样式的自定义方法。OFN_HIDEREADONLY,隐藏只读复选框。
	//OFN_ENABLESIZING,允许使用鼠标或键盘调整资源管理器样式对话框的大小。OFN_FILEMUSTEXIST,用户只能在 文件名 输入字段中键入现有文件的名称。 
	CFileDialog dlg(TRUE, NULL, NULL, OFN_EXPLORER | OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_FILEMUSTEXIST, strFilter);
	dlg.m_ofn.lStructSize = sizeof(OPENASINFO);
	if (dlg.DoModal() == IDOK)
	{
		m_sourcePath = dlg.GetPathName();//返回选定文件的完整路径。
	}
	UpdateData(FALSE);//更新数据到UI
}
cpp 复制代码
void CShellOperation::OnShellDes()
{
	// TODO: 在此添加控件通知处理程序代码
	LPBROWSEINFO lpbi = new BROWSEINFOW();
	lpbi->hwndOwner = GetSafeHwnd();//对话框的所有者窗口的句柄。
	lpbi->pidlRoot = NULL;//一个 PIDL,指定要从中开始浏览的根文件夹的位置。
	lpbi->pszDisplayName = NULL;//指向缓冲区的指针,用于接收用户选择的文件夹的显示名称。
	lpbi->lpszTitle = L"请选择要写的文件位置";//指向对话框中树视图控件上方显示的以 null 结尾的字符串的指针。 
	lpbi->ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;//指定对话框选项的标志。BIF_RETURNONLYFSDIRS,仅返回文件系统目录。 BIF_STATUSTEXT, 在对话框中包括状态区域。 回调函数可以通过将消息发送到对话框来设置状态文本。
	lpbi->lpfn = NULL;//指向对话框在事件发生时调用的应用程序定义的函数的指针。 

	//SHBrowseForFolder:显示一个对话框,使用户能够选择 Shell文件夹。返回一个 PIDL,该值指定所选文件夹相对于命名空间根目录的位置。
	LPITEMIDLIST lpitemdlist = SHBrowseForFolder(lpbi);
	if (lpitemdlist == NULL)
	{
		delete lpbi;
		lpbi = NULL;
		return;
	}
	char path[MAX_PATH];
	int len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);//将字符串映射到 UTF-16(宽字符)字符串。 返回写入缓冲区的字符数.
	LPWSTR widePath = new wchar_t[len];
	MultiByteToWideChar(CP_ACP, 0, path, -1, widePath, len);
	SHGetPathFromIDList(lpitemdlist, widePath);//将项标识符列表转换为文件系统路径。
	delete lpbi;
	m_desPath = widePath;
	UpdateData(FALSE);//更新数据到UI
}
cpp 复制代码
void CShellOperation::Onexecute()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(FALSE);//更新UI

	CString strTem1, strTem2;
	strTem1 = m_sourcePath;
	strTem2 = m_desPath;
	m_sourcePath.Insert(m_sourcePath.GetLength() + 1, L'\0');//结尾插入字符'\0'
	m_desPath.Insert(m_desPath.GetLength() + 1, L'\0');//结尾插入字符'\0'
	fileOpStruct.pFrom = m_sourcePath;//指向一个或多个源文件名称的指针。
	fileOpStruct.pTo = m_desPath;//指向目标文件或目录名称的指针。 
	int k = m_desPath.GetLength();//目标的长度
	
	CString strPre, strNxt, strMsg, strHint;
	switch (iIndex)
	{
		//复制
		case 0:
		{
			strPre = "将文件";
			strNxt = "中!";
			strPre = strPre + strTem1 + "复制到" + strTem2 + strNxt;
			strHint = "复制被中断";
			strMsg = "复制出错,其代码为:";

			fileOpStruct.lpszProgressTitle = strPre;//指向进度对话框标题的指针。
			fileOpStruct.wFunc = FO_COPY;//一个值,指示要执行的操作。
			break;
		}

		//删除
		case 1:
		{
			strPre = "将文件";
			strNxt = "删除!";
			strPre = strPre + strTem1 + strNxt;
			strHint = "删除被中断";
			strMsg = "删除出错,其代码为:";

			fileOpStruct.lpszProgressTitle = strPre;
			fileOpStruct.wFunc = FO_DELETE;
			break;
		}

		//移动
		case 2:
		{
			strPre = "将文件";
			strNxt = "中!";
			strPre = strPre + strTem1 + "移动到" + strTem2 + strNxt;
			strHint = "移动被中断";
			strMsg = "移动出错,其代码为:";

			fileOpStruct.lpszProgressTitle = strPre;
			fileOpStruct.wFunc = FO_MOVE;
			break;
		}
	}

	fileOpStruct.fFlags = FOF_SIMPLEPROGRESS;//显示进度对话框,但不会在操作时显示单个文件名。
	int res = SHFileOperation(&fileOpStruct);//复制、移动、重命名或删除文件系统对象。如果成功,则返回零;
	DWORD errorCode = GetLastError();//检索调用线程的最后错误代码值。
	if (fileOpStruct.fAnyOperationsAborted == TRUE)//如果任何文件操作在完成之前中止,返回TRUE;
	{
		AfxMessageBox(strHint);
	}
	else
	{
		if (res != 0)
		{
			CString strTem;
			strTem.Format(L"%s %d", strMsg, errorCode);
			AfxMessageBox(strMsg);
		}
	}
	return;
}
cpp 复制代码
void CShellOperation::OnSelchangeFunction()
{
	// TODO: 在此添加控件通知处理程序代码
	CComboBox* pCbx = (CComboBox*)GetDlgItem(IDC_FUNCTION);
	iIndex = pCbx->GetCurSel();
	switch (iIndex)
	{
		case 1:
		{
			CEdit* pWnd = (CEdit*)GetDlgItem(IDC_DES);
			pWnd->ShowWindow(SW_HIDE);
			pWnd = (CEdit*)GetDlgItem(IDC_SHELL_DES);
			pWnd->ShowWindow(SW_HIDE);
			pWnd = (CEdit*)GetDlgItem(IDC_STATIC_DES);
			pWnd->ShowWindow(SW_HIDE);
			break;
		}
	
		case 0:
		case 2:
		{
			CEdit* pWnd = (CEdit*)GetDlgItem(IDC_DES);
			pWnd->ShowWindow(SW_SHOW);
			pWnd = (CEdit*)GetDlgItem(IDC_SHELL_DES);
			pWnd->ShowWindow(SW_SHOW);
			pWnd = (CEdit*)GetDlgItem(IDC_STATIC_DES);
			pWnd->ShowWindow(SW_SHOW);
			break;
		}
	}
}
cpp 复制代码
void CMFCTest9View::OnShellOperation()
{
	// TODO: 在此添加命令处理程序代码
	CShellOperation shellOp;
	shellOp.DoModal();
}

删除后改为移动

相关推荐
春蕾夏荷_7282977252 小时前
Sockets-2.3.9.9 UDP使用实例
c++·udp
GetcharZp3 小时前
拒绝硬编码!C++ 配置文件管理神器 yaml-cpp 实战指南
c++
墨有6663 小时前
C++ string 部分功能详解:迭代器、初始化与常用函数
开发语言·c++
枫叶丹44 小时前
【Qt开发】Qt系统(二)-> 事件分发器
c语言·开发语言·数据库·c++·qt·系统架构
千里马-horse5 小时前
Rect Native bridging 源码分析--AString.h
c++·ts·rn·jsi
闻缺陷则喜何志丹5 小时前
【二分查找】P10091 [ROIR 2022 Day 2] 分数排序|普及+
c++·算法·二分查找
阿豪只会阿巴6 小时前
【多喝热水系列】从零开始的ROS2之旅——Day4
c++·笔记·python·ros2
郭涤生7 小时前
fmtlib/fmt仓库熟悉
c++
Stanford_11068 小时前
【2026新年启程】学习之路,探索之路,技术之路,成长之路……都与你同行!!!
前端·c++·学习·微信小程序·排序算法·微信开放平台