打开文件对话框在xp和win7上的实现文件任意多选
2015-02-28 17:26
351 查看
作者:朱金灿
来源:http://blog.csdn.net/clever101
在xp系统上进行文件多选,实际上其文件字符串数组的缓冲区是有限,并不能支持选择任意多个文件,为此以前我还写过一篇文章:使用CFileDialog的钩子函数解决对话框的多选问题。实际上这种做法在vista系统及win7系统上并不支持。那么如何在vista系统及win7系统支持打开文件对话框任意多选文件呢?我想到windows是一个基于com的系统,没准使用com接口能做到。事实上是这样的,需要使用一个叫IFileOpenDialog的接口类。下面是示例代码:
值得注意的是这个做法并不兼容xp系统,因此在使用哪种做法时需要你先对操作系统的版本进行判断。我专门写了一个例程供大家参考:VC文件多选对话框
参考文献:
1. WindowsVista for Developers——第六部分:新的文件对话框
2. IFileDialog使用指南
来源:http://blog.csdn.net/clever101
在xp系统上进行文件多选,实际上其文件字符串数组的缓冲区是有限,并不能支持选择任意多个文件,为此以前我还写过一篇文章:使用CFileDialog的钩子函数解决对话框的多选问题。实际上这种做法在vista系统及win7系统上并不支持。那么如何在vista系统及win7系统支持打开文件对话框任意多选文件呢?我想到windows是一个基于com的系统,没准使用com接口能做到。事实上是这样的,需要使用一个叫IFileOpenDialog的接口类。下面是示例代码:
// Return the file system path for a given IShellItem. static bool PathFromShellItem ( IShellItem* pItem, CString& sPath ) { HRESULT hr; LPOLESTR pwsz = NULL; hr = pItem->GetDisplayName ( SIGDN_FILESYSPATH, &pwsz ); if ( FAILED(hr) ) return false; sPath = pwsz; CoTaskMemFree ( pwsz ); return true; } // Convert a pipe-separated list of filter strings into a vector of // COMDLG_FILTERSPEC. The vector<CString> is needed to actually hold the strings // that the COMDLG_FILTERSPEC structs will point to. static bool BuildFilterSpecList (_U_STRINGorID szFilterList, COMDLG_FILTERSPEC*& pVecFilter,int& nFilterNum ) { std::vector<CString> vecsFilterParts; CString sFilterList = szFilterList.m_lpstr; CString sToken; int nIdx = 0; // Split the passed-in filter list on pipe characters (MFC-style) for(;;) { sToken = sFilterList.Tokenize(_T("|"), nIdx ); if ( sToken.IsEmpty() ) break; vecsFilterParts.push_back ( sToken ); } // There should be an even number of tokens in the string if ( vecsFilterParts.size() & 1 ) { ATLASSERT(0); vecsFilterParts.pop_back(); } if(vecsFilterParts.empty()) return false; nFilterNum = vecsFilterParts.size()/2.0; pVecFilter = new COMDLG_FILTERSPEC[nFilterNum]; // Use each pair of tokens for a COMDLG_FILTERSPEC struct. /*for (std::vector<CString>::size_type i = 0; i < vecsFilterParts.size(); i += 2 )*/ for (std::vector<CString>::size_type i = 0; i <nFilterNum; i++) { USES_CONVERSION; int j = i*2; std::wstring strName = A2W(vecsFilterParts[j]); pVecFilter[i].pszName = new WCHAR[strName.length()+1]; memset((void*)pVecFilter[i].pszName,'\0',(strName.length()+1)*sizeof(WCHAR)); wcsncpy((wchar_t*)pVecFilter[i].pszName,strName.c_str(),strName.length()); j = j+1; std::wstring strSpec = A2W(vecsFilterParts[j]); pVecFilter[i].pszSpec = new WCHAR[strSpec.length()+1]; memset((void*)pVecFilter[i].pszSpec,'\0',(strSpec.length()+1)*sizeof(WCHAR)); wcsncpy((wchar_t*)pVecFilter[i].pszSpec,strSpec.c_str(),strSpec.length()); } // return !vecFilters.empty(); return true; } void CMultiSelectDlg::OnBnClickedBtnVista() { // TODO: 在此添加控件通知处理程序代码 HRESULT hr; CComPtr<IFileOpenDialog> pDlg; // std::vector<CString> vecsFilterParts; // std::vector<COMDLG_FILTERSPEC> vecFilters; COMDLG_FILTERSPEC* pVecFilter = NULL;; int nFilterNum = 0; // std::vector<std::wstring> vecFilters; CString sDlgTitle = _T("Multi-selection File Open Dialog"); CString sOKButtonLabel = _T("确定"); CString sFilenameLabel = _T("文件名(N):"); DWORD dwFlags = 0; // Create the file-open dialog COM object. hr = pDlg.CoCreateInstance( __uuidof(FileOpenDialog) ); if ( FAILED(hr) ) return; // Tell the dlg to load the state data associated with this GUID: // {7D5FE367-E148-4a96-B326-42EF237A3662} // This is not strictly necessary for our app (normally you'd wand loads // and saves to share the same state data) but I'm putting this in for the demo. static const GUID guidFileOpen = { 0x7D5FE367, 0xE148, 0x4A96, { 0xB3, 0x26, 0x42, 0xEF, 0x23, 0x7A, 0x36, 0x62 } }; hr = pDlg->SetClientGuid ( guidFileOpen ); // Call this helper function to convert a pipe-separated file spec list // (like MFC uses) to a vector of COMDLG_FILTERSPEC. if ( BuildFilterSpecList(_T("Text files (*.txt)|*.txt|Executable files (*.exe;*.dll)|*.exe;*.dll|All files (*.*)|*.*|"), pVecFilter,nFilterNum)) hr = pDlg->SetFileTypes(nFilterNum,pVecFilter); // Set some other properties of the dialog. It's not the end of the world if // any of these calls fail. USES_CONVERSION; hr = pDlg->SetTitle (A2W(sDlgTitle)); hr = pDlg->SetOkButtonLabel(A2W(sOKButtonLabel)); hr = pDlg->SetFileNameLabel(A2W(sFilenameLabel)); // Set the multi-select option flag. hr = pDlg->GetOptions ( &dwFlags ); hr = pDlg->SetOptions ( dwFlags | FOS_ALLOWMULTISELECT ); // Set up our event listener. // CComObjectStackEx<CDlgEventHandler> cbk; // Show the dialog! hr = pDlg->Show ( m_hWnd ); //if ( bAdvised ) // pDlg->Unadvise ( dwCookie ); // Get the list of selected items and add each filename to the list ctrl. if ( SUCCEEDED(hr) ) { CComPtr<IShellItemArray> pItemArray; hr = pDlg->GetResults ( &pItemArray ); if ( SUCCEEDED(hr) ) { DWORD cSelItems; hr = pItemArray->GetCount ( &cSelItems ); if ( SUCCEEDED(hr) ) { int nCount = 0; for ( DWORD j = 0; j < cSelItems; j++ ) { CComPtr<IShellItem> pItem; hr = pItemArray->GetItemAt ( j, &pItem ); if ( SUCCEEDED(hr) ) { CString sPath; if ( PathFromShellItem ( pItem, sPath ) ) { m_listbox.AddString(sPath); nCount++; } } } CString str; str.Format(_T("%u files selected"), nCount); m_static.SetWindowText(str); } } } for (int i = 0;i<nFilterNum;i++) { delete []pVecFilter[i].pszName; delete []pVecFilter[i].pszSpec; } delete []pVecFilter; }
值得注意的是这个做法并不兼容xp系统,因此在使用哪种做法时需要你先对操作系统的版本进行判断。我专门写了一个例程供大家参考:VC文件多选对话框
参考文献:
1. WindowsVista for Developers——第六部分:新的文件对话框
2. IFileDialog使用指南
相关文章推荐
- 打开文件对话框在xp和win7上的实现文件任意多选
- win7,xp通用的打开文件浏览对话框的方法
- vba使用win32 API(GetOpenFileName )实现打开文件对话框
- vba使用win32 API(GetOpenFileName )实现打开文件对话框
- 用VC6打开XP风格通用文件对话框
- 使用XP风格的打开文件对话框
- 在打开文件对话框上实现图象预览
- vba使用win32 API(GetOpenFileName )实现打开文件对话框
- vba使用win32 API(GetOpenFileName )实现打开文件对话框
- MFC实现打开、保存文件对话框和浏览文件夹对话框
- vba使用win32 API(GetOpenFileName )实现打开文件对话框
- 打开文件对话框,多选与单选,检测文件是否存在
- vba使用win32 API(GetOpenFileName )实现打开文件对话框
- vba使用win32 API(GetOpenFileName )实现打开文件对话框
- JS实现HTML上用button打开文件对话框
- vba使用win32 API(GetOpenFileName )实现打开文件对话框
- vba使用win32 API(GetOpenFileName )实现打开文件对话框
- vba使用win32 API(GetOpenFileName )实现打开文件对话框
- 在打开文件对话框上实现图象预览(转帖)
- java 实现文件下载的时候,避免浏览器自动打开文件,而是出现另存为对话框