博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
打开文件对话框在xp和win7上的实现文件任意多选
阅读量:2429 次
发布时间:2019-05-10

本文共 4065 字,大约阅读时间需要 13 分钟。

作者:朱金灿

来源:

   

       在xp系统上进行文件多选,实际上其文件字符串数组的缓冲区是有限,并不能支持选择任意多个文件,为此以前我还写过一篇文章:。实际上这种做法在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
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
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
::size_type i = 0; i < vecsFilterParts.size(); i += 2 )*/ for (std::vector
::size_type i = 0; i
pDlg;// std::vector
vecsFilterParts;// std::vector
vecFilters; COMDLG_FILTERSPEC* pVecFilter = NULL;; int nFilterNum = 0;// std::vector
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
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
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
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

 

        值得注意的是这个做法并不兼容xp系统,因此在使用哪种做法时需要你先对操作系统的版本进行判断。我专门写了一个例程供大家参考:

 

参考文献:

 

1.

 

2.

转载地址:http://ruimb.baihongyu.com/

你可能感兴趣的文章
Linux驱动之总线
查看>>
一图读懂浏览器演变史 | 每日趣闻
查看>>
苹果安全漏洞曝光:可能有 5 亿部 iPhone 易受攻击
查看>>
打造金融科技银行,招行的底气源自……
查看>>
火爆全网的动态曲线图是怎么做的?
查看>>
程序员感叹一年只能存下15万太少了……网友:潸然泪下
查看>>
文科出身敲出 Instagram,被小札“挤”走,建新冠追踪网站,这个程序员有点牛!...
查看>>
面对 Python,Java 中枪了 | 每日趣闻
查看>>
地方普通院校的计算机专业「科班」学生如何突围而出?| 原力计划
查看>>
小白也能看懂的 Java 异常处理
查看>>
C++ 是如何从代码到游戏的?
查看>>
程序员惊魂 12 小时:“���”引发线上事故
查看>>
调查了 10,975 位 Go 语言开发者,我们有了这些发现!
查看>>
面试官吐槽:“Python程序员就是不行!”网友:我能把你面哭!
查看>>
太真实!深刻解读论文里的话术| 每日趣闻
查看>>
拿来就能用!Python 每天定时发送一句情话 | 原力计划
查看>>
Java“拍了拍”你,面试其实没那么难...
查看>>
帅爆了!3个月0基础转型头条数据分析师,他做对了什么?
查看>>
程序员:我受够了!不想再在小厂里干Java了!
查看>>
厉害!国内大学生计算机编程第一人,一人挑战一个队,百度最年轻 T10,现创业自动驾驶...
查看>>