TreeView项和数据包含文件名,数据包含TBitmap。我的问题是以某种方式保存树视图中的项目和数据,因此可以在一个线程中访问项目和数据。如果可以,在保存项目和数据后,我可以访问线程中的项目和数据,而不是在Synchronize中访问它。由于在同步中访问GUI TreeItems和Data,因此现在编写的代码太慢了。
if not Terminated then
begin
Synchronize(
procedure
var
i: integer;
begin
for i := 1 to Form1.TreeView1.Items.Count - 1 do
begin
{ get the bitmap }
iImageEnIO.WIAParams.ProcessingBitmap := iImageEnIO.IEBitmap;
{ The following line prevents me from accessing the TreeView data in a thread }
iImageEnIO.WIAParams.Transfer(TIEWiaItem(Form1.TreeView1.Items[i].Data), False);
{ Set the filename }
iFilename := Form1.TreeView1.Items[i].Text + '.jpg';
{ Add the image to the iIEImageList }
iIndex := iIEImageList.AppendImageRef(TIEBitmap.Create(iImageEnIO.IEBitmap), iFileName);
iIEImageList.Filename[iIndex] := iFileName;
end;
end);
线程代码访问线程中的位图本身效果很好,但是如果我可以将获取位图的代码移动到线程而不是在Synchronize中会更好。所以我的问题是“有没有办法在Synchronize中保存树视图项和数据,以便可以在Synchronize之外的线程中访问它?”
iImageEnIO.OnProgress := ImageEnProcProgress;
iImageEnIO.OnFinishWork := ImageEnProcFinishWork;
{ Get the bitmap from the imagelist and save the image in the thread }
iCount := iIEImageList.ImageCount;
for j := 0 to iCount-1 do
begin
{ get the filename from the string list }
iFilename := iIEImageList.Filename[j];
{ attach the iIEBitmap2 to iImageEnIO }
iImageEnIO.AttachedIEBitmap := iIEImageList.Image[j];
iPath := IncludeTrailingPathDelimiter(iFolder) + iFilename;
iImageEnIO.SaveToFile(iPath);
end;
我希望我已经正确地提出了我的问题,很明显我想尝试做什么。
答案 0 :(得分:3)
我想把它转过来。您想知道在执行线程方法时如何从GUI控件读取数据。这是一个基本的设计缺陷。问题的解决方案将涉及根本不尝试这样做。
树视图不应该是数据的所有者。它是一个GUI控件,应该只显示数据视图。数据应保存在未绑定到VCL线程规则的结构中。一旦将数据结构与GUI分离,您的问题就变得微不足道了。一旦达到这一点,就没有问题需要解决。
那么,你需要什么样的结构?虽然它存储在树形视图中,但它似乎是一个平面列表。将其存储在TList<T>
容器中。您对T
使用了什么?嗯,这只是每个项目所需的信息。这可能是一个记录。或者它可以是一个班级。如果您在项类型中持有非值类型对象,那么类可能更好。在这种情况下,TObjectList<T>
更适合。所以,它看起来像这样:
type
TItem = class
private
FFileName: string;
FBitmap: TBitmap;
end;
然后你的容器只是TObjectList<TItem>
。像这样实例化:
FItems := TObjectList<TItem>.Create(True);
True
适用于OwnsObjects
参数。这意味着当您从容器中删除项目或删除容器时,项目将被销毁。
此时,您可以通过迭代容器来填充树视图,并创建表示项目的节点。
然后,当您的线程需要对数据进行操作时,它可以引用与GUI控件分离的FItems
。
故事的寓意是你不应该使用GUI控件作为主要数据容器。