使用:在英特尔酷睿i7-2820QM上运行的Delphi XE7 Update 1,TAwImageGrid,Windows 10 Professional。
此代码从数据库将图像加载到网格中:
var
s, w: String;
r: Integer;
ms: TMemoryStream;
bmp: TBitmap;
begin
r := uqProj_Search.RecordCount;
// Load images
for r := imgGrid.Count - 1 downto 0 do
imgGrid.Items.Images[r].Free;
imgGrid.Clear;
ms := TMemoryStream.Create;
try
while not(uqProj_Search.Eof) do
begin
r := uqProj_Search.FieldByName('row_id').AsInteger;
// :proj_id
uqImg_S.ParamByName('proj_id').AsInteger := r;
uqImg_S.Prepared := True;
uqImg_S.Open;
ms.Clear;
uqImg_Simg.SaveToStream(ms);
uqImg_S.Close;
ms.Position := 0;
bmp := TBitmap.Create;
try
bmp.LoadFromStream(ms);
imgGrid.Items.Add(IntToStr(r));
imgGrid.Items.Images[imgGrid.Count - 1] := TBitmap.Create;
imgGrid.Items.Images[imgGrid.Count - 1].Assign(bmp);
finally
bmp.Free;
end;
uqProj_Search.Next;
end;
finally
ms.Free;
end;
end;
我在KeyDown事件中有这个代码(在按下 Del 键时调用):
procedure TfmSrchRec.imgGridKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
x, p: Integer;
AFormat: Word;
AData: THandle;
APalette: HPalette;
begin
x := imgGrid.ItemIndex;
p := StrToInt(imgGrid.Items.Strings[x]);
if (x = -1) then
Exit;
if (UpCase(Char(Key)) = 'C') and (Shift = [ssCtrl]) then
begin
// Clipboard.Assign(imgGrid.Images[imgGrid.ItemIndex])
TBitmap(imgGrid.Images[x]).Dormant;
TBitmap(imgGrid.Images[x]).SaveToClipboardFormat(AFormat, AData, APalette);
Clipboard.SetAsHandle(AFormat, AData);
end
else if (Key = VK_DELETE) then
begin
imgGrid.Items.Images[x].Free;
imgGrid.Items.Delete(x);
end;
end;
在表单的OnClose事件中释放内存:
procedure TfmSrchRec.FormClose(Sender: TObject; var Action: TCloseAction);
var
r: Integer;
begin
for r := imgGrid.Count - 1 downto 0 do
imgGrid.Items.Images[r].Free;
end;
问题在于:
从网格中删除图像后,如果该图像是最后剩余的图像,则关闭程序将产生以下错误消息:
---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:
61 - 68 bytes: Unknown x 1
---------------------------
OK
---------------------------
如果在关闭应用程序之前网格中有剩余图像,则不会发生错误。我在项目启动时(在DPR文件中)ReportMemoryLeaksOnShutDown := True
。
我猜这个错误与组件的代码有关,而不是我使用它的方式。我希望TAwImageGrid组件作者NGLN可以看看这个问题并提供答案,但其他德尔福大师也欢迎。
链接:
TAwImageGrid组件源官方主页: https://svn.apada.nl/svn/NLDelphi-opensource/ngln/AwImageGrid/
StackOverflow问题,它提供了对组件的良好介绍: Looking for a custom image grid
答案 0 :(得分:2)
我可以重现您的发现并将其视为一个错误。
在制作组件时,我从D7复制了TStringList
的实现,即使用指向不存在的大小固定数组的指针来存储项目的内部存储。奇怪的是,我找不到它的缺陷,但是D7的TStringList
实现并没有产生这个bug。我想它可以做explained here。
我看到XE2中TStringList
的实现已更改为使用动态数组。当我将组件代码更改为相同的设计时,内存泄漏就消失了。所以我也会更改开源代码,但暂时你可以自己做。