当使用GetSaveFileName(Win32 API)弹出保存文件对话框时,进程会一直占用着这个文件夹,导致在文件夹被选择后不能被删除或重命名。

解决方案:给OPENFILENAME的Flags加上OFN_NOCHANGEDIR。例如:

1
2
3
4
5
6
7
8
9
10
OPENFILENAME ofn;
TCHAR szFileName[MAX_PATH] = { 0 };
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = _T("所有文件 (*.*)\0*.*\0\0");
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
::GetSaveFileName(&ofn);

OFN_NOCHANGEDIR的意思是 如果用户在搜索文件时更改目录,请将当前目录恢复为其原始值。

如果不加这个Flag,选择文件夹后,会改变当前程序的工作目录,导致文件夹被占用。

Qt中怎么玩的?

之前使用Qt的时候(使用Native Dialog)好像从来没有遇到过这个问题,出于好奇心的驱使,看了下最新Qt6.2.2中这部分的源码(Src/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp)。

1
2
3
4
5
6
7
8
9
// Flags.
ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST);
if (m_options->fileMode() == QFileDialogOptions::ExistingFile
|| m_options->fileMode() == QFileDialogOptions::ExistingFiles)
ofn->Flags |= (OFN_FILEMUSTEXIST);
if (m_options->fileMode() == QFileDialogOptions::ExistingFiles)
ofn->Flags |= (OFN_ALLOWMULTISELECT);
if (!(m_options->options() & QFileDialogOptions::DontConfirmOverwrite))
ofn->Flags |= OFN_OVERWRITEPROMPT;

果然,默认也加了OFN_NOCHANGEDIR。

Reference