我们如何在 CFileDialog 和多文件选择中使用智能指针?
How do we use smart pointers with CFileDialog and multi-file selection?
如何使我们使用通用 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
.
只要您需要一个自动管理的堆分配数组,std::vector
就是首选解决方案。所有 new[]
和 delete[]
都会奇迹般地消失,OPENFILENAME
结构中设置的参数将匹配,作为奖励。
像这样:
void CExportSettingsDlg::OnBnClickedMfcbuttonImportXsl()
{
// ...
// The controlled sequence is default-initialized (i.e. zeroed out)
auto pszFile = std::vector<TCHAR>(32767);
// ...
// Initialise the file dialog
CFileDialog dlgImport(TRUE,
_T(".XSL"), _T(""), OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, strFilter, this);
dlgImport.m_ofn.lpstrFile = pszFile.data();
// Without the cast this would raise a signed/unsigned mismatch warning
// depending on the target architecture
dlgImport.m_ofn.nMaxFile = static_cast<uint32_t>(pszFile.size());
dlgImport.m_ofn.nFileOffset = 0;
if (dlgImport.DoModal() != IDOK)
{
// User did not select any files so simply return
// Memory is cleaned up by vector's d'tor
return;
}
// ...
// No need to clean up
}
如何使我们使用通用 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
.
只要您需要一个自动管理的堆分配数组,std::vector
就是首选解决方案。所有 new[]
和 delete[]
都会奇迹般地消失,OPENFILENAME
结构中设置的参数将匹配,作为奖励。
像这样:
void CExportSettingsDlg::OnBnClickedMfcbuttonImportXsl()
{
// ...
// The controlled sequence is default-initialized (i.e. zeroed out)
auto pszFile = std::vector<TCHAR>(32767);
// ...
// Initialise the file dialog
CFileDialog dlgImport(TRUE,
_T(".XSL"), _T(""), OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, strFilter, this);
dlgImport.m_ofn.lpstrFile = pszFile.data();
// Without the cast this would raise a signed/unsigned mismatch warning
// depending on the target architecture
dlgImport.m_ofn.nMaxFile = static_cast<uint32_t>(pszFile.size());
dlgImport.m_ofn.nFileOffset = 0;
if (dlgImport.DoModal() != IDOK)
{
// User did not select any files so simply return
// Memory is cleaned up by vector's d'tor
return;
}
// ...
// No need to clean up
}