使用:Delphi XE7 Update 1, TAwImageGrid, Windows 10 Professional运行在Intel酷睿i7-2820QM.
下面的代码将图片从数据库加载到网格中:
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可以看看这个问题并提供答案,但也欢迎其他Delphi专家。
链接:
TAwImageGrid组件源码官方主页:https://github.com/NGLN/AwImageGrid
StackOverflow问题,给出了一个很好的介绍组件:寻找自定义图像网格
我可以重现你的发现并认为这是一个bug。
当制作组件时,我从D7复制了TStringList
的实现,即通过使用指向不存在的固定大小数组的指针来存储项目。奇怪的是,我找不到它的缺陷,但D7的TStringList
实现并没有产生这个bug。我想它与这里解释的有关。
我看到TStringList
在XE2中的实现更改为使用动态数组。当我将组件的代码更改为相同的设计时,内存泄漏就消失了。所以我也会修改开源代码,但目前您可以自己做。