We don't display ads so we rely on your Bitcoin donations to 1KWEk9QaiJb2NwP5YFmR24LyUBa4JyuKqZ
Post date: Mar 16, 2010 3:02:54 PM
ICO file format is an image file format for icons in Microsoft Windows. .ICO files contain one or more small images at multiple sizes and color depths. This function shows you how to extract the entire .ico file from an executable.
Read more: http://en.wikipedia.org/wiki/ICO_%28file_format%29
{
Coder: Xash
Compiled: Delphi 10 Lite
}
Function PickIconDlgW(OwnerWnd: HWND; lpstrFile: PWideChar; var nMaxFile: LongInt; var lpdwIconIndex: LongInt): LongBool; stdcall; external 'SHELL32.DLL' index 62;implementation{ [WriteIcon] } procedure WriteIcon(Stream: TStream; Icon: HICON; WriteLength: Boolean = False); const RC3_STOCKICON = 0; RC3_ICON = 1; RC3_CURSOR = 2; type PCursorOrIcon = ^TCursorOrIcon; TCursorOrIcon = packed record Reserved: Word; wType: Word; Count: Word; end; type PIconRec = ^TIconRec; TIconRec = packed record Width: Byte; Height: Byte; Colors: Word; Reserved1: Word; Reserved2: Word; DIBSize: Longint; DIBOffset: Longint; end; procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var BI: TBitmapInfoHeader; Colors: Integer); var DS: TDIBSection; Bytes: Integer; begin DS.dsbmih.biSize := 0; Bytes := GetObject(Bitmap, SizeOf(DS), @DS); if Bytes = 0 then Abort // ERROR else if (Bytes >= (sizeof(DS.dsbm) + sizeof(DS.dsbmih))) and (DS.dsbmih.biSize >= DWORD(sizeof(DS.dsbmih))) then BI := DS.dsbmih else begin FillChar(BI, sizeof(BI), 0); with BI, DS.dsbm do begin biSize := SizeOf(BI); biWidth := bmWidth; biHeight := bmHeight; end; end; case Colors of 2: BI.biBitCount := 1; 3..16: begin BI.biBitCount := 4; BI.biClrUsed := Colors; end; 17..256: begin BI.biBitCount := 8; BI.biClrUsed := Colors; end; else BI.biBitCount := DS.dsbm.bmBitsPixel * DS.dsbm.bmPlanes; end; BI.biPlanes := 1; if BI.biClrImportant > BI.biClrUsed then BI.biClrImportant := BI.biClrUsed; if BI.biSizeImage = 0 then BI.biSizeImage := BytesPerScanLine(BI.biWidth, BI.biBitCount, 32) * Abs(BI.biHeight); end; procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: DWORD; var ImageSize: DWORD; Colors: Integer); var BI: TBitmapInfoHeader; begin InitializeBitmapInfoHeader(Bitmap, BI, Colors); if BI.biBitCount > 8 then begin InfoHeaderSize := SizeOf(TBitmapInfoHeader); if (BI.biCompression and BI_BITFIELDS) <> 0 then Inc(InfoHeaderSize, 12); end else if BI.biClrUsed = 0 then InfoHeaderSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) * (1 shl BI.biBitCount) else InfoHeaderSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) * BI.biClrUsed; ImageSize := BI.biSizeImage; end; function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE; var BitmapInfo; var Bits; Colors: Integer): Boolean; var OldPal: HPALETTE; DC: HDC; begin InitializeBitmapInfoHeader(Bitmap, TBitmapInfoHeader(BitmapInfo), Colors); OldPal := 0; DC := CreateCompatibleDC(0); try if Palette <> 0 then begin OldPal := SelectPalette(DC, Palette, False); RealizePalette(DC); end; Result := GetDIBits(DC, Bitmap, 0, TBitmapInfoHeader(BitmapInfo).biHeight, @Bits, TBitmapInfo(BitmapInfo), DIB_RGB_COLORS) <> 0; finally if OldPal <> 0 then SelectPalette(DC, OldPal, False); DeleteDC(DC); end; end; var IconInfo: TIconInfo; MonoInfoSize, ColorInfoSize: DWORD; MonoBitsSize, ColorBitsSize: DWORD; MonoInfo, MonoBits, ColorInfo, ColorBits: Pointer; CI: TCursorOrIcon; List: TIconRec; Length: Longint; begin FillChar(CI, SizeOf(CI), 0); FillChar(List, SizeOf(List), 0); GetIconInfo(Icon, IconInfo); try InternalGetDIBSizes(IconInfo.hbmMask, MonoInfoSize, MonoBitsSize, 2); InternalGetDIBSizes(IconInfo.hbmColor, ColorInfoSize, ColorBitsSize, 0 {16 -> 0}); MonoInfo := nil; MonoBits := nil; ColorInfo := nil; ColorBits := nil; try MonoInfo := AllocMem(MonoInfoSize); MonoBits := AllocMem(MonoBitsSize); ColorInfo := AllocMem(ColorInfoSize); ColorBits := AllocMem(ColorBitsSize); InternalGetDIB(IconInfo.hbmMask, 0, MonoInfo^, MonoBits^, 2); InternalGetDIB(IconInfo.hbmColor, 0, ColorInfo^, ColorBits^, 0 {16 -> 0}); if WriteLength then begin Length := SizeOf(CI) + SizeOf(List) + ColorInfoSize + ColorBitsSize + MonoBitsSize; Stream.Write(Length, SizeOf(Length)); end; with CI do begin CI.wType := RC3_ICON; CI.Count := 1; end; Stream.Write(CI, SizeOf(CI)); with List, PBitmapInfoHeader(ColorInfo)^ do begin Width := biWidth; Height := biHeight; Colors := biPlanes * biBitCount; DIBSize := ColorInfoSize + ColorBitsSize + MonoBitsSize; DIBOffset := SizeOf(CI) + SizeOf(List); end; Stream.Write(List, SizeOf(List)); with PBitmapInfoHeader(ColorInfo)^ do Inc(biHeight, biHeight); { color height includes mono bits } Stream.Write(ColorInfo^, ColorInfoSize); Stream.Write(ColorBits^, ColorBitsSize); Stream.Write(MonoBits^, MonoBitsSize); finally FreeMem(ColorInfo, ColorInfoSize); FreeMem(ColorBits, ColorBitsSize); FreeMem(MonoInfo, MonoInfoSize); FreeMem(MonoBits, MonoBitsSize); end; finally DeleteObject(IconInfo.hbmColor); DeleteObject(IconInfo.hbmMask); end; end;{ [/WriteIcon] }procedure TForm1.Image1Click(Sender: TObject);var FileName : array[0..MAX_PATH - 1] of WideChar; Size, Index: LongInt; hLargeIcon, hSmallIcon : HIcon; Stream: TFileStream;begin Size := MAX_PATH; StringToWideChar('%SystemRoot%\system32\Shell32.dll', FileName, MAX_PATH); If PickIconDlgW(Self.Handle, FileName, Size, Index) Then If (Index <> -1) Then If ExtractIconExW( FileName, Index, hLargeIcon, hSmallIcon, 1) > 0 Then Begin Stream := TFileStream.Create('icon.ico', fmCreate); try WriteIcon(Stream, hLargeIcon); finally Stream.Free; end; Image1.Picture.LoadFromFile('icon.ico'); DestroyIcon(hLargeIcon); DestroyIcon(hSmallIcon); End;end;