最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

CFileDialog的鉤子函數(shù)解決對話框的多選之DoModal問題

 更新時(shí)間:2012年12月07日 14:14:36   作者:  
前幾天領(lǐng)導(dǎo)問我一個(gè)問題:就是使用CFileDialog類在設(shè)置多選時(shí)選中的文件所放的文件緩沖區(qū)不知設(shè)置多大合適,本文將詳細(xì)介紹,需要的朋友可以參考下

前幾天領(lǐng)導(dǎo)問我一個(gè)問題:就是使用CFileDialog類在設(shè)置多選時(shí)選中的文件所放的文件緩沖區(qū)不知設(shè)置多大合適,設(shè)置小了DoModal返回為失敗, 通過CommDlgExtendedError函數(shù)獲取錯(cuò)誤碼為FNERR_BUFFERTOOSMALL(即緩沖區(qū)太小),設(shè)置大了又浪費(fèi)內(nèi)存。(我們 一次要選幾百個(gè)文件,實(shí)在不知設(shè)置多大合適)。

      我談了我的思路:CFileDialog的數(shù)據(jù)成員m_ofn有一個(gè)數(shù)據(jù)成員為鉤子函數(shù)指針,通過設(shè)置這個(gè)函數(shù),可以勾取CFileDialog的相關(guān)消 息,比如用戶改變路徑的消息,然后獲取當(dāng)前路徑的文件個(gè)數(shù),以此為依據(jù)來設(shè)置緩沖區(qū)的大小。領(lǐng)導(dǎo)不是很明白我的思路,他上網(wǎng)搜了搜,找到一種方法,就是通過派生CFileDialog類的方法來做,具體如下:

     Multiple Selection in a File Dialog

    上面的鏈接提到的方法確實(shí)可行。但是我也相信我的方法是可行的。下班后我上網(wǎng)搜索了一下,發(fā)現(xiàn)微軟官網(wǎng)上有一個(gè)對此問題的解決辦法,鏈接如下:

如何處理在 Windows 中 FNERR_BUFFERTOOSMALL 

     該鏈接提供的代碼適合的是Win 32的程序,并不適合MFC的程序,而且我建了一個(gè)Win32的程序測試該例子的代碼時(shí),發(fā)現(xiàn)一個(gè)問題,就是當(dāng)選擇的文件過多時(shí),就是需要分配的緩沖區(qū)比較多時(shí),使用鏈接中的HeapAlloc函數(shù)會(huì)出現(xiàn)錯(cuò)誤,錯(cuò)誤提示如下:

 

     因此要將鏈接中分配內(nèi)存和釋放的內(nèi)存的HeapAlloc和HeapFree函數(shù)分別用C++的new和delete操作符替換。

      在微軟官網(wǎng)提供的做法的基礎(chǔ)上我摸索出用在MFC程序的做法,具體代碼如下:

復(fù)制代碼 代碼如下:

