mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-22 21:19:24 +02:00
lcl: fix loading of icons and cursor from the resources:
- fix signature check for TCursorImage in case of ReadData call - split loading of icons and cursor from the resource because of different structures used for them - load TCursorImage from RT_CURSOR instead of RT_ICON git-svn-id: trunk@30006 -
This commit is contained in:
parent
e65ea3f1b8
commit
e334fff57a
@ -33,7 +33,7 @@ interface
|
|||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils, Math, Types, Classes, FPCAdds, LCLversion,
|
SysUtils, Math, Types, Classes, Contnrs, FPCAdds, LCLversion,
|
||||||
FileUtil,
|
FileUtil,
|
||||||
FPImage, FPCanvas,
|
FPImage, FPCanvas,
|
||||||
FPWriteBMP, // bmp support
|
FPWriteBMP, // bmp support
|
||||||
@ -1607,8 +1607,9 @@ type
|
|||||||
function GetRawImagePtr: PRawImage; override;
|
function GetRawImagePtr: PRawImage; override;
|
||||||
function GetRawImageDescriptionPtr: PRawImageDescription; override;
|
function GetRawImageDescriptionPtr: PRawImageDescription; override;
|
||||||
function GetTransparent: Boolean; override;
|
function GetTransparent: Boolean; override;
|
||||||
class function GetTypeID: Word; virtual;
|
|
||||||
class function GetSharedImageClass: TSharedRasterImageClass; override;
|
class function GetSharedImageClass: TSharedRasterImageClass; override;
|
||||||
|
class function GetStreamSignature: Cardinal; virtual;
|
||||||
|
class function GetTypeID: Word; virtual;
|
||||||
procedure HandleNeeded; override;
|
procedure HandleNeeded; override;
|
||||||
function InternalReleaseBitmapHandle: HBITMAP; override;
|
function InternalReleaseBitmapHandle: HBITMAP; override;
|
||||||
function InternalReleaseMaskHandle: HBITMAP; override;
|
function InternalReleaseMaskHandle: HBITMAP; override;
|
||||||
@ -1639,7 +1640,7 @@ type
|
|||||||
function LazarusResourceTypeValid(const ResourceType: string): boolean; override;
|
function LazarusResourceTypeValid(const ResourceType: string): boolean; override;
|
||||||
procedure LoadFromResourceName(Instance: THandle; const ResName: String); override;
|
procedure LoadFromResourceName(Instance: THandle; const ResName: String); override;
|
||||||
procedure LoadFromResourceID(Instance: THandle; ResID: PtrInt); override;
|
procedure LoadFromResourceID(Instance: THandle; ResID: PtrInt); override;
|
||||||
procedure LoadFromResourceHandle(Instance: THandle; ResHandle: TFPResourceHandle);
|
procedure LoadFromResourceHandle(Instance: THandle; ResHandle: TFPResourceHandle); virtual;
|
||||||
function BitmapHandleAllocated: boolean; override;
|
function BitmapHandleAllocated: boolean; override;
|
||||||
function MaskHandleAllocated: boolean; override;
|
function MaskHandleAllocated: boolean; override;
|
||||||
function PaletteAllocated: boolean; override;
|
function PaletteAllocated: boolean; override;
|
||||||
@ -1657,9 +1658,11 @@ type
|
|||||||
function GetIconHandle: HICON;
|
function GetIconHandle: HICON;
|
||||||
procedure SetIconHandle(const AValue: HICON);
|
procedure SetIconHandle(const AValue: HICON);
|
||||||
protected
|
protected
|
||||||
|
class function GetStreamSignature: Cardinal; override;
|
||||||
class function GetTypeID: Word; override;
|
class function GetTypeID: Word; override;
|
||||||
procedure HandleNeeded; override;
|
procedure HandleNeeded; override;
|
||||||
public
|
public
|
||||||
|
procedure LoadFromResourceHandle(Instance: THandle; ResHandle: TFPResourceHandle); override;
|
||||||
function ReleaseHandle: HICON;
|
function ReleaseHandle: HICON;
|
||||||
function GetResourceType: TResourceType; override;
|
function GetResourceType: TResourceType; override;
|
||||||
property Handle: HICON read GetIconHandle write SetIconHandle;
|
property Handle: HICON read GetIconHandle write SetIconHandle;
|
||||||
@ -1736,11 +1739,13 @@ type
|
|||||||
protected
|
protected
|
||||||
procedure HandleNeeded; override;
|
procedure HandleNeeded; override;
|
||||||
class function GetDefaultSize: TSize; override;
|
class function GetDefaultSize: TSize; override;
|
||||||
|
class function GetStreamSignature: Cardinal; override;
|
||||||
class function GetSharedImageClass: TSharedRasterImageClass; override;
|
class function GetSharedImageClass: TSharedRasterImageClass; override;
|
||||||
class function GetTypeID: Word; override;
|
class function GetTypeID: Word; override;
|
||||||
public
|
public
|
||||||
class function GetFileExtensions: string; override;
|
class function GetFileExtensions: string; override;
|
||||||
function GetResourceType: TResourceType; override;
|
function GetResourceType: TResourceType; override;
|
||||||
|
procedure LoadFromResourceHandle(Instance: THandle; ResHandle: TFPResourceHandle); override;
|
||||||
function LazarusResourceTypeValid(const ResourceType: string): boolean; override;
|
function LazarusResourceTypeValid(const ResourceType: string): boolean; override;
|
||||||
function ReleaseHandle: HCURSOR;
|
function ReleaseHandle: HCURSOR;
|
||||||
property HotSpot: TPoint read GetHotSpot;
|
property HotSpot: TPoint read GetHotSpot;
|
||||||
@ -2622,9 +2627,9 @@ end;
|
|||||||
{$I png.inc}
|
{$I png.inc}
|
||||||
{$I pnm.inc}
|
{$I pnm.inc}
|
||||||
{$I jpegimage.inc}
|
{$I jpegimage.inc}
|
||||||
{$I cursorimage.inc}
|
|
||||||
{$I icon.inc}
|
{$I icon.inc}
|
||||||
{$I icnsicon.inc}
|
{$I icnsicon.inc}
|
||||||
|
{$I cursorimage.inc}
|
||||||
{$I fpimagebitmap.inc}
|
{$I fpimagebitmap.inc}
|
||||||
{$I bitmap.inc}
|
{$I bitmap.inc}
|
||||||
{$I tiffimage.inc}
|
{$I tiffimage.inc}
|
||||||
|
@ -17,7 +17,20 @@
|
|||||||
* *
|
* *
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
}
|
}
|
||||||
|
const
|
||||||
|
CursorSignature: array [0..3] of char = #0#0#2#0;
|
||||||
|
|
||||||
|
function TestStreamIsCursor(const AStream: TStream): boolean;
|
||||||
|
var
|
||||||
|
Signature: array[0..3] of char;
|
||||||
|
ReadSize: Integer;
|
||||||
|
OldPosition: TStreamSeekType;
|
||||||
|
begin
|
||||||
|
OldPosition:=AStream.Position;
|
||||||
|
ReadSize:=AStream.Read(Signature, SizeOf(Signature));
|
||||||
|
Result:=(ReadSize=SizeOf(Signature)) and CompareMem(@Signature,@CursorSignature,4);
|
||||||
|
AStream.Position:=OldPosition;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TSharedCursorImage }
|
{ TSharedCursorImage }
|
||||||
|
|
||||||
@ -48,6 +61,73 @@ begin
|
|||||||
Result := RT_GROUP_CURSOR;
|
Result := RT_GROUP_CURSOR;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCursorImage.LoadFromResourceHandle(Instance: THandle; ResHandle: TFPResourceHandle);
|
||||||
|
var
|
||||||
|
GlobalHandle: TFPResourceHGlobal;
|
||||||
|
Dir: PNewHeader;
|
||||||
|
DirEntry: PGrpCursorDirEntry;
|
||||||
|
IconEntry: TIconDirEntry;
|
||||||
|
LocalHeader: TLocalHeader;
|
||||||
|
i, offset: integer;
|
||||||
|
Stream: TMemoryStream;
|
||||||
|
CursorStream: TResourceStream;
|
||||||
|
ResourceStreams: TObjectList;
|
||||||
|
begin
|
||||||
|
// build a usual cur stream using several RT_CURSOR resources
|
||||||
|
GlobalHandle := LoadResource(Instance, ResHandle);
|
||||||
|
if GlobalHandle = 0 then
|
||||||
|
Exit;
|
||||||
|
Dir := LockResource(GlobalHandle);
|
||||||
|
if Dir = nil then
|
||||||
|
Exit;
|
||||||
|
|
||||||
|
Stream := TMemoryStream.Create;
|
||||||
|
try
|
||||||
|
// write cursor header
|
||||||
|
Stream.Write(Dir^, SizeOf(TIconHeader));
|
||||||
|
// write cursor entries headers
|
||||||
|
ResourceStreams := TObjectList.Create(True);
|
||||||
|
try
|
||||||
|
offset := Stream.Position + SizeOf(IconEntry) * LEtoN(Dir^.idCount);
|
||||||
|
DirEntry := PGrpCursorDirEntry(PChar(Dir) + SizeOf(Dir^));
|
||||||
|
for i := 0 to LEtoN(Dir^.idCount) - 1 do
|
||||||
|
begin
|
||||||
|
CursorStream := TResourceStream.CreateFromID(Instance, LEtoN(DirEntry^.nID), RT_CURSOR);
|
||||||
|
ResourceStreams.Add(CursorStream);
|
||||||
|
|
||||||
|
// hot spots are stored in the local header of cursor
|
||||||
|
CursorStream.Read(LocalHeader, SizeOf(LocalHeader));
|
||||||
|
|
||||||
|
IconEntry.bWidth := DirEntry^.wWidth;
|
||||||
|
IconEntry.bHeight := DirEntry^.wHeight div 2; // in cursor resource the height is doubled
|
||||||
|
IconEntry.bColorCount := 0;
|
||||||
|
IconEntry.bReserved := 0;
|
||||||
|
IconEntry.wXHotSpot := LocalHeader.xHotSpot;
|
||||||
|
IconEntry.wYHotSpot := LocalHeader.yHotSpot;
|
||||||
|
IconEntry.dwImageOffset := NtoLE(offset);
|
||||||
|
IconEntry.dwBytesInRes := DirEntry^.dwBytesInRes - SizeOf(LocalHeader);
|
||||||
|
inc(offset, LEtoN(IconEntry.dwBytesInRes));
|
||||||
|
Stream.Write(IconEntry, SizeOf(IconEntry));
|
||||||
|
Inc(DirEntry);
|
||||||
|
end;
|
||||||
|
// write cursors data
|
||||||
|
for i := 0 to ResourceStreams.Count - 1 do
|
||||||
|
begin
|
||||||
|
CursorStream := TResourceStream(ResourceStreams[i]);
|
||||||
|
Stream.CopyFrom(CursorStream, CursorStream.Size - CursorStream.Position);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
ResourceStreams.Free;
|
||||||
|
end;
|
||||||
|
Stream.Position := 0;
|
||||||
|
ReadData(Stream);
|
||||||
|
finally
|
||||||
|
Stream.Free;
|
||||||
|
UnLockResource(GlobalHandle);
|
||||||
|
FreeResource(GlobalHandle);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
class function TCursorImage.GetSharedImageClass: TSharedRasterImageClass;
|
class function TCursorImage.GetSharedImageClass: TSharedRasterImageClass;
|
||||||
begin
|
begin
|
||||||
Result := TSharedCursorImage;
|
Result := TSharedCursorImage;
|
||||||
@ -118,4 +198,9 @@ begin
|
|||||||
Result := Size(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));
|
Result := Size(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TCursorImage.GetStreamSignature: Cardinal;
|
||||||
|
begin
|
||||||
|
Result := Cardinal(CursorSignature);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
const
|
const
|
||||||
IconSignature: array [0..3] of char = #0#0#1#0;
|
IconSignature: array [0..3] of char = #0#0#1#0;
|
||||||
CursorSignature: array [0..3] of char = #0#0#2#0;
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TIconHeader = {packed} record // packed it not needed
|
TIconHeader = {packed} record // packed it not needed
|
||||||
@ -54,32 +53,38 @@ type
|
|||||||
PIconDirEntry = ^TIconDirEntry;
|
PIconDirEntry = ^TIconDirEntry;
|
||||||
|
|
||||||
// executables and libraries has the next structures for icons and cursors
|
// executables and libraries has the next structures for icons and cursors
|
||||||
|
PGrpIconDirEntry = ^TGrpIconDirEntry;
|
||||||
TGrpIconDirEntry = packed record
|
TGrpIconDirEntry = packed record
|
||||||
bWidth: Byte; // Width, in pixels, of the image
|
bWidth: Byte; // Width, in pixels, of the image
|
||||||
bHeight: Byte; // Height, in pixels, of the image
|
bHeight: Byte; // Height, in pixels, of the image
|
||||||
bColorCount: Byte; // Number of colors in image (0 if >=8bpp)
|
bColorCount: Byte; // Number of colors in image (0 if >=8bpp)
|
||||||
bReserved: Byte; // Reserved
|
bReserved: Byte; // Reserved
|
||||||
case Byte of
|
|
||||||
1: (
|
|
||||||
// icon
|
|
||||||
wPlanes: Word; // color planes
|
wPlanes: Word; // color planes
|
||||||
wBpp: Word; // bits per pixel
|
wBpp: Word; // bits per pixel
|
||||||
// common
|
|
||||||
dwBytesInRes: Dword; // how many bytes in this resource?
|
dwBytesInRes: Dword; // how many bytes in this resource?
|
||||||
nID: Word; // the ID
|
nID: Word; // the ID
|
||||||
);
|
|
||||||
2:(
|
|
||||||
// cursor
|
|
||||||
wXHotSpot: Word;
|
|
||||||
wYHotSpot: Word;
|
|
||||||
);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TGrpIconDir = packed record
|
PGrpCursorDirEntry = ^TGrpCursorDirEntry;
|
||||||
|
TGrpCursorDirEntry = packed record
|
||||||
|
wWidth: Word; // Width, in pixels, of the image
|
||||||
|
wHeight: Word; // Height, in pixels, of the image
|
||||||
|
wPlanes: Word; // color planes
|
||||||
|
wBitCount: Word; // bits per pixel
|
||||||
|
dwBytesInRes: Dword; // how many bytes in this resource?
|
||||||
|
nID: Word; // the ID
|
||||||
|
end;
|
||||||
|
|
||||||
|
TLocalHeader = packed record
|
||||||
|
xHotSpot: Word;
|
||||||
|
yHotSpot: Word;
|
||||||
|
end;
|
||||||
|
|
||||||
|
PNewHeader = ^TNewHeader;
|
||||||
|
TNewHeader = packed record
|
||||||
idReserved: Word; // Reserved (must be 0)
|
idReserved: Word; // Reserved (must be 0)
|
||||||
idType: Word; // Resource type (1 for icons)
|
idType: Word; // Resource type (1 for icons)
|
||||||
idCount: Word; // How many images?
|
idCount: Word; // How many images?
|
||||||
idEntries: array[0..0] of TGrpIconDirEntry; // The entries for each image
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TestStreamIsIcon(const AStream: TStream): boolean;
|
function TestStreamIsIcon(const AStream: TStream): boolean;
|
||||||
@ -94,18 +99,6 @@ begin
|
|||||||
AStream.Position:=OldPosition;
|
AStream.Position:=OldPosition;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TestStreamIsCursor(const AStream: TStream): boolean;
|
|
||||||
var
|
|
||||||
Signature: array[0..3] of char;
|
|
||||||
ReadSize: Integer;
|
|
||||||
OldPosition: TStreamSeekType;
|
|
||||||
begin
|
|
||||||
OldPosition:=AStream.Position;
|
|
||||||
ReadSize:=AStream.Read(Signature, SizeOf(Signature));
|
|
||||||
Result:=(ReadSize=SizeOf(Signature)) and CompareMem(@Signature,@CursorSignature,4);
|
|
||||||
AStream.Position:=OldPosition;
|
|
||||||
end;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
{ TSharedIcon }
|
{ TSharedIcon }
|
||||||
@ -621,6 +614,11 @@ begin
|
|||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TCustomIcon.GetStreamSignature: Cardinal;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
class function TCustomIcon.GetTypeID: Word;
|
class function TCustomIcon.GetTypeID: Word;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := 0;
|
||||||
@ -702,57 +700,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomIcon.LoadFromResourceHandle(Instance: THandle; ResHandle: TFPResourceHandle);
|
procedure TCustomIcon.LoadFromResourceHandle(Instance: THandle; ResHandle: TFPResourceHandle);
|
||||||
var
|
|
||||||
GlobalHandle: TFPResourceHGlobal;
|
|
||||||
Dir: ^TGrpIconDir;
|
|
||||||
DirEntry: ^TGrpIconDirEntry;
|
|
||||||
IconEntry: TIconDirEntry;
|
|
||||||
i, offset: integer;
|
|
||||||
Stream: TMemoryStream;
|
|
||||||
IconStream: TResourceStream;
|
|
||||||
begin
|
begin
|
||||||
// build a usual ico/cur stream using several RT_ICON resources
|
|
||||||
GlobalHandle := LoadResource(Instance, ResHandle);
|
|
||||||
if GlobalHandle = 0 then
|
|
||||||
Exit;
|
|
||||||
Dir := LockResource(GlobalHandle);
|
|
||||||
if Dir = nil then
|
|
||||||
Exit;
|
|
||||||
|
|
||||||
Stream := TMemoryStream.Create;
|
|
||||||
try
|
|
||||||
// write icon header
|
|
||||||
Stream.Write(Dir^, SizeOf(TIconHeader));
|
|
||||||
// write icon entries headers
|
|
||||||
offset := Stream.Position + SizeOf(IconEntry) * LEtoN(Dir^.idCount);
|
|
||||||
DirEntry := @Dir^.idEntries[0];
|
|
||||||
for i := 0 to LEtoN(Dir^.idCount) - 1 do
|
|
||||||
begin
|
|
||||||
Move(DirEntry^, IconEntry, SizeOf(DirEntry^));
|
|
||||||
IconEntry.dwImageOffset := NtoLE(offset);
|
|
||||||
inc(offset, LEtoN(IconEntry.dwBytesInRes));
|
|
||||||
Stream.Write(IconEntry, SizeOf(IconEntry));
|
|
||||||
Inc(DirEntry);
|
|
||||||
end;
|
|
||||||
// write icons data
|
|
||||||
DirEntry := @Dir^.idEntries[0];
|
|
||||||
for i := 0 to LEtoN(Dir^.idCount) - 1 do
|
|
||||||
begin
|
|
||||||
IconStream := TResourceStream.CreateFromID(Instance, LEtoN(DirEntry^.nID), RT_ICON);
|
|
||||||
try
|
|
||||||
Stream.CopyFrom(IconStream, IconStream.Size);
|
|
||||||
finally
|
|
||||||
IconStream.Free;
|
|
||||||
end;
|
|
||||||
Inc(DirEntry);
|
|
||||||
end;
|
|
||||||
Stream.Position := 0;
|
|
||||||
ReadData(Stream);
|
|
||||||
finally
|
|
||||||
Stream.Free;
|
|
||||||
UnLockResource(GlobalHandle);
|
|
||||||
FreeResource(GlobalHandle);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomIcon.MaskHandleAllocated: boolean;
|
function TCustomIcon.MaskHandleAllocated: boolean;
|
||||||
@ -841,7 +789,7 @@ begin
|
|||||||
Position := Stream.Position;
|
Position := Stream.Position;
|
||||||
Stream.Read(Signature, SizeOf(Signature));
|
Stream.Read(Signature, SizeOf(Signature));
|
||||||
Stream.Position := Position;
|
Stream.Position := Position;
|
||||||
if Cardinal(Signature) = Cardinal(IconSignature)
|
if Cardinal(Signature) = GetStreamSignature
|
||||||
then begin
|
then begin
|
||||||
// Assume Icon - stream without explicit size
|
// Assume Icon - stream without explicit size
|
||||||
LoadFromStream(Stream);
|
LoadFromStream(Stream);
|
||||||
@ -1402,6 +1350,11 @@ begin
|
|||||||
SetHandle(AValue);
|
SetHandle(AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TIcon.GetStreamSignature: Cardinal;
|
||||||
|
begin
|
||||||
|
Result := Cardinal(IconSignature);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TIcon.HandleNeeded;
|
procedure TIcon.HandleNeeded;
|
||||||
var
|
var
|
||||||
IconInfo: TIconInfo;
|
IconInfo: TIconInfo;
|
||||||
@ -1414,4 +1367,58 @@ begin
|
|||||||
FSharedImage.FHandle := WidgetSet.CreateIconIndirect(@IconInfo);
|
FSharedImage.FHandle := WidgetSet.CreateIconIndirect(@IconInfo);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TIcon.LoadFromResourceHandle(Instance: THandle; ResHandle: TFPResourceHandle);
|
||||||
|
var
|
||||||
|
GlobalHandle: TFPResourceHGlobal;
|
||||||
|
Dir: PNewHeader;
|
||||||
|
DirEntry: PGrpIconDirEntry;
|
||||||
|
IconEntry: TIconDirEntry;
|
||||||
|
i, offset: integer;
|
||||||
|
Stream: TMemoryStream;
|
||||||
|
IconStream: TResourceStream;
|
||||||
|
begin
|
||||||
|
// build a usual ico stream using several RT_ICON resources
|
||||||
|
GlobalHandle := LoadResource(Instance, ResHandle);
|
||||||
|
if GlobalHandle = 0 then
|
||||||
|
Exit;
|
||||||
|
Dir := LockResource(GlobalHandle);
|
||||||
|
if Dir = nil then
|
||||||
|
Exit;
|
||||||
|
|
||||||
|
Stream := TMemoryStream.Create;
|
||||||
|
try
|
||||||
|
// write icon header
|
||||||
|
Stream.Write(Dir^, SizeOf(TIconHeader));
|
||||||
|
// write icon entries headers
|
||||||
|
offset := Stream.Position + SizeOf(IconEntry) * LEtoN(Dir^.idCount);
|
||||||
|
DirEntry := PGrpIconDirEntry(PChar(Dir) + SizeOf(Dir^));
|
||||||
|
for i := 0 to LEtoN(Dir^.idCount) - 1 do
|
||||||
|
begin
|
||||||
|
Move(DirEntry^, IconEntry, SizeOf(DirEntry^));
|
||||||
|
IconEntry.dwImageOffset := NtoLE(offset);
|
||||||
|
inc(offset, LEtoN(IconEntry.dwBytesInRes));
|
||||||
|
Stream.Write(IconEntry, SizeOf(IconEntry));
|
||||||
|
Inc(DirEntry);
|
||||||
|
end;
|
||||||
|
// write icons data
|
||||||
|
DirEntry := PGrpIconDirEntry(PChar(Dir) + SizeOf(Dir^));
|
||||||
|
for i := 0 to LEtoN(Dir^.idCount) - 1 do
|
||||||
|
begin
|
||||||
|
IconStream := TResourceStream.CreateFromID(Instance, LEtoN(DirEntry^.nID), RT_ICON);
|
||||||
|
try
|
||||||
|
Stream.CopyFrom(IconStream, IconStream.Size);
|
||||||
|
finally
|
||||||
|
IconStream.Free;
|
||||||
|
end;
|
||||||
|
Inc(DirEntry);
|
||||||
|
end;
|
||||||
|
Stream.Position := 0;
|
||||||
|
ReadData(Stream);
|
||||||
|
finally
|
||||||
|
Stream.Free;
|
||||||
|
UnLockResource(GlobalHandle);
|
||||||
|
FreeResource(GlobalHandle);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user