弹出文件选择对话框(支持多选)

来源:互联网 发布:40岁学编程 没公司要 编辑:程序博客网 时间:2024/04/30 01:27

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

1、使用CFileDlg

原型:

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

参数说明:

ParametersbOpenFileDialogSet to TRUE to construct a File Open dialog box or FALSE to construct a File Save As dialog box.lpszDefExtThe 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.lpszFileNameThe initial filename that appears in the filename edit box. If NULL, no filename initially appears.dwFlagsA 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.lpszFilterA 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.pParentWndA 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 hereCFileDialog 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 hereOPENFILENAME 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 hereOPENFILENAME 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 ) ){  // 获取文件夹路径szPathlstrcpyn(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;           //移至下一个文件}}}


好了,基本就是这些。








0 0
原创粉丝点击