Code: Select all
;
; Changing icon resources in executables (the NT-API way)
;
;
; NOTE: Needs NT, 2000 or XP to work
;
;
;
; WARNING: the following code is known to fail in certain cases
; be sure to backup your data before using this!
;
;
;
; (:t)raumatic - february 2005
;
#RT_GROUP_ICON = #RT_ICON + 11
; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/msdn_icons.asp
Structure ICONDIRENTRYCOMMON
bWidth.b ; Width, in pixels, of the image
bHeight.b ; Height, in pixels, of the image
bColorCount.b ; Number of colors in image (0 if >=8bpp)
bReserved.b ; Reserved ( must be 0)
wPlanes.w ; Color Planes
wBitCount.w ; Bits per pixel
dwBytesInRes.l ; How many bytes in this resource?
EndStructure
;
Structure ICONDIRENTRY
common.ICONDIRENTRYCOMMON
dwImageOffset.l ; Where in the file is this image?
EndStructure
Structure ICONDIR
idReserved.w ; Reserved (must be 0)
idType.w ; Resource Type (1 for icons)
idCount.w ; How many images?
idEntries.ICONDIRENTRY[0] ; An entry for each image (idCount of 'em)
EndStructure
;
Structure GRPICONDIR1ENTRY1
common.ICONDIRENTRYCOMMON
nId.w ; the ID
EndStructure
Structure GRPICONDIR1
idReserved.w ; Reserved (must be 0)
idType.w ; Resource type (1 for icons)
idCount.w ; How many images?
idEntries.GRPICONDIR1ENTRY1[0] ; The entries for each image
EndStructure
;
; Change Icon-Resource in "exeFilename.s" with "iconFileName.s"
;
Procedure.l ChangeIcon(iconFileName.s, exeFileName.s)
*icon.ICONDIR = AllocateMemory(SizeOf(ICONDIR))
If ReadFile(0, iconFileName.s)
ReadData(0, *icon, SizeOf(ICONDIR))
*icon = ReAllocateMemory(*icon, SizeOf(ICONDIR) + (*icon\idCount*2) *SizeOf(ICONDIRENTRY))
For i=0 To *icon\idCount-1
FileSeek(0, 6+SizeOf(ICONDIRENTRY) * i) ; SizeOf(ICONDIR) - SizeOf(ICONDIRENTRY) = 6
ReadData(0, *icon\idEntries[i], SizeOf(ICONDIRENTRY) * (i+1))
Next
;
hInst.l = BeginUpdateResource_(exeFileName, #False)
If hInst = 0
retVal.l = #False
Else
; CHANGE #RT_GROUP_ICON
*iconGroup.GRPICONDIR1 = AllocateMemory(SizeOf(GRPICONDIR1) + 6 + SizeOf(GRPICONDIR1ENTRY1) * *icon\idCount)
For i=0 To *icon\idCount-1
CopyMemory(*icon\idEntries[i]\common, *iconGroup\idEntries[i]\common, SizeOf(ICONDIRENTRYCOMMON))
*iconGroup\idEntries[i]\nId = (i+1)
Next
*iconGroup\idReserved = 0
*iconGroup\idType = 1
*iconGroup\idCount = *icon\idCount
;
; TODO: Error with bColorCount
; Written value is always wrong!? (e.g. 1 instead of 16)
;
retVal = UpdateResource_(hInst, #RT_GROUP_ICON, 1, #LANG_NEUTRAL, *iconGroup, 6+SizeOf(GRPICONDIR1ENTRY1)* *iconGroup\idCount)
FreeMemory(*iconGroup) : *iconGroup = #Null
; CHANGE #RT_ICON
For i = 0 To *icon\idCount-1
; get the desired icon from .ico file
*resData = AllocateMemory(*icon\idEntries[i]\common\dwBytesInRes)
FileSeek(0, *icon\idEntries[i]\dwImageOffset)
ReadData(0, *resData, *icon\idEntries[i]\common\dwBytesInRes)
retVal = UpdateResource_(hInst, #RT_ICON, (i+1), #LANG_NEUTRAL, *resData, *icon\idEntries[i]\common\dwBytesInRes)
Next
retVal = EndUpdateResource_(hInst, #False)
FreeMemory(*resData) : *resData = #Null
EndIf
FreeMemory(*icon) : *icon = #Null
CloseFile(0)
Else
retVal = #False
EndIf
ProcedureReturn retVal
EndProcedure