不多说,贴出代码以作备份:

1、使用CFileDlg

原型:

CFileDialog( BOOL bOpenFileDialog, 
LPCTSTR lpszDefExt = NULL, 
LPCTSTR lpszFileName = NULL, 
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL, 
CWnd* pParentWnd = NULL );



参数说明:

Parameters

bOpenFileDialog

Set to TRUE to construct a File Open dialog box or FALSE to construct a File Save As dialog box.

lpszDefExt

The default filename extension. If the user does not include an extension in the Filename edit box, the extension specified by lpszDefExt is automatically appended to the filename. If this parameter is NULL, no file extension is appended.

lpszFileName

The initial filename that appears in the filename edit box. If NULL, no filename initially appears.

dwFlags

A combination of one or more flags that allow you to customize the dialog box. For a description of these flags, see theOPENFILENAME structure in the Win32 SDK documentation. If you modify the m_ofn.Flags structure member, use a bitwise-OR operator in your changes to keep the default behavior intact.

lpszFilter

A series of string pairs that specify filters you can apply to the file. If you specify file filters, only selected files will appear in the Files list box. See the Remarks section for more information on how to work with file filters.

pParentWnd

A pointer to the file dialog-box object’s parent or owner window.




Example1:

创建一个基于对话框的工程,添加一个Button和一个List Box控件,

Button的响应函数:

void CSelectDlg::OnButselect() 
{
	// TODO: Add your control notification handler code here
	CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT 
		|OFN_ALLOWMULTISELECT,"All Files(*.*)|*.*||",AfxGetMainWnd());	//构造文件打开对话框
	CString strPath="";					//声明变量
	if(dlg.DoModal() == IDOK)						//判断是否按下"打开"按钮
	{
		POSITION m_Position = dlg.GetStartPosition();
		while(m_Position != NULL)
		{
			strPath = dlg.GetNextPathName(m_Position);
			m_List.InsertString(m_List.GetCount(),strPath);
		}
	}
}


使用上面的方法能同时选择多个文件,但是上述方法还是有文件数量的限制的,

请看MSDN上的说明:

To allow the user to select multiple files, set theOFN_ALLOWMULTISELECT flag before callingDoModal. You need to supply your own filename buffer to accommodate the returned list of multiple filenames. Do this by replacingm_ofn.lpstrFile with a pointer to a buffer you have allocated, after constructing theCFileDialog, but before callingDoModal. Additionally, you must setm_ofn.nMaxFile with the number of characters in the buffer pointed to bym_ofn.lpstrFile.


由上可知,要实现多选,首先要设置OFN_ALLOWMULTISELECT标志,其次就是filename buffer的大小了,因为当添加的文件很多时,需要一个足够大的空间去存储。


下面贴出优化后的代码:

Example2:

void CSelectDlg::OnButselect() 
{
	// TODO: Add your control notification handler code here

	//声明变量
	CString strPath = _T("");					    
	//构造文件打开对话框
	CFileDialog dlg(TRUE, NULL, NULL, 
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |OFN_ALLOWMULTISELECT, 
		_T("All Files(*.*)|*.*||"), AfxGetMainWnd());	
	
	// 为了实现多文件同时添加
	DWORD max_file = 40000;             // 定义own filename buffer的大小
	TCHAR * lsf = new TCHAR[max_file];
	dlg.m_ofn.nMaxFile = max_file;
	dlg.m_ofn.lpstrFile = lsf;
	dlg.m_ofn.lpstrFile[0] = NULL;      // 初始化对话框
	
	if(dlg.DoModal() == IDOK)			//判断是否按下"打开"按钮
	{
		POSITION m_Position = dlg.GetStartPosition();
		while(m_Position != NULL)
		{
			strPath = dlg.GetNextPathName(m_Position);
			m_List.InsertString(m_List.GetCount(),strPath);
		}
	}
        delete lsf;
}




测试过了,同时添加一千多个文件不是问题。可以通过修改max_file来支持更多的文件。


虽然能同时添加很多文件,但是出现了另一个问题,那就是程序假死了。

所以,如果添加文件很多时还是新建一个线程用于添加文件吧!

