There is a leak of a Bitmap handle in TBitmap.ReadDIB
for RLE bitmaps in
graphics.pas. It is still there in Delphi 4 for which
I have a fix below.
Same fix lines apply to Delphi 3 code although there
have been some other
code adjustments to the function.
I have a {$DEFINE FIXES} at the top of my replacement
graphics.pas. Look out
for the {$IFDEF FIXES} conditional defines in the
code below for fixed
lines.
Hope this helps, it took me a long time to pinpoint this.
David
procedure TBitmap.ReadDIB(Stream: TStream; ImageSize:
LongWord);
const
DIBPalSizes: array [Boolean] of Byte = (sizeof(TRGBQuad),
sizeof(TRGBTriple));
var
..... Lines chopped ....
{$IFDEF FIXES}
ABmHandle: HBITMAP; //David
Willis
{$ENDIF}
begin
..... Lines chopped ....
DC := GDICheck(GetDC(0));
try
if (bmiHeader.biCompression
= BI_RLE8)
or (bmiHeader.biCompression
= BI_RLE4) or DDBsOnly then
begin
MemDC
:= 0;
{$IFDEF
FIXES}
ABmHandle := 0; //David Willis
{$ENDIF}
GetMem(BitsMem,
ImageSize);
try
Stream.ReadBuffer(BitsMem^, ImageSize);
MemDC := GDICheck(CreateCompatibleDC(DC));
{$IFDEF FIXES}
ABmHandle := CreateCompatibleBitmap(DC, 1, 1); //David Willis
DeleteObject(SelectObject(MemDC, ABmHandle)); //David Willis
{$ELSE}
DeleteObject(SelectObject(MemDC, CreateCompatibleBitmap(DC, 1,1)));
//Original line
{$ENDIF}
OldPal := 0;
if bmiHeader.biClrUsed > 0 then
begin
Pal := PaletteFromDIBColorTable(0, ColorTable,bmiHeader.biClrUsed);
OldPal := SelectPalette(MemDC, Pal, False);
RealizePalette(MemDC);
end;
try
BMHandle := CreateDIBitmap(MemDC, BitmapInfo^.bmiHeader,
CBM_INIT, BitsMem,
BitmapInfo^, DIB_RGB_COLORS);
if (BMHandle = 0) then
if GetLastError = 0 then
InvalidBitmap
else
RaiseLastWin32Error;
finally
if OldPal <> 0 then
SelectPalette(MemDC, OldPal, True);
end;
finally
if MemDC <> 0 then DeleteDC(MemDC);
{$IFDEF FIXES}
if ABmHandle <> 0 then DeleteObject(ABmHandle); //David Willis
{$ENDIF}
FreeMem(BitsMem);
end;
end
.... Rest of function unchanged ...