提取文件的所有图标

Extract all icons of a file

首先,我想访问“.exe”文件中的所有图标(16x16...256x256 和更大)。

作为我研究的结果,我发现了这样的代码:

#ifndef __ICON_LIST_H__
#define __ICON_LIST_H__

#include <windows.h>
#include <vector>

class IconFile: public std::vector<HICON>{
public:

  IconFile(){};

  IconFile(std::string i_filename){
    addIconsFromFile(i_filename);
  };

  int addIconsFromFile(std::string i_fileName){
    int iCount=0;
    HANDLE file = CreateFile( i_fileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, 
OPEN_EXISTING, 0, NULL);
    if(file!=INVALID_HANDLE_VALUE){
      int   size   = GetFileSize(file,NULL);
      DWORD actRead;
      BYTE* buffer = new BYTE[size];
      ReadFile(file, buffer, size, &actRead, NULL);
      CloseHandle(file);
      int ind = -1;
      for(int p = 0; p< size-4; ++p){
        if(buffer[p]==40 && buffer[p+1]==0 && buffer[p+2]==0 && buffer[p+3]==0){
          HICON icon = CreateIconFromResourceEx(&buffer[p], size-p, true, 0x00030000,0,0,0);
          if(icon){
            ++iCount;
            this->push_back(icon);
          }
        }
      }     
      delete[] buffer;
    }
    return iCount;
  };
};
#endif //__ICON_LIST_H__

此代码工作正常但不显示 256x256 或更大的图标,代码输出:

std::vector(0x8ef2013, 0x64ce1867, 0x24681219)

目前,这是文件的图标列表:

如何获得 256x256 图标?

使用LoadLibraryEx加载文件,EnumResourceNames枚举图标,CreateIconFromResourceEx引导每个图标。

请注意,不建议从 std::vector 和其他 C++ 标准库容器驱动 class。

下面的示例使用 LR_SHARED,您可能需要更改它。

#include <windows.h>
#include <vector>

BOOL CALLBACK EnumIcons(HMODULE hmodule, LPCTSTR type, LPTSTR lpszName, 
    LONG_PTR ptr)
{
    if (!ptr)
        return FALSE;
    auto pvec = (std::vector<HICON>*)ptr;
    auto hRes = FindResource(hmodule, lpszName, type);
    if (!hRes)
        return TRUE;
    auto size = SizeofResource(hmodule, hRes);
    auto hg = LoadResource(hmodule, hRes);
    if (!hg)
        return TRUE;
    auto bytes = (BYTE*)LockResource(hg);
    auto hicon = CreateIconFromResourceEx(bytes, size, TRUE, 0x00030000, 
        0, 0, LR_SHARED);
    if (hicon)
        pvec->push_back(hicon);
    return TRUE;
}

int main()
{
    std::vector<HICON> vec;
    const char* modulepath = "file.exe";
    HMODULE hmodule = LoadLibraryEx(modulepath, NULL,
        LOAD_LIBRARY_AS_IMAGE_RESOURCE);
    if (!hmodule)
        return 0;

    EnumResourceNames(hmodule, RT_ICON,(ENUMRESNAMEPROC)EnumIcons,(LONG_PTR)&vec);
    for (auto e : vec)
    {
        ICONINFOEX ii = { sizeof(ii) };
        if (!GetIconInfoEx(e, &ii) || !ii.hbmColor)
            continue;
        BITMAP bm;
        GetObject(ii.hbmColor, sizeof(bm), &bm);
        printf("%d %d %d\n", bm.bmWidth, bm.bmHeight, bm.bmBitsPixel);
    }

    //free icons...
    return 0;
}