|
@@ -114,8 +114,9 @@ destructor TIcoFile.Destroy;
|
|
|
var
|
|
|
i: integer;
|
|
|
begin
|
|
|
- for i:=low(FIcons) to high(FIcons) do
|
|
|
- DestroyIconData(FIcons[i]);
|
|
|
+ if Length(FIcons) > 0 then
|
|
|
+ for i:=low(FIcons) to high(FIcons) do
|
|
|
+ DestroyIconData(FIcons[i]);
|
|
|
inherited;
|
|
|
end;
|
|
|
|
|
@@ -240,49 +241,55 @@ var
|
|
|
Size: Cardinal;
|
|
|
i: integer;
|
|
|
begin
|
|
|
- try
|
|
|
- setLength(FIcons,length(FIcons)+1);
|
|
|
- with FIcons[high(FIcons)] do
|
|
|
- begin
|
|
|
- Assert(GetIconInfo(h,IconInfo));
|
|
|
+ if not GetIconInfo(h, IconInfo) then
|
|
|
+ Exit;
|
|
|
|
|
|
- InternalGetDIB(IconInfo.hbmColor,iRgbTable,BitmapInfo,ImageBits);
|
|
|
- InternalGetDIB(IconInfo.hbmMask,i,MaskBitmapInfo,MaskBits);
|
|
|
- // MaskBitmapInfo ìîæåò ïîíàäîáèòüñÿ òîëüêî äëÿ îòðèñîâêè, äëÿ ñîõðàíåíèÿ â ôàéë îíà íå íóæíà}
|
|
|
+ try
|
|
|
+ try
|
|
|
+ setLength(FIcons,length(FIcons)+1);
|
|
|
+ with FIcons[high(FIcons)] do
|
|
|
+ begin
|
|
|
+ InternalGetDIB(IconInfo.hbmColor,iRgbTable,BitmapInfo,ImageBits);
|
|
|
+ InternalGetDIB(IconInfo.hbmMask,i,MaskBitmapInfo,MaskBits);
|
|
|
+ // MaskBitmapInfo ìîæåò ïîíàäîáèòüñÿ òîëüêî äëÿ îòðèñîâêè, äëÿ ñîõðàíåíèÿ â ôàéë îíà íå íóæíà}
|
|
|
|
|
|
- with Info do
|
|
|
- begin
|
|
|
- Colors := 0;
|
|
|
- Width := BitmapInfo^.bmiHeader.biWidth;
|
|
|
- Height := BitmapInfo^.bmiHeader.biHeight;
|
|
|
- Reserved1 := MaskBitmapInfo^.bmiHeader.biBitCount;
|
|
|
- Reserved2 := BitmapInfo^.bmiHeader.biBitCount;
|
|
|
- DIBSize := MaskBitmapInfo^.bmiHeader.biSizeImage+DWORD(iRgbTable)+BitmapInfo^.bmiHeader.biSize+BitmapInfo^.bmiHeader.biSizeImage;
|
|
|
- DIBOffset := -1; // Íàäî ïðîñòàâèòü ïðè ñîõðàíåíèè.
|
|
|
- end;
|
|
|
+ with Info do
|
|
|
+ begin
|
|
|
+ Colors := 0;
|
|
|
+ Width := BitmapInfo^.bmiHeader.biWidth;
|
|
|
+ Height := BitmapInfo^.bmiHeader.biHeight;
|
|
|
+ Reserved1 := MaskBitmapInfo^.bmiHeader.biBitCount;
|
|
|
+ Reserved2 := BitmapInfo^.bmiHeader.biBitCount;
|
|
|
+ DIBSize := MaskBitmapInfo^.bmiHeader.biSizeImage+DWORD(iRgbTable)+BitmapInfo^.bmiHeader.biSize+BitmapInfo^.bmiHeader.biSizeImage;
|
|
|
+ DIBOffset := -1; // Íàäî ïðîñòàâèòü ïðè ñîõðàíåíèè.
|
|
|
+ end;
|
|
|
|
|
|
- with BitmapInfo^.bmiHeader do
|
|
|
- begin
|
|
|
- ImageLineWidth := BytesPerScanline(biWidth,biBitCount,32); // Ïî íåìó îïðåäåëÿåì ðàçìåð ëèíèè
|
|
|
+ with BitmapInfo^.bmiHeader do
|
|
|
+ begin
|
|
|
+ ImageLineWidth := BytesPerScanline(biWidth,biBitCount,32); // Ïî íåìó îïðåäåëÿåì ðàçìåð ëèíèè
|
|
|
|
|
|
- Assert((biWidth*biBitCount+31) div 32*4 = ImageLineWidth);
|
|
|
- Size := biHeight*ImageLineWidth; // È äîëæåí ïîëó÷èòüñÿ ðàçìåð âñåãî áèòìàïà
|
|
|
- Assert(Size=biSizeImage);
|
|
|
+ Assert((biWidth*biBitCount+31) div 32*4 = ImageLineWidth);
|
|
|
+ Size := biHeight*ImageLineWidth; // È äîëæåí ïîëó÷èòüñÿ ðàçìåð âñåãî áèòìàïà
|
|
|
+ Assert(Size=biSizeImage);
|
|
|
|
|
|
- biHeight := biHeight*2; // Òàê äîëæíî áûòü ÿêîáû èç-çà íàëè÷èÿ ìàñêè
|
|
|
- end;
|
|
|
+ biHeight := biHeight*2; // Òàê äîëæíî áûòü ÿêîáû èç-çà íàëè÷èÿ ìàñêè
|
|
|
+ end;
|
|
|
|
|
|
- with MaskBitmapInfo^.bmiHeader do
|
|
|
- begin
|
|
|
- MaskLineWidth := BytesPerScanline(biWidth,biBitCount,32);
|
|
|
+ with MaskBitmapInfo^.bmiHeader do
|
|
|
+ begin
|
|
|
+ MaskLineWidth := BytesPerScanline(biWidth,biBitCount,32);
|
|
|
|
|
|
- Assert((biWidth+31) div 32*4 = MaskLineWidth); // Ïðîâåðêè
|
|
|
- Size := biHeight*MaskLineWidth; // Ðàçìåð ìàñêè (1-áèòíîé)
|
|
|
- Assert(Size=biSizeImage);
|
|
|
- end;
|
|
|
- end;
|
|
|
- except
|
|
|
- setLength(FIcons,length(FIcons)-1);
|
|
|
+ Assert((biWidth+31) div 32*4 = MaskLineWidth); // Ïðîâåðêè
|
|
|
+ Size := biHeight*MaskLineWidth; // Ðàçìåð ìàñêè (1-áèòíîé)
|
|
|
+ Assert(Size=biSizeImage);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ except
|
|
|
+ setLength(FIcons,length(FIcons)-1);
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ DeleteObject(IconInfo.hbmColor);
|
|
|
+ DeleteObject(IconInfo.hbmMask);
|
|
|
end;
|
|
|
end;
|
|
|
|
|
@@ -413,20 +420,24 @@ begin
|
|
|
FileHeader.Count := length(FIcons);
|
|
|
Stream.WriteBuffer(FileHeader,SizeOf(FileHeader));
|
|
|
offset := Stream.Position+length(FIcons)*SizeOf(TIconRec); // Áèòìàïû íà÷íóòñÿ çäåñü
|
|
|
- for i:=low(FIcons) to high(FIcons) do
|
|
|
- with FIcons[i] do
|
|
|
- begin
|
|
|
- Info.DIBOffset := offset;
|
|
|
- Stream.WriteBuffer(Info,SizeOf(TIconRec));
|
|
|
- offset := offset+SizeOf(BitmapInfo^.bmiHeader)+iRgbTable+length(ImageBits)+length(MaskBits);
|
|
|
- end;
|
|
|
- for i:=low(FIcons) to high(FIcons) do
|
|
|
- with FIcons[i] do
|
|
|
- begin
|
|
|
- Stream.WriteBuffer(BitmapInfo^.bmiHeader,SizeOf(BitmapInfo^.bmiHeader)+iRgbTable);
|
|
|
- Stream.WriteBuffer(ImageBits[0],length(ImageBits));
|
|
|
- Stream.WriteBuffer(MaskBits[0],length(MaskBits));
|
|
|
- end;
|
|
|
+
|
|
|
+ if Length(FIcons) > 0 then
|
|
|
+ begin
|
|
|
+ for i:=low(FIcons) to high(FIcons) do
|
|
|
+ with FIcons[i] do
|
|
|
+ begin
|
|
|
+ Info.DIBOffset := offset;
|
|
|
+ Stream.WriteBuffer(Info,SizeOf(TIconRec));
|
|
|
+ offset := offset+SizeOf(BitmapInfo^.bmiHeader)+iRgbTable+length(ImageBits)+length(MaskBits);
|
|
|
+ end;
|
|
|
+ for i:=low(FIcons) to high(FIcons) do
|
|
|
+ with FIcons[i] do
|
|
|
+ begin
|
|
|
+ Stream.WriteBuffer(BitmapInfo^.bmiHeader,SizeOf(BitmapInfo^.bmiHeader)+iRgbTable);
|
|
|
+ Stream.WriteBuffer(ImageBits[0],length(ImageBits));
|
|
|
+ Stream.WriteBuffer(MaskBits[0],length(MaskBits));
|
|
|
+ end;
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
procedure TIcoFile.check;
|
|
@@ -437,25 +448,26 @@ begin
|
|
|
// Ìîæíî òàêæå ïðèìåíÿòü, ÷òîáû ïðîâåðèòü ïðàâèëüíîñòü çàãðóçêè è âîîáùå íà âñÿêèé ñëó÷àé
|
|
|
// ÷òîáû îòëîâèòü ãëþêè.
|
|
|
// "Ñîöèàëèçì - ýòî êîíòðîëü è ó÷¸ò."
|
|
|
- for i:=low(FIcons) to high(FIcons) do
|
|
|
- with FIcons[i] do
|
|
|
- begin
|
|
|
- Assert((Info.Reserved1=0) = (Info.Reserved2=0)); // Ðàâíû íóëþ òîëüêî îäíîâðåìåííî
|
|
|
- Assert((Info.Colors<>0) or (Info.Reserved1<>0));
|
|
|
- Assert(Info.Reserved1 in [0,1]);
|
|
|
- with BitmapInfo^.bmiHeader do
|
|
|
- begin
|
|
|
- Assert(biSize=sizeOf(BitmapInfo^.bmiHeader));
|
|
|
- Assert(Info.Width=biWidth);
|
|
|
- Assert(Info.Height*2=biHeight);
|
|
|
- Assert(biPlanes=1);
|
|
|
- Assert(Info.Reserved2 in [0,biBitCount]);
|
|
|
- Assert(biBitCount in [1,4,8,16,24,32]);
|
|
|
- Assert(biCompression=BI_RGB{=0});
|
|
|
- Assert(biXPelsPerMeter=0);
|
|
|
- Assert(biYPelsPerMeter=0);
|
|
|
- end;
|
|
|
- end;
|
|
|
+ if Length(FIcons) > 0 then
|
|
|
+ for i:=low(FIcons) to high(FIcons) do
|
|
|
+ with FIcons[i] do
|
|
|
+ begin
|
|
|
+ Assert((Info.Reserved1=0) = (Info.Reserved2=0)); // Ðàâíû íóëþ òîëüêî îäíîâðåìåííî
|
|
|
+ Assert((Info.Colors<>0) or (Info.Reserved1<>0));
|
|
|
+ Assert(Info.Reserved1 in [0,1]);
|
|
|
+ with BitmapInfo^.bmiHeader do
|
|
|
+ begin
|
|
|
+ Assert(biSize=sizeOf(BitmapInfo^.bmiHeader));
|
|
|
+ Assert(Info.Width=biWidth);
|
|
|
+ Assert(Info.Height*2=biHeight);
|
|
|
+ Assert(biPlanes=1);
|
|
|
+ Assert(Info.Reserved2 in [0,biBitCount]);
|
|
|
+ Assert(biBitCount in [1,4,8,16,24,32]);
|
|
|
+ Assert(biCompression=BI_RGB{=0});
|
|
|
+ Assert(biXPelsPerMeter=0);
|
|
|
+ Assert(biYPelsPerMeter=0);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
procedure TIcoFile.draw(icoNo,x,y:integer;dest:hdc;drawMask,drawImage,drawAlpha:boolean);
|
|
@@ -597,29 +609,35 @@ end;
|
|
|
|
|
|
function CreateIconFromHandle(IconHandle : HIcon) : TIcon;
|
|
|
var
|
|
|
- IcoFile : TIcoFile;
|
|
|
- memstream : TMemoryStream;
|
|
|
+ IcoFile : TIcoFile = nil;
|
|
|
+ memstream : TMemoryStream = nil;
|
|
|
IconData : TIconData;
|
|
|
I : Integer;
|
|
|
begin
|
|
|
+ Result := nil;
|
|
|
try
|
|
|
IcoFile := TIcoFile.Create(nil);
|
|
|
memstream := TMemoryStream.Create;
|
|
|
IcoFile.loadFromHandle(IconHandle);
|
|
|
- for I := Low(IcoFile.Icons) to High(IcoFile.Icons) do
|
|
|
- if not IcoFile.IsValidAlpha(I) then
|
|
|
- begin
|
|
|
- IcoFile.saveTrueColorFrom32(I, IconData);
|
|
|
- IcoFile.DestroyIconData(IcoFile.Icons[i]);
|
|
|
- IcoFile.Icons[I] := IconData;
|
|
|
- end;
|
|
|
- IcoFile.saveToStream(memstream);
|
|
|
- Result := TIcon.Create;
|
|
|
- memstream.Position := 0;
|
|
|
- Result.LoadFromStream(memstream);
|
|
|
+ if Length(IcoFile.Icons) > 0 then
|
|
|
+ begin
|
|
|
+ for I := Low(IcoFile.Icons) to High(IcoFile.Icons) do
|
|
|
+ if not IcoFile.IsValidAlpha(I) then
|
|
|
+ begin
|
|
|
+ IcoFile.saveTrueColorFrom32(I, IconData);
|
|
|
+ IcoFile.DestroyIconData(IcoFile.Icons[i]);
|
|
|
+ IcoFile.Icons[I] := IconData;
|
|
|
+ end;
|
|
|
+ IcoFile.saveToStream(memstream);
|
|
|
+ Result := TIcon.Create;
|
|
|
+ memstream.Position := 0;
|
|
|
+ Result.LoadFromStream(memstream);
|
|
|
+ end;
|
|
|
finally
|
|
|
- IcoFile.Free;
|
|
|
- memstream.Free;
|
|
|
+ if Assigned(IcoFile) then
|
|
|
+ IcoFile.Free;
|
|
|
+ if Assigned(memstream) then
|
|
|
+ memstream.Free;
|
|
|
end;
|
|
|
end;
|
|
|
|