Re: HICON to UpdateResource?

From: Crispen, Bob (bob.crispen_at_boeing.com)
Date: 27 February 2003


Subject: Re: HICON to UpdateResource?
Date: Sat, 08 Feb 2003 20:19:51 +0100
From: Lucian Wischik <lu.nn_at_wischik.com> Organization: University of Bologna
Newsgroups: comp.os.ms-windows.programmer.win32

chrisaotto_at_yahoo.com (Chris Otto) wrote:
>I have a valid icon handle (HICON) and would like to replace an icon
>in an executable file. I know how to use Begin / UpdateResource but
>these require that i have a pointer to resource data. How can I
>convert the HICON to the format used by UpdateResource?

Hi. I wrote the following code a while ago. It takes a .ico file, and converts it into a form suitable for going into an application's resource. Note that this involves two resources: one for the icon itself, and one for the "groupicon" resource, which is a list of the different versions of the icon at different resolutions (which in my code is only one). I wrote my code for C++Builder, so you won't be able to use it directly, but maybe it will give you some ideas.

// The following code is from Lischner ch. 16. He says:
// Note that the data format in a file differs from the data
// format in the resource. The ResInfo unit declares the format
// for resource files. The declarations below pertain to
// external .ICO and .CUR files.

#pragma pack(push,1)
typedef struct tagFileGroupItem
{ BYTE bWidth;
  BYTE bHeight;
  BYTE bColorCount;
  BYTE bReserved;
  WORD wPlanes; WORD wBitCount;
  DWORD dwSize; // item size in bytes
  DWORD dwOffset; // start of item in the file } TFileGroupItem;

typedef struct tagFileGroupHeader
{ WORD wReserved;
  WORD wType; // 1 for icons, 2 for cursors   WORD wCount;
  TFileGroupItem Items[1];
} TFileGroupHeader;

typedef struct tagGroupItem
{ BYTE bWidth;
  BYTE bHeight;
  BYTE bColorCount;
  BYTE bReserved;
  WORD wPlanes;
  WORD wBitCount;
  DWORD dwBytesInRes;
  WORD wNameOrdinal;
} TGroupItem;

typedef struct tagGroupHeader
{ WORD wReserved;
  WORD wType; // 1 for icons, 2 for cursors   WORD wCount;
  TGroupItem Items[1];
} TGroupHeader;
#pragma pack(pop)

_di_IOTAResourceEntry __fastcall AddIconFileResource(AnsiString fn, char *name,WORD flags,WORD langid,int DataVersion,int Version,int Characteristics,_di_IOTAProjectResource pr) { if (!FileOrResourceExists(fn)) {dbe("AddIconFileResource. The file "+fn+" doesn't exist.");return NULL;}
  TFileDataStream *fs=new TFileDataStream(fn);   _di_IOTAResourceEntry

res=AddIconStreamResource(fs,name,flags,langid,DataVersion,Version,Character istics,pr);
  delete fs;
  return res;
}

_di_IOTAResourceEntry __fastcall AddIconStreamResource(TMemoryStream *fs,char *name,WORD flags,WORD langid,int DataVersion,int Version,int
Characteristics,_di_IOTAProjectResource pr) { if (pr==NULL) pr=GetProjectResources(NULL);   if (pr==NULL) {dbe("AddIconFileResource. Failed to get project resources.");return NULL;}

  // Lischner: Create an icon or cursor resource by separating the group header
  // and creating a separate resource for each item in the group.  Then create a
  // group entry. Automatically assign a resource identifier for each individual
  // resource, ensuring that the identifiers do not conflict with any identifiers already in use.
  // First determine the highest resource ID currently assigned to a resource of this type
  int MaxId=0;
  for (int i=0; i<pr->GetEntryCount(); i++)   { _di_IOTAResourceEntry re=pr->GetEntry(i);     if (re->GetResourceType()==RT_ICON)
    { int resid=(int)re->GetResourceName();       if (HIWORD(resid)==0 && resid>MaxId) MaxId=resid;     }
  }
  // Assign MaxId+1 as the ID of the first image resource.   MaxId++;
  // Extract each icon/cursor image.
  TFileGroupHeader *FileHdr = (TFileGroupHeader*)fs->Memory;   int ResHdrSize = 3*sizeof(WORD) + FileHdr->wCount*sizeof(TGroupItem);   TGroupHeader *ResHdr=(TGroupHeader*)new char[ResHdrSize];
  ResHdr->wReserved=0;
  ResHdr->wType=FileHdr->wType;
  ResHdr->wCount=FileHdr->wCount;

  for (int i=0; i<FileHdr->wCount; i++)
  {

CopyMemory(&(ResHdr->Items[i]),&(FileHdr->Items[i]),sizeof(TGroupItem));

    ResHdr->Items[i].wNameOrdinal=(WORD)MaxId;     _di_IOTAResourceEntry

re=pr->CreateEntry(RT_ICON,MAKEINTRESOURCE(MaxId),flags,langid,DataVersion,V ersion,Characteristics);

    re->SetDataSize(ResHdr->Items[i].dwBytesInRes);     TResourceDataStream *ds=new TResourceDataStream(re);     fs->Position = FileHdr->Items[i].dwOffset;     ds->CopyFrom(fs, FileHdr->Items[i].dwSize);     delete ds;
    MaxId++;
  }
  // Create the group resource entry.
  _di_IOTAResourceEntry

re=pr->CreateEntry(MAKEINTRESOURCE(RT_GROUP_ICON),name,flags,langid,DataVers ion,Version,Characteristics);
  re->SetDataSize(ResHdrSize);
  TResourceDataStream *ds=new TResourceDataStream(re);   ds->Write(ResHdr,ResHdrSize); delete ds;   delete[] ResHdr;
  return re;
}

--
Lucian


This archive was generated by hypermail pre-2.1.8 : 26 April 2003 EDT