54
53
PIconDirEntry = ^TIconDirEntry;
56
55
// executables and libraries has the next structures for icons and cursors
56
PGrpIconDirEntry = ^TGrpIconDirEntry;
57
57
TGrpIconDirEntry = packed record
58
bWidth: Byte; // Width, in pixels, of the image
59
bHeight: Byte; // Height, in pixels, of the image
60
bColorCount: Byte; // Number of colors in image (0 if >=8bpp)
61
bReserved: Byte; // Reserved
65
wPlanes: Word; // color planes
66
wBpp: Word; // bits per pixel
68
dwBytesInRes: Dword; // how many bytes in this resource?
78
TGrpIconDir = packed record
58
bWidth: Byte; // Width, in pixels, of the image
59
bHeight: Byte; // Height, in pixels, of the image
60
bColorCount: Byte; // Number of colors in image (0 if >=8bpp)
61
bReserved: Byte; // Reserved
62
wPlanes: Word; // color planes
63
wBpp: Word; // bits per pixel
64
dwBytesInRes: Dword; // how many bytes in this resource?
68
PGrpCursorDirEntry = ^TGrpCursorDirEntry;
69
TGrpCursorDirEntry = packed record
70
wWidth: Word; // Width, in pixels, of the image
71
wHeight: Word; // Height, in pixels, of the image
72
wPlanes: Word; // color planes
73
wBitCount: Word; // bits per pixel
74
dwBytesInRes: Dword; // how many bytes in this resource?
78
TLocalHeader = packed record
83
PNewHeader = ^TNewHeader;
84
TNewHeader = packed record
79
85
idReserved: Word; // Reserved (must be 0)
80
86
idType: Word; // Resource type (1 for icons)
81
87
idCount: Word; // How many images?
82
idEntries: array[0..0] of TGrpIconDirEntry; // The entries for each image
85
90
function TestStreamIsIcon(const AStream: TStream): boolean;
94
99
AStream.Position:=OldPosition;
97
function TestStreamIsCursor(const AStream: TStream): boolean;
99
Signature: array[0..3] of char;
101
OldPosition: TStreamSeekType;
103
OldPosition:=AStream.Position;
104
ReadSize:=AStream.Read(Signature, SizeOf(Signature));
105
Result:=(ReadSize=SizeOf(Signature)) and CompareMem(@Signature,@CursorSignature,4);
106
AStream.Position:=OldPosition;
109
102
////////////////////////////////////////////////////////////////////////////////
150
148
FImages := TFPList.Create;
153
procedure TSharedIcon.Delete(Aindex: Integer);
151
procedure TSharedIcon.Delete(AIndex: Integer);
155
153
Image: TIconImage;
157
Image := TIconImage(FImages[Aindex]);
155
Image := TIconImage(FImages[AIndex]);
158
156
FImages.Delete(AIndex);
558
558
Result := TSharedIcon(FSharedImage).GetIndex(AFormat, AHeight, AWidth);
561
function TCustomIcon.GetMasked: Boolean;
563
// per definition an icon is masked, but maybe we should make it settable for alpha images
567
561
function TCustomIcon.GetMaskHandle: HBITMAP;
679
678
ResHandle := FindResource(Instance, PChar(ResName), PChar(ResType));
680
679
if ResHandle = 0 then
681
raise EResNotFound.Create(ResName); // todo: valid exception
680
raise EResNotFound.Create(Format('[TCustomIcon.LoadFromResourceName] The resource "%s" was not found', [ResName])); // todo: valid exception
682
681
LoadFromResourceHandle(Instance, ResHandle);
693
692
ResHandle := FindResource(Instance, PChar(ResID), PChar(ResType));
694
693
if ResHandle = 0 then
695
raise EResNotFound.Create(''); // todo: valid exception
694
raise EResNotFound.Create(Format('[TCustomIcon.LoadFromResourceID] The resource #%d was not found', [ResID])); // todo: valid exception
696
695
LoadFromResourceHandle(Instance, ResHandle);
699
698
procedure TCustomIcon.LoadFromResourceHandle(Instance: THandle; ResHandle: TFPResourceHandle);
701
GlobalHandle: TFPResourceHGlobal;
703
DirEntry: ^TGrpIconDirEntry;
704
IconEntry: TIconDirEntry;
706
Stream: TMemoryStream;
707
IconStream: TResourceStream;
709
// build a usual ico/cur stream using several RT_ICON resources
710
GlobalHandle := LoadResource(Instance, ResHandle);
711
if GlobalHandle = 0 then
713
Dir := LockResource(GlobalHandle);
717
Stream := TMemoryStream.Create;
720
Stream.Write(Dir^, SizeOf(TIconHeader));
721
// write icon entries headers
722
offset := Stream.Position + SizeOf(IconEntry) * LEtoN(Dir^.idCount);
723
DirEntry := @Dir^.idEntries[0];
724
for i := 0 to LEtoN(Dir^.idCount) - 1 do
726
Move(DirEntry^, IconEntry, SizeOf(DirEntry^));
727
IconEntry.dwImageOffset := NtoLE(offset);
728
inc(offset, LEtoN(IconEntry.dwBytesInRes));
729
Stream.Write(IconEntry, SizeOf(IconEntry));
733
DirEntry := @Dir^.idEntries[0];
734
for i := 0 to LEtoN(Dir^.idCount) - 1 do
736
IconStream := TResourceStream.CreateFromID(Instance, LEtoN(DirEntry^.nID), RT_ICON);
738
Stream.CopyFrom(IconStream, IconStream.Size);
744
Stream.Position := 0;
748
UnLockResource(GlobalHandle);
749
FreeResource(GlobalHandle);
753
702
function TCustomIcon.MaskHandleAllocated: boolean;
836
785
Position := Stream.Position;
837
786
Stream.Read(Signature, SizeOf(Signature));
838
787
Stream.Position := Position;
839
if Cardinal(Signature) = Cardinal(IconSignature)
788
if Cardinal(Signature) = GetStreamSignature
841
790
// Assume Icon - stream without explicit size
842
791
LoadFromStream(Stream);
1409
1363
FSharedImage.FHandle := WidgetSet.CreateIconIndirect(@IconInfo);
1366
procedure TIcon.LoadFromResourceHandle(Instance: THandle; ResHandle: TFPResourceHandle);
1368
GlobalHandle: TFPResourceHGlobal;
1370
DirEntry: PGrpIconDirEntry;
1371
IconEntry: TIconDirEntry;
1373
Stream: TMemoryStream;
1374
IconStream: TResourceStream;
1376
// build a usual ico stream using several RT_ICON resources
1377
GlobalHandle := LoadResource(Instance, ResHandle);
1378
if GlobalHandle = 0 then
1380
Dir := LockResource(GlobalHandle);
1384
Stream := TMemoryStream.Create;
1386
// write icon header
1387
Stream.Write(Dir^, SizeOf(TIconHeader));
1388
// write icon entries headers
1389
offset := Stream.Position + SizeOf(IconEntry) * LEtoN(Dir^.idCount);
1390
DirEntry := PGrpIconDirEntry(PChar(Dir) + SizeOf(Dir^));
1391
for i := 0 to LEtoN(Dir^.idCount) - 1 do
1393
Move(DirEntry^, IconEntry, SizeOf(DirEntry^));
1394
IconEntry.dwImageOffset := NtoLE(offset);
1395
inc(offset, LEtoN(IconEntry.dwBytesInRes));
1396
Stream.Write(IconEntry, SizeOf(IconEntry));
1400
DirEntry := PGrpIconDirEntry(PChar(Dir) + SizeOf(Dir^));
1401
for i := 0 to LEtoN(Dir^.idCount) - 1 do
1403
IconStream := TResourceStream.CreateFromID(Instance, LEtoN(DirEntry^.nID), RT_ICON);
1405
Stream.CopyFrom(IconStream, IconStream.Size);
1411
Stream.Position := 0;
1415
UnLockResource(GlobalHandle);
1416
FreeResource(GlobalHandle);