SHBrowseForFolder 函数在执行过程中会动态分配内存来存储与所选文件夹相关的信息,这些信息以 ITEMIDLIST 结构的形式返回。而 SHGetPathFromIDList 函数只是负责从这个 ITEMIDLIST 结构中提取出路径信息并填充到指定的缓冲区中,但它并不会释放 ITEMIDLIST 所占用的内存。为了避免内存泄漏,就需要调用 CoTaskMemFree 函数来显式地释放这块由 SHBrowseForFolder 分配的内存,因为这块内存是通过 COM 任务分配器(CoTaskMemAlloc)分配的,所以需要使用与之对应的 CoTaskMemFree 函数来释放。
出处:https://learn.microsoft.com/zh-cn/windows/win32/api/shlobj_core/nf-shlobj_core-shbrowseforfoldera
调用应用程序负责调用 CoTaskMemFree ,以在不再需要时释放 SHBrowseForFolder 返回的 IDList。
一定要释放PCIDLIST_ABSOLUTE。否则内存泄漏。
#include "stdafx.h"
#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
#include <tchar.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
std::wcout.imbue(std::locale("chs"));
TCHAR szPath[MAX_PATH];
BROWSEINFO bi = { 0 };
bi.lpszTitle = _T("请选择一个文件夹");
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
if (pidl != 0)
{
if (SHGetPathFromIDList(pidl, szPath))
{
std::wcout << _T("你选择的文件夹是: ") << szPath << std::endl;
}
else
{
std::cerr << _T("无法获取文件夹路径。") << std::endl;
}
// 释放内存
CoTaskMemFree(pidl);
std::wcout << _T("你选择的文件夹是: ") << szPath << std::endl;
}
else
{
std::cerr << _T("未选择文件夹。") << std::endl;
}
return 0;
}