C++ 如何提取文件图标并另存为.ico,同时在C++;?

C++ 如何提取文件图标并另存为.ico,同时在C++;?,c++,save,icons,extract,color-depth,C++,Save,Icons,Extract,Color Depth,我能够提取一个文件的图标并使用下面的脚本保存它,但是脚本将图标保存为灰色(似乎是4位颜色深度) 如何保存图标,同时保留其原始颜色深度 using namespace std; #include <iostream> #include <string> #include <fstream> #include <windows.h> #include "commctrl.h" #pragma comment(lib, "comctl32.lib")

我能够提取一个文件的图标并使用下面的脚本保存它,但是脚本将图标保存为灰色(似乎是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;
    }
}
使用名称空间std;
#包括
#包括
#包括
#包括
#包括“commctrl.h”
#pragma注释(lib,“comctl32.lib”)
#包括
#pragma注释(lib,“oleaut32.lib”)
HRESULT保存图标(HICON HICON,PCTSTR路径){
//创建IPacture接口
PICTDESC desc={sizeof(PICTDESC)};
desc.picType=picType_图标;
desc.icon.hicon=hicon;
i结构*p图像=0;
HRESULT hr=OleCreatePictureIndirect(&desc,IID_i结构,FALSE,(void**)和pPicture);
如果(失败(hr))返回hr;
//创建一个流并保存图像
IStream*pStream=0;
CreateStreamOnHGlobal(0、TRUE和pStream);
长cbSize=0;
hr=pPicture->SaveAsFile(pStream、TRUE和cbSize);
//将流内容写入文件
如果(!失败(hr)){
HGLOBAL hBuf=0;
GetHGlobalFromStream(pStream和hBuf);
void*buffer=GlobalLock(hBuf);
HANDLE hFile=CreateFile(路径,泛型写,0,0,创建总是,0,0);
如果(!hFile)hr=HRESULT_FROM_WIN32(GetLastError());
否则{
DWORD WRITED=0;
WriteFile(hFile、buffer、cbSize和writed,0);
闭合手柄(hFile);
}
GlobalUnlock(缓冲区);
}
//清理
pStream->Release();
pPicture->Release();
返回人力资源;
}
HICON GetIcon(PCTSTR pszFile)
{
SHFILEINFO-sfi;
HIMAGELIST himl=重新解释演员阵容(
SHGetFileInfo(pszFile、0和sfi、sizeof(sfi),
shgfiu SYSICONINDEX);
如果(himl){
返回图像列表图标(himl、sfi.iIcon、ILD\U NORMAL);
}
否则{
返回NULL;
}
}
int main()
{
字符串fileBaseName=“appName”;
wstring fileBaseNameWSTRING(fileBaseName.begin(),fileBaseName.end());
HICON HICON=GetIcon((fileBaseNameWSTRING+L.lnk”).c_str();
if(hIcon==NULL){

cout通常,图标包含多个原始位深度,也包含多个分辨率。返回HICON的API不会这样做,它们从图标中拾取单个图像

如果您想要完整的,请将
SHGFI\u SYSICONINDEX
更改为
SHGFI\u ICONLOCATION
,您将获得带有图标+图标索引的DLL路径

加载DLL,最好使用
LoadLibraryEx
API和
Load\u LIBRARY\u AS\u DATAFILE
选项

然后调用资源API,
FindResource
/
LoadResource
/
SizeofResource
/
LockResource
,以获取图标的源数据