tags:

views:

87

answers:

1

Can anyone show a short and simple code snippet? It should take the name of an .exe as the input and output a .ico file. The shorter the better, and please don't recommend any binaries. This seems like such a simple task yet the only code I've found appears extremely bloated. Thanks!

+4  A: 

Though it sounds simple, like most stuff in Win32 in practice it's not trivial. In particular this whole chunk of the codebase feels really, really old...and it's a royal pain to manipulate it. Aggravating this is the fact that there are multiple icon sizes per file, as well as multiple icons per size per file.

Here's some old code which does a lot of what you need (but not all). This should get you well on your way by cracking EXEs and getting you at the icons themselves:

Some setup:

static const int _MAX_ICONS = 2;

typedef struct INTERNAL_ICON_INFO
{
    HICON hIcon;
    int nSize;
}  INTERNAL_ICON_INFO;


typedef struct TAG_ICON_BUNDLE_DETAILS
{
    int nLargeIcons;
    INTERNAL_ICON_INFO aiiLargeIcons[_MAX_ICONS];

    int nSmallIcons;
    INTERNAL_ICON_INFO aiiSmallIcons[_MAX_ICONS];
} ICON_BUNDLE_DETAILS;

The icon extraction code:

HINSTANCE hTargetModule  = LoadLibrary((LPCTSTR)stTargetFile); 
if (NULL != hTargetModule)
{
 int nIconCount = ExtractIconEx((LPCTSTR)stTargetFile, -1, NULL, NULL, 0); // get total icon count
 ICON_BUNDLE_DETAILS* priiArray = new ICON_BUNDLE_DETAILS[nIconCount];

 int nExtracted = 0; 
 for (int i = 0; i < nIconCount; i++)
 {
  HICON* phiLargeIcons = new HICON[nIconCount];
  HICON* phiSmallIcons = new HICON[nIconCount];

  nExtracted = ExtractIconEx((LPCTSTR)stTargetFile, i, phiLargeIcons, phiSmallIcons, _MAX_ICONS);

  for (int j = 0; j < nExtracted; j++)
  {
   ICONINFO ii;
   GetIconInfo(phiLargeIcons[j], &ii);

   priiArray[i].nLargeIcons = nExtracted;
   priiArray[i].aiiLargeIcons[j].hIcon = phiLargeIcons[j];
   priiArray[i].aiiLargeIcons[j].nSize = sizeof(ICONINFO);
  }

  for (j = 0; j < nExtracted; j++)
  {
   priiArray[i].nSmallIcons = nExtracted;
   priiArray[i].aiiSmallIcons[j].hIcon = phiSmallIcons[j];
   priiArray[i].aiiSmallIcons[j].nSize = sizeof(ICONINFO);
  }
 }

 if (nExtracted > 0)
 {
  // process extracted icons
 }
}

In short, this code opens up a target file, counts how many icons are therein, then grabs info regarding each instance of each ICONINFO. That's the struct I think you care about, as it contains the bitmaps themselves.

Going from ICONINFO to new .ico file was not what we needed to do, so I can't help with that part...but how hard could it be? ;-)

Good luck!

DarkSquid
...and in case anybody wonders: Yes, of course I feel the embarrassment that comes with looking at code written 10 years ago! Hopefully it's still useful, even if it is all lpsz'd up ;-)
DarkSquid
+1 Didn't know it -had- to be complicated (compared to a couple lines of code). This is a great start for me, thanks!
Lin