[MFC]如何调用OpenFileDialog?

我还在迷路 2014-09-11 04:02:42
在MFC创建的项目中,创建的是基于对话框的工程

在工程里面实现按钮点击弹出一个打开文件的对话框
在网上搜罗的资料来看是使用OpenFileDialog这个类,但是我在项目中使用这个类创建一个对象,在编译时报错:
error C2065: “OpenFileDialog”: 未声明的标识符

虽然我现在已经用CFileDialog解决了对话框的问题,但是我依然想问,使用OpenFileDialog需要什么前提条件么?
...全文
463 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
我还在迷路 2014-09-15
  • 打赏
  • 举报
回复
结贴散分。。。
dvlinker 2014-09-12
  • 打赏
  • 举报
回复
当然如果是只支持单选,更简单,ofn.lpstrFile即选择的文件名
dvlinker 2014-09-12
  • 打赏
  • 举报
回复
打开文件对话框GetOpenFileName的示例:(支持文件的多选)

	// 修改m_ofn.lpstrFile指向的buf大小,默认的大小太小,此处根据FILE_MAX_COUNT来设定
	int nBufLen = FILE_MAX_COUNT*(MAX_PATH+1) + 1;
	TCHAR* pBuf = new TCHAR[nBufLen];
	memset( pBuf, 0, nBufLen*sizeof(TCHAR) );

	OPENFILENAME ofn;
	memset( &ofn, 0 ,sizeof(ofn) );
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = m_hParentWnd;
	ofn.lpstrFile = pBuf;
	ofn.nMaxFile = nBufLen;
	ofn.lpstrFilter = _T("All Files(*.*)\0*.*\0\0");
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.lpstrInitialDir = NULL;
	ofn.Flags = OFN_EXPLORER|OFN_ALLOWMULTISELECT|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NODEREFERENCELINKS;

	if ( ::GetOpenFileName( &ofn ) )
	{
		int nNewFileItemCount = 0;
		pos = (POSITION)ofn.lpstrFile;
		while ( pos != NULL )
		{
			CString strPathName = GetNextPathName( pos, ofn ); // 依次找到选择的多个文件名
		}
	}
	else
	{
		// 存放用户选择文件路径信息的buf大小有限,当选择的文件过多时,文件信息长度超过定长buf时,DoModal函数
		// 会返回IDCANCEL,CommDlgExtendedError()将返回FNERR_BUFFERTOOSMALL错误,2012/06/05
		DWORD dwErr = CommDlgExtendedError();
		if ( 12291 == dwErr ) // 12291 - FNERR_BUFFERTOOSMALL
		{
			str.Format( STRING_SELED_FILE_EXCEED_COUNT_LIMIT, TRANSFERRED_FILE_ITEM_MAX_COUNT );
			ErrorMsg( str, m_hParentWnd );
		}
	}
	
	delete []pBuf;
至于如何得到多个选择的文件名,可以参考CFileDialog中的相关代码实现,将代码抽出来封装成GetNextPathName函数,供上面调用(虽然不用MFC类,但是MFC类的很多代码写的非常好,可以直接抽出来使用,安全性和稳定性有绝对的保证)

// 主要用于文件打开对话框选中多个文件时,解析出多个文件名,从CFileDialog::GetNextPathName
// 函数中剥离出来
CString GetNextPathName(POSITION& pos, OPENFILENAME& ofn) 
{
	BOOL bExplorer = ofn.Flags & OFN_EXPLORER;
	TCHAR chDelimiter;
	if (bExplorer)
		chDelimiter = '\0';
	else
		chDelimiter = ' ';

	LPTSTR lpsz = (LPTSTR)pos;
	if (lpsz == ofn.lpstrFile) // first time
	{
		if ((ofn.Flags & OFN_ALLOWMULTISELECT) == 0)
		{
			pos = NULL;
			return ofn.lpstrFile;
		}

		// find char pos after first Delimiter
		while(*lpsz != chDelimiter && *lpsz != '\0')
			lpsz = _tcsinc(lpsz);
		lpsz = _tcsinc(lpsz);

		// if single selection then return only selection
		if (*lpsz == 0)
		{
			pos = NULL;
			return ofn.lpstrFile;
		}
	}

	CString strPath = ofn.lpstrFile;
	if (!bExplorer)
	{
		LPTSTR lpszPath = ofn.lpstrFile;
		while(*lpszPath != chDelimiter)
			lpszPath = _tcsinc(lpszPath);
		strPath = strPath.Left(lpszPath - ofn.lpstrFile);
	}

	LPTSTR lpszFileName = lpsz;
	CString strFileName = lpsz;

	// find char pos at next Delimiter
	while(*lpsz != chDelimiter && *lpsz != '\0')
		lpsz = _tcsinc(lpsz);

	if (!bExplorer && *lpsz == '\0')
		pos = NULL;
	else
	{
		if (!bExplorer)
			strFileName = strFileName.Left(lpsz - lpszFileName);

		lpsz = _tcsinc(lpsz);
		if (*lpsz == '\0') // if double terminated then done
			pos = NULL;
		else
			pos = (POSITION)lpsz;
	}

	// only add '\\' if it is needed
	if (!strPath.IsEmpty())
	{
		// check for last back-slash or forward slash (handles DBCS)
		LPCTSTR lpsz = _tcsrchr(strPath, '\\');
		if (lpsz == NULL)
			lpsz = _tcsrchr(strPath, '/');
		// if it is also the last character, then we don't need an extra
		if (lpsz != NULL &&
			(lpsz - (LPCTSTR)strPath) == strPath.GetLength()-1)
		{
			ASSERT(*lpsz == '\\' || *lpsz == '/');
			return strPath + strFileName;
		}
	}

	return strPath + '\\' + strFileName;
}
dvlinker 2014-09-12
  • 打赏
  • 举报
