讀者回報:《線上雜誌》第 26 期「再談 CFileDialog 對話框的定制」範例存在 Bug:多選檔案過多時,後選檔案無效、點擊「確定」無反應。本文深入分析根因並提供解決方案。
標準多選 CFileDialog 使用方式:
CFileDialog mFileDlg(TRUE, NULL, NULL,
OFN_ALLOWMULTISELECT,
_T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||"),
AfxGetMainWnd());
CString pathName;
if (mFileDlg.DoModal() == IDOK) {
POSITION mPos = mFileDlg.GetStartPosition();
while (mPos != NULL) {
pathName = mFileDlg.GetNextPathName(mPos);
TRACE("%s\n", pathName);
}
}
加入追蹤 mFileDlg.m_ofn.nMaxFile 發現預設值為 260(字元數)。

nMaxFile 指定 lpstrFile 緩衝區大小(以 TCHAR 為單位)。多選時所有檔案完整路徑串聯存放於此緩衝區,若超過大小,GetOpenFileName 回傳 FALSE,導致後選檔案遺失、對話框無反應。緩衝區至少需 256 字元。
#define NAMEBUF 1024 // 依需求調整,如 4096、8192
// 建立 CFileDialog 實例後、呼叫 DoModal 前:
mFileDlg.m_ofn.lpstrFile = new TCHAR[NAMEBUF];
memset(mFileDlg.m_ofn.lpstrFile, 0, NAMEBUF);
mFileDlg.m_ofn.nMaxFile = NAMEBUF;
// 使用完畢後釋放:
delete[] mFileDlg.m_ofn.lpstrFile;
CFileDialog mFileDlg(TRUE, NULL, NULL,
OFN_ALLOWMULTISELECT,
_T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||"),
AfxGetMainWnd());
// 擴大緩衝區
#define NAMEBUF 4096
mFileDlg.m_ofn.lpstrFile = new TCHAR[NAMEBUF];
memset(mFileDlg.m_ofn.lpstrFile, 0, NAMEBUF);
mFileDlg.m_ofn.nMaxFile = NAMEBUF;
if (mFileDlg.DoModal() == IDOK) {
POSITION mPos = mFileDlg.GetStartPosition();
while (mPos != NULL) {
CString pathName = mFileDlg.GetNextPathName(mPos);
TRACE("%s\n", pathName);
}
}
delete[] mFileDlg.m_ofn.lpstrFile; // 記得釋放
多選檔案路徑總長度超過預設 260 字元緩衝區是導致失效的根本原因。依專案實際需求適當擴大 nMaxFile 並重新配置 lpstrFile 緩衝區即可徹底解決。