我可以提取一个文件的图标,并使用下面的脚本保存它,但脚本将图标保存为灰色(似乎是4位颜色深度)。
如何在保存图标的同时保留其原始颜色深度?
using namespace std;
#include <iostream>
#include <string>
#include <fstream>
#include <windows.h>
#include "commctrl.h"
#pragma comment(lib, "comctl32.lib")
#include <olectl.h>
#pragma comment(lib, "oleaut32.lib")
HRESULT SaveIcon(HICON hIcon, PCTSTR path) {
// Create the IPicture intrface
PICTDESC desc = { sizeof(PICTDESC) };
desc.picType = PICTYPE_ICON;
desc.icon.hicon = hIcon;
IPicture* pPicture = 0;
HRESULT hr = OleCreatePictureIndirect(&desc, IID_IPicture, FALSE, (void**)& pPicture);
if (FAILED(hr)) return hr;
// Create a stream and save the image
IStream* pStream = 0;
CreateStreamOnHGlobal(0, TRUE, &pStream);
LONG cbSize = 0;
hr = pPicture->SaveAsFile(pStream, TRUE, &cbSize);
// Write the stream content to the file
if (!FAILED(hr)) {
HGLOBAL hBuf = 0;
GetHGlobalFromStream(pStream, &hBuf);
void* buffer = GlobalLock(hBuf);
HANDLE hFile = CreateFile(path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (!hFile) hr = HRESULT_FROM_WIN32(GetLastError());
else {
DWORD written = 0;
WriteFile(hFile, buffer, cbSize, &written, 0);
CloseHandle(hFile);
}
GlobalUnlock(buffer);
}
// Cleanup
pStream->Release();
pPicture->Release();
return hr;
}
HICON GetIcon(PCTSTR pszFile)
{
SHFILEINFO sfi;
HIMAGELIST himl = reinterpret_cast<HIMAGELIST>(
SHGetFileInfo(pszFile, 0, &sfi, sizeof(sfi),
SHGFI_SYSICONINDEX));
if (himl) {
return ImageList_GetIcon(himl, sfi.iIcon, ILD_NORMAL);
}
else {
return NULL;
}
}
int main()
{
string fileBaseName = "appName";
wstring fileBaseNameWSTRING(fileBaseName.begin(), fileBaseName.end());
HICON hIcon = GetIcon((fileBaseNameWSTRING + L".lnk").c_str());
if (hIcon == NULL) {
cout << "GetIcon failed" << endl;
return 1;
}
else {
HRESULT hr = SaveIcon(hIcon, (L"temp\\" + fileBaseNameWSTRING + L".ico").c_str());
return hr;
}
}
SaveIcon函数取自此页面:How can I save HICON to an .ico file?
发布于 2019-08-30 18:02:07
通常,图标包含多个原始位深度,也包含多个分辨率。返回HICON的API不会这样做,它们会从图标中选择一个图像。
如果你想要完整的文件,把SHGFI_SYSICONINDEX
改成SHGFI_ICONLOCATION
,你会得到一个带有图标+图标索引的DLL的路径。
加载DLL,最好使用LoadLibraryEx
API和LOAD_LIBRARY_AS_DATAFILE
选项。
然后调用资源API FindResource
/ LoadResource
/ SizeofResource
/ LockResource
,获取图标的源数据。
https://stackoverflow.com/questions/57723702
复制相似问题