回复
GetSaveFileName的示例:

	TCHAR szFile[MAX_PATH] = { 0 };
	_tcscpy( szFile, _T("123.txt") ); // 初始化文件名
	OPENFILENAME ofn;
	memset( &ofn, 0 ,sizeof(ofn) );
	ofn.lStructSize = sizeof(OPENFILENAME); 
	ofn.hwndOwner = m_hParentWnd; 
	ofn.lpstrFilter = _T("记录文件(*.txt)\0*.txt\0默认格式(*.*)\0*.*\0\0"); 
	ofn.lpstrFile= szFile; 
	ofn.nMaxFile = sizeof(szFile)/sizeof(TCHAR); 
	ofn.lpstrDefExt = _T("txt");
	ofn.lpstrInitialDir = NULL; 
	ofn.Flags = OFN_PATHMUSTEXIST|OFN_EXPLORER|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT; 

	if( ::GetSaveFileName( &ofn ) )
	{
		strSaveFilePathName = ofn.lpstrFile; // 得到用户输入的文件名
        }
我还在迷路 2014-09-12
  • 打赏
  • 举报
回复
引用 11 楼 chenlycly 的回复:
如果不想用CFileDialog类,可以直接使用API来代替:GetOpenFileName和GetSaveFileName,其实CFileDialog类最终也是调用了这两个API的 -------------------------------------------------------------------------------------- 我前段时间将MFC工程改为Win32工程,不再使用MFC类,直接使用API编程,用到上面的两个API函数,需要示例代码,我可以发给你
好的,非常感谢,Lion_Liu_0301@163.com
dvlinker 2014-09-11
  • 打赏
  • 举报
回复
如果不想用CFileDialog类,可以直接使用API来代替:GetOpenFileName和GetSaveFileName,其实CFileDialog类最终也是调用了这两个API的 -------------------------------------------------------------------------------------- 我前段时间将MFC工程改为Win32工程,不再使用MFC类,直接使用API编程,用到上面的两个API函数,需要示例代码,我可以发给你
dvlinker 2014-09-11
  • 打赏
  • 举报
回复
MFC中是没有OpenFileDialog类的
赵4老师 2014-09-11
  • 打赏
  • 举报
回复
查MSDN是Windows程序员必须掌握的技能之一。
赵4老师 2014-09-11
  • 打赏
  • 举报
回复
CFileDialog Member Functions Construction CFileDialog Constructs a CFileDialog object. Operations DoModal Displays the dialog box and allows the user to make a selection. GetPathName Returns the full path of the selected file. GetFileName Returns the filename of the selected file. GetFileExt Returns the file extension of the selected file. GetFileTitle Returns the title of the selected file. GetNextPathName Returns the full path of the next selected file. GetReadOnlyPref Returns the read-only status of the selected file. GetStartPosition Returns the position of the first element of the filename list. Overridables OnShareViolation Called when a share violation occurs. OnFileNameOK Called to validate the filename entered in the dialog box. OnLBSelChangedNotify Called when the list box selection changes. OnFileNameChange Called to handle the CDN_SELCHANGE notification message. OnFolderChange Called to handle the CDN_FOLDERCHANGE notification message. OnInitDone Called to handle the CDN_INITDONE notification message. OnTypeChange Called to handle the CDN_INITDONE notification message. See Also CFileDialog Overview, CFileDialog Data Members, Dialog Box Classes
我还在迷路 2014-09-11
  • 打赏
  • 举报
回复
引用 4 楼 m617105 的回复:
[quote=引用 2 楼 liuhengxiao 的回复:] [quote=引用 1 楼 m617105 的回复:] OpenFileDialog是“.NET Framework 类库 ”里面的。 MFC里类一般都带有C这个前缀
这个方法也试了,没有这个类。。。[/quote] 我说的意思是,这个类是属于“.NET Framework 类库 ”里面的。 MFC中没有这个。 另外我说的MFC的类前面带有“C”是用来区别是不是MFC框架内的类的简易方法[/quote] 哦,那我在MFC里面该怎么做才能去调用OpenFileDialog这个类呢?
浩南_哥 2014-09-11
  • 打赏
  • 举报
回复
引用 2 楼 liuhengxiao 的回复:
[quote=引用 1 楼 m617105 的回复:] OpenFileDialog是“.NET Framework 类库 ”里面的。 MFC里类一般都带有C这个前缀
这个方法也试了,没有这个类。。。[/quote] 我说的意思是,这个类是属于“.NET Framework 类库 ”里面的。 MFC中没有这个。 另外我说的MFC的类前面带有“C”是用来区别是不是MFC框架内的类的简易方法
  • 打赏
  • 举报
回复
mfc也没有COpenFileDialog类吧。
我还在迷路 2014-09-11
  • 打赏
  • 举报
回复
引用 1 楼 m617105 的回复:
OpenFileDialog是“.NET Framework 类库 ”里面的。 MFC里类一般都带有C这个前缀
这个方法也试了,没有这个类。。。
浩南_哥 2014-09-11
  • 打赏
  • 举报
回复
OpenFileDialog是“.NET Framework 类库 ”里面的。 MFC里类一般都带有C这个前缀

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