解决CB中TOpenDialog, TOpenPictureDialog打开文件数量有限制的问题
2012-05-23 13:11
381 查看
调用TOpenPictureDialog选择大量图片时候发现,返回的Files里面只有前面的一千多个文件,实际只有我选择文件的一半左右。开始以为是CB的BUG,于是把OpenDialog源码中的MultiSelectBufferSize改大,测试没效果。网上有人说,GetOpenFileName的Ansi版本有32K内存限制,Unicode版本没有限制。实际我的程序已经是Unicode的了。Ansi的API只是进行的字符转换,之后还是调用Unicode版本的API,所以这个方法行不通。
在一个博客里面介绍,可以通过Shell接口自己获取选择的文件,有参考代码,这就好办了,有了解决问题的方向。
那怎么加入CB中呢,直接调用GetOpenFileName? 重写TOpenDialog?都太麻烦了,打开源码,发现有TOpenDialog有个函数void __fastcall GetFileNames(tagOFNW &OpenFileName)是用来取得所选文件的,正好就改它了。这里给出改好的代码,加入工程源码中就可以。
加入代码后,不管TOpenDialog还是TOpenPictureDialog,打开文件数量都不再受限制(当然受内存限制,也不是无限的)。
在此BS一下微软的程序员。
在一个博客里面介绍,可以通过Shell接口自己获取选择的文件,有参考代码,这就好办了,有了解决问题的方向。
那怎么加入CB中呢,直接调用GetOpenFileName? 重写TOpenDialog?都太麻烦了,打开源码,发现有TOpenDialog有个函数void __fastcall GetFileNames(tagOFNW &OpenFileName)是用来取得所选文件的,正好就改它了。这里给出改好的代码,加入工程源码中就可以。
#include <shlobj.h> #ifndef WM_GETISHELLBROWSER #define WM_GETISHELLBROWSER (WM_USER+7) #endif #define GetPIDLFolder(pida) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[0]) #define GetPIDLItem(pida, i) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[i+1]) BOOL ILIsFile(LPCITEMIDLIST pidl) { BOOL bRet = FALSE; LPCITEMIDLIST pidlChild = NULL; IShellFolder* psf = NULL; HRESULT hr = SHBindToParent(pidl, IID_IShellFolder, (LPVOID*) & psf, &pidlChild); if (SUCCEEDED(hr) && psf) { SFGAOF rgfInOut = SFGAO_FOLDER | SFGAO_FILESYSTEM; hr = psf->GetAttributesOf(1, &pidlChild, &rgfInOut); if (SUCCEEDED(hr)) { if ((~rgfInOut & SFGAO_FOLDER) && (rgfInOut & SFGAO_FILESYSTEM)) { bRet = TRUE; } } psf->Release(); } return bRet; } void __fastcall TOpenDialog::GetFileNames(tagOFNW &OpenFileName) { static TStringList *lst = new TStringList; FORMATETC fmte; STGMEDIUM stgmedium; LPITEMIDLIST pidlFull = NULL; IShellView * pIShellView = NULL; LPMALLOC pMalloc = NULL; IDataObject* pIDataObject = NULL; IShellBrowser* pSB = (IShellBrowser*)SendMessage(GetParent(Handle), WM_GETISHELLBROWSER, 0, 0); TCHAR szPath[_MAX_PATH]; if (pSB == NULL) //GetFileNames被调用两次,第二次pSB为空, 返回第一次结果 { if (lst) { FFileName = OpenFileName.lpstrFile;
FFiles->Assign(lst); delete lst; lst = NULL; } return; } if (lst == NULL) lst = new TStringList; ZeroMemory((LPVOID) & fmte, sizeof(STGMEDIUM)); ZeroMemory((LPVOID) & fmte, sizeof(FORMATETC)); fmte.tymed = TYMED_HGLOBAL; fmte.lindex = -1; fmte.dwAspect = DVASPECT_CONTENT; fmte.cfFormat = RegisterClipboardFormat(CFSTR_SHELLIDLIST); do { HRESULT hr = pSB->QueryActiveShellView(&pIShellView); if (FAILED(hr)) break; hr = ::SHGetMalloc(&pMalloc); if (FAILED(hr)) break; hr = pIShellView->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (LPVOID*) & pIDataObject); if (FAILED(hr)) break; if (pIDataObject == NULL) break; hr = pIDataObject->GetData(&fmte, &stgmedium); if (FAILED(hr)) break; LPIDA pida = (LPIDA)GlobalLock(stgmedium.hGlobal); if (pida) { LPCITEMIDLIST pidlFolder = GetPIDLFolder(pida); for (UINT i = 0; i < pida->cidl; i++) { LPCITEMIDLIST pidl = GetPIDLItem(pida, i); pidlFull = ILCombine(pidlFolder, pidl); if (ILIsFile(pidlFull)) { ZeroMemory(szPath, sizeof(TCHAR) * _MAX_PATH); hr = SHGetPathFromIDList(pidlFull, szPath); if (SUCCEEDED(hr)) { lst->Add((szPath)); } } pMalloc->Free(pidlFull); pidlFull = NULL; } } GlobalUnlock(stgmedium.hGlobal); ReleaseStgMedium(&stgmedium); } while (FALSE); if (pIDataObject) pIDataObject->Release(); if (pIShellView) pIShellView->Release(); if (pMalloc) { if (pidlFull) pMalloc->Free(pidlFull); pMalloc->Release(); } }
加入代码后,不管TOpenDialog还是TOpenPictureDialog,打开文件数量都不再受限制(当然受内存限制,也不是无限的)。
在此BS一下微软的程序员。
相关文章推荐
- weblogic服务上传word等文件直接打开问题解决
- 解决PHP文件(word/excel)下载 内容打开乱码问题
- VC6无法打开文件问题解决,与office2007冲突
- 无法打开文件"LIBC.lib"问题解决
- 解决linux打开文件数1024限制的解决办法
- 解决问题——LINK : fatal error LNK1104: 无法打开文件“GuiTk115d.lib”
- 解决ubuntu下打开pdf文件乱码问题
- 【常见问题】Chm文件能打开,但看不见内容,已解决
- Java IO流将数据输出到.csv文件中,excel打开时乱码问题的解决
- 解决linux 下打开windows的txt文件乱码问题
- 解决fatal error C1083: 无法打开包括文件:“opencv2/core/cvdef.h”: No such file or directory问题
- 解决Excel 2016无法直接打开文件的问题
- 遇到问题----linux-----linux 打开文件数 too many open files 解决方法
- win7打开chm文件问题解决之道
- 解决ewebeditor的上传组件与IIS大小限制导致无法上传大于200K文件的问题
- 解决vs2010“创建或打开C++浏览数据库文件 发生错误”的问题" .
- Linux ulimit解决最大打开文件数限制
- 解决VS2005打开js,css,asp.php等文件,中文都是乱码的问题
- 【转】利用ftpclient下载文件,解决用window.open打开ftp地址中有中文,不能下载的问题
- 解决linux用记事本打开文件乱码问题