Example3:

说明:m_list是List Box控件关联的变量,List Box控件用于显示用户选择的文件


// 声明线程函数
	static DWORD WINAPI ThreadFunc(LPVOID lpParam);
	// 声明线程句柄
	HANDLE m_hThread;


可以在按钮的响应函数中创建线程


// 创建线程
	m_hThread = CreateThread(NULL, 0, ThreadFunc, &m_List, 0, 0);


定义线程函数

DWORD WINAPI CSelectDlg::ThreadFunc(LPVOID lpParam)
{
	CListBox * m_List = (CListBox*)lpParam;

	//声明变量
	CString strPath = _T("");					    
	//构造文件打开对话框
	CFileDialog dlg(TRUE, NULL, NULL, 
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |OFN_ALLOWMULTISELECT, 
		_T("All Files(*.*)|*.*||"), AfxGetMainWnd());	
	
	// 为了实现多文件同时添加
	DWORD max_file = 40000;             // 定义own filename buffer的大小
	TCHAR * lsf = new TCHAR[max_file];
	dlg.m_ofn.nMaxFile = max_file;
	dlg.m_ofn.lpstrFile = lsf;
	dlg.m_ofn.lpstrFile[0] = NULL;      // 初始化对话框
	
	if(dlg.DoModal() == IDOK)			//判断是否按下"打开"按钮
	{
		POSITION m_Position = dlg.GetStartPosition();
		while(m_Position != NULL)
		{
			strPath = dlg.GetNextPathName(m_Position);
			m_List->InsertString(m_List->GetCount(),strPath);
		}
	}

	delete lsf;

	return 1;
}









2、使用GetOpenFileName


BOOL GetOpenFileName(
  LPOPENFILENAME lpofn   // address of structure with initialization 
                         // data
);



Example1:


void CWindowsDialogDlg::OnButtonopen() 
{
	// TODO: Add your control notification handler code here


	OPENFILENAME ofn;
	char strFile[MAX_PATH];
	memset(&ofn,0,sizeof(OPENFILENAME));
	memset(strFile,0,sizeof(char)*MAX_PATH);

	ofn.hwndOwner   = GetSafeHwnd();
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.lpstrFilter = _T("All Files(*.*)");
	ofn.lpstrFile   = strFile;
	ofn.nMaxFile    = MAX_PATH;
	ofn.Flags       = OFN_FILEMUSTEXIST;
	

	if(GetOpenFileName(&ofn)) 
	{
		MessageBox(strFile);  // strFile得用户所选择文件全路径
	}

}

选择一个文件,弹出路径。


Example2:

实现多选:

void CWindowsDialogDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	OPENFILENAME ofn;
	TCHAR szOpenFileNames[1000*MAX_PATH];
	TCHAR szPath[MAX_PATH];
	TCHAR szFileName[1000*MAX_PATH];
	
	TCHAR* p;
	ZeroMemory( &ofn, sizeof(ofn) );
	
	ofn.Flags = OFN_EXPLORER | OFN_ALLOWMULTISELECT;
	ofn.lStructSize = sizeof(ofn);
	ofn.lpstrFile = szOpenFileNames;
	ofn.nMaxFile = sizeof(szOpenFileNames);
	ofn.lpstrFile[0] = NULL;
	ofn.lpstrFilter = _T("All Files(*.*)|*.*||");
	
	if( GetOpenFileName( &ofn ) )
	{  
		// 获取文件夹路径szPath
		lstrcpyn(szPath, szOpenFileNames, ofn.nFileOffset );
		lstrcat(szPath, _T("\\"));   // 末尾加上反斜杠

		p = szOpenFileNames + ofn.nFileOffset; //把指针移到第一个文件

		while( *p )
		{   
			ZeroMemory(szFileName, sizeof(szFileName));
			lstrcat(szFileName, szPath);  //给文件名加上路径  
			lstrcat(szFileName, p);       //加上文件名     
			
			// 插入到List Box中
			m_list.InsertString(m_list.GetCount(), szFileName);

			p += lstrlen(p) +1;           //移至下一个文件
		}
	}	
}





好了,基本就是这些。