【发布时间】:2018-10-28 12:23:29
【问题描述】:
我正在从文件中提取图标并在对话框中显示它们
const LPCWSTR path = L"c:\path\to\file";
const UINT nIconsCheck = ExtractIconEx(path, -1, nullptr, nullptr, 0);
if(nIconsCheck > 0)
{
HICON *iconHandles=new HICON;
const UINT nIcons = ExtractIconEx(path, 0, iconHandles, nullptr, nIconsCheck);
if(nIcons == nIconsCheck && nIcons != unsigned(-1))
{
IconSelect iconSelect(this); //dialog
for(UINT i=0; i<nIcons; i++)
{
qDebug() << i;
iconSelect.addIcon(QtWin::fromHICON(iconHandles[i])); //fromHICON returns QPixmap
DestroyIcon(iconHandles[i]);
}
iconSelect.exec();
}
}
对话框中的图标已正确加载,但有时会意外导致应用程序崩溃。
知道发生了什么吗?
Documentation on ExtractIconEx
编辑:感谢您提供快速而有用的答案。以下是我使用 atm 的完整工作代码:
// In my case I have a QString `filePath`
// `QString::toWCharArray` retrieves a non-0-terminated string,
// so append a 0 to `path`
std::vector<WCHAR> path(unsigned(filePath.length())+1);
filePath.toWCharArray(path.data());
path.at(path.size()-1) = 0;
// Get number of icons in selected file
UINT nIcons = ExtractIconEx(path.data(), -1, nullptr, nullptr, 0);
if(nIcons == 0)
{
// Try to find associated file that contains icon(s)
// If found, `path` is replaced with the new path
WORD index=0;
DestroyIcon(ExtractAssociatedIcon(GetModuleHandle(nullptr), path.data(), &index));
// Get number of icons in associated file
nIcons = ExtractIconEx(path.data(), -1, nullptr, nullptr, 0);
}
if(nIcons > 0)
{
// Get array of HICONs
std::vector<HICON> iconHandles(nIcons);
nIcons = ExtractIconEx(path.data(), 0, iconHandles.data(), nullptr, nIcons);
for(UINT i=0; i<nIcons; i++) // Using iconHandles.size() is possibly safer,
// but AFAIK nIcons always carries the correct value
{
// Use iconHandles[i]
// In Qt you can use QtWin::fromHICON(iconHandles[i]) to generate a QPixmap
DestroyIcon(iconHandles[i]);
}
}
【问题讨论】:
-
您确定
iconHandles的大小足以容纳所有nIconsCheck句柄吗? (我不是 C++ 程序员,也不经常使用 ExtractIconEx,但这似乎是您的代码的问题。) -
HICON *iconHandles=new HICON;为单个 HICON 句柄分配了足够的内存,而不是句柄数组。正如@AndreasRejbrand 指出的那样,您需要分配足够的内存来接收至少nIconsCheck句柄。 -
谢谢,就是这样!更改为
HICON *iconHandles=new HICON[nIcons];(并在循环后添加delete[] iconHandles;) -
我建议用
std::vector<HICON> iconHandles(nIconsCheck); const UINT nIcons = ExtractIconEx(path, 0, iconHandles.data(), nullptr, iconHandles.size());代替手动分配 -
如果它偶尔崩溃,它不是“工作正常”!
标签: c++ arrays winapi icons allocation