【发布时间】:2021-12-11 23:57:18
【问题描述】:
如何对使用通用CFileDialog 对话框的代码进行现代化改造?
示例代码:
void CExportSettingsDlg::OnBnClickedMfcbuttonImportXsl()
{
CString strFilter; // This will be used to display the right type of template files
CString strTargetFolder = theApp.GetWorkingPath(); // Default
TCHAR* pszFile = new TCHAR[32767]; // Buffer for the files selected by the user
TCHAR szTabText[_MAX_PATH] = { 0 }; // Buffer for the selected tab text (we use it for the filter description)
// Initialise the filter string
strFilter = _T("Styles|SRRSchedule*.xsl;SRRSchedule*.css||");
// Initialise the file dialog
CFileDialog dlgImport(TRUE,
_T(".XSL"), _T(""), OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, strFilter, this);
ZeroMemory(pszFile, 32767 * sizeof(TCHAR));
dlgImport.m_ofn.lpstrFile = pszFile;
dlgImport.m_ofn.nMaxFile = 32767;
dlgImport.m_ofn.nFileOffset = 0;
if (dlgImport.DoModal() != IDOK)
{
// User did not select any files so tidy up the memory
delete[] pszFile;
return;
}
// Iterate the selected files
POSITION pos = dlgImport.GetStartPosition();
CString strSourceFilePath, strTargetFilePath, strSourceFileName, strSourceFileTitle, strSourceExtension, strFileName;
while (pos)
{
strSourceFilePath = dlgImport.GetNextPathName(pos);
// ...
}
// Tidy memory
delete[] pszFile;
}
我们怎样才能把它变成使用智能指针? lpstrFile 变量的类型为 LPWSTR。
【问题讨论】:
-
在这种情况下,最简单的就是
TCHAR* pszFile = new TCHAR[32767];->TCHAR pszFile[32767] = {0}; -
@Jabberwocky 我不知道它是否适用于这种情况,但有时在使用过多内存时会收到堆栈大小警告(不记得正确的术语)。我会让@Iinspectable 发表评论。
-
是的,拥有大的局部变量(在大多数平台上存储在堆栈中)并不是一个好主意。但是 32767 并没有那么多。
-
@Jabberwocky 当你像你说的那样做时,你仍然会收到指针衰减警告。除非我改变
dlgImport.m_ofn.lpstrFile = &pszFile[0];。然后就OK了。 -
@jab "32767 没那么多" - 这是 UNICODE 构建中的 64KiB。默认堆栈大小为 1MiB,占可用堆栈空间的 6.25%,仅针对此单个数组。这很多。 64 位构建的情况更糟,64 位调用约定加剧了这种情况,其中堆栈需要 16 字节对齐,加上 32 字节的影子空间(对于除叶函数之外的每个函数调用)。这对堆栈有很大的压力,如果可能的话,最好不要增加压力。这里可以。
标签: visual-c++ mfc smart-pointers openfiledialog