// 鉤子函數(shù)
UINT_PTR CALLBACK MyOFNHookProc( HWND hdlg, // handle to child dialog box
UINT uiMsg, // message identifier
WPARAM wParam, // message parameter
LPARAM lParam // message parameter
)
{
int nResult = FALSE;
if (hdlg == NULL)
return 0;
#ifdef _DEBUG
// from "_AfxCommDlgProc()" of the file "dlgcomm.cpp"
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
if (pThreadState->m_pAlternateWndInit != NULL)
pThreadState->m_pAlternateWndInit = NULL;
#endif
switch(uiMsg)
{
case WM_NOTIFY:
{
LPOFNOTIFY pOfn = (LPOFNOTIFY)lParam;
switch(pOfn->hdr.code)
{
case CDN_SELCHANGE:
{
TCHAR dummy_buffer;
// Get the required size for the 'files' buffer
HWND hOwner = GetParent(hdlg);
HWND hParent = GetParent(hOwner);
UINT nfiles = CommDlg_OpenSave_GetSpec(hOwner, &dummy_buffer, 1);
// Get the required size for the 'folder' buffer
int cbLength = CommDlg_OpenSave_GetSpec(GetParent(hdlg), NULL, 0);
cbLength += _MAX_PATH;
if(cbLength>(pOfn->lpOFN)->nMaxFile)
{
delete (pOfn->lpOFN)->lpstrFile;
(pOfn->lpOFN)->lpstrFile = new TCHAR[cbLength];
ZeroMemory((pOfn->lpOFN)->lpstrFile,cbLength);
(pOfn->lpOFN)->nMaxFile = cbLength;
}
nResult = TRUE;
break;
}
default:
break;
}
break;
}
default:
break;
}
return nResult;
}
#define NAMEBUF 1024
// 調(diào)用函數(shù)
void CMultiSelectDlg::OnButton1()
{
m_listbox.ResetContent();
m_static.SetWindowText(_T("0 files selected"));
TCHAR szFilters[]= _T("MyType Files (*.doc)|*.doc||");
// Create an Open dialog; the default file name extension is ".doc".
CFileDialog fileDlg(TRUE, _T("doc"), _T("*.doc"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT, szFilters);
fileDlg.m_ofn.lpstrFile=new TCHAR[NAMEBUF]; // 重新定義lpstrFile 緩沖大小
memset(fileDlg.m_ofn.lpstrFile,0,NAMEBUF); // 初始化定義的緩沖
fileDlg.m_ofn.nMaxFile = NAMEBUF; // 重定義nMaxFile
fileDlg.m_ofn.lpfnHook = (LPOFNHOOKPROC)MyOFNHookProc;
INT_PTR ret = fileDlg.DoModal();
if (ret == IDOK)
{
int width = 0;
CString str;
CDC *pDC = m_listbox.GetDC();
int saved = pDC->SaveDC();
pDC->SelectObject(GetFont());
UINT count = 0;
POSITION pos = fileDlg.GetStartPosition();
while (pos)
{
str = fileDlg.GetNextPathName(pos);
m_listbox.AddString(str);
CSize size(0, 0);
size = pDC->GetTextExtent(str);
width = width > size.cx ? width : size.cx;
++count;
}
pDC->RestoreDC(saved);
ReleaseDC(pDC);
m_listbox.SetHorizontalExtent(width + 5);
str.Format(_T("%u files selected"), count);
m_static.SetWindowText(str);
}
DWORD dwCode = CommDlgExtendedError();
if (FNERR_BUFFERTOOSMALL==dwCode)
{
AfxMessageBox(_T("獲取文件路徑失敗!"));
}
delete []fileDlg.m_ofn.lpstrFile;
fileDlg.m_ofn.lpstrFile = NULL;
}

    另外使用鉤子函數(shù)的一個(gè)嚴(yán)重缺點(diǎn)是程序必須使用Unicode字符集進(jìn)行編譯,使用多字節(jié)字符集編譯程序執(zhí)行后FNERR_BUFFERTOOSMALL的錯(cuò)誤(這一點(diǎn)已經(jīng)測試過,我比較難以理解的是為何在這一點(diǎn)上微軟不予支持多字節(jié)程序)。我的測試環(huán)境為: VS C++ 2005 + sp1,Win XP + sp3,unicode字符集。

相關(guān)文章

  • C語言開發(fā)實(shí)現(xiàn)貪吃蛇小游戲

    C語言開發(fā)實(shí)現(xiàn)貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了C語言開發(fā)實(shí)現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • Qt自定義美化滑動(dòng)條

    Qt自定義美化滑動(dòng)條

    這篇文章主要為大家詳細(xì)介紹了Qt自定義美化滑動(dòng)條的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11
  • 位運(yùn)算實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)換為二進(jìn)制

    位運(yùn)算實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)換為二進(jìn)制

    這篇文章主要介紹了位運(yùn)算實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)換為二進(jìn)制的相關(guān)資料,需要的朋友可以參考下
    2015-03-03
  • C++?plog日志使用方法介紹

    C++?plog日志使用方法介紹

    最近突然心血來潮,想學(xué)一下日志方面的操作。在網(wǎng)上找了很多日志相關(guān)的技術(shù),最終還是決定使用plog,小巧,快速,跨平臺(tái)
    2022-10-10
  • C++算法實(shí)現(xiàn)leetcode 1252奇數(shù)值單元格數(shù)目

    C++算法實(shí)現(xiàn)leetcode 1252奇數(shù)值單元格數(shù)目

    這篇文章為大家主要介紹了C++實(shí)現(xiàn)leetcode 1252奇數(shù)值單元格的數(shù)目題解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • c++類的隱式轉(zhuǎn)換與強(qiáng)制轉(zhuǎn)換重載詳解

    c++類的隱式轉(zhuǎn)換與強(qiáng)制轉(zhuǎn)換重載詳解

    轉(zhuǎn)換函數(shù)的名稱是類型轉(zhuǎn)換的目標(biāo)類型,因此,不必再為它指定返回值類型;轉(zhuǎn)換函數(shù)是被用于本類型的數(shù)值或變量轉(zhuǎn)換為其他的類型,也不必帶參數(shù)
    2013-09-09
  • C++內(nèi)存泄漏及檢測工具詳解

    C++內(nèi)存泄漏及檢測工具詳解

    最簡單的方法當(dāng)然是借助于專業(yè)的檢測工具,比較有名如BoundsCheck,功能非常強(qiáng)大,相信做C++開發(fā)的人都離不開它。此外就是不使用任何工具,而是自己來實(shí)現(xiàn)對內(nèi)存泄露的監(jiān)控
    2013-10-10
  • C++面試題之結(jié)構(gòu)體內(nèi)存對齊計(jì)算問題總結(jié)大全

    C++面試題之結(jié)構(gòu)體內(nèi)存對齊計(jì)算問題總結(jié)大全

    這篇文章主要給大家總結(jié)了關(guān)于C++面試題中結(jié)構(gòu)體內(nèi)存對齊計(jì)算問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),通過這些介紹的內(nèi)容對大家在面試C++工作的時(shí)候,會(huì)有一定的參考幫助,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • C語言中對字母進(jìn)行大小寫轉(zhuǎn)換的簡單方法

    C語言中對字母進(jìn)行大小寫轉(zhuǎn)換的簡單方法

    這篇文章主要介紹了C語言中對字母進(jìn)行大小寫轉(zhuǎn)換的簡單方法,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-08-08
  • C++實(shí)現(xiàn)下載的代碼

    C++實(shí)現(xiàn)下載的代碼

    這篇文章主要介紹了C++實(shí)現(xiàn)下載的代碼,以下載百度圖片為例較為完整的講述了C++下載的具體實(shí)現(xiàn)方法,需要的朋友可以參考下
    2014-10-10

最新評(píng)論

怀远县| 阿鲁科尔沁旗| 盘山县| 滁州市| 新兴县| 海城市| 高平市| 新巴尔虎右旗| 临夏县| 磴口县| 涿鹿县| 玛多县| 嘉祥县| 宁德市| 中山市| 海原县| 册亨县| 湖北省| 伊宁市| 古交市| 龙南县| 三河市| 鸡东县| 白山市| 凤翔县| 新建县| 横山县| 永清县| 松原市| 二连浩特市| 彩票| 昭通市| 外汇| 宁海县| 郎溪县| 南雄市| 碌曲县| 遵化市| 仪陇县| 通江县| 上虞市|