[英]Trouble with dynamic array of timage and tlabel in delphi
I want to add an attachment, and have the form grow longer each time an attachment is added, to make room for a line that holds information about the attachment with a label and some 16X16 images. 我想添加一个附件,并在每次添加附件时使表单更长,以腾出空间来容纳带有标签和一些16X16图像的附件信息。 For this I chose to use a dynamic array (not sure whether that's best).
为此,我选择使用动态数组(不确定是否最好)。 each time an attachment is added, I want to create a new instance of these objects.
每次添加附件时,我都想创建这些对象的新实例。 My code doesn't seem to work.
我的代码似乎无效。 what's wrong with the follwing code?
以下代码有什么问题?
procedure TVisionMail.AddAttachment(FileString: String);
var
I: Integer;
begin
AttCount := AttCount + 1; // increment attachment count
//set attachment file name
if (AttCount <> 0) and (edAttachment.Text <> '') then
edAttachment.text := edAttachment.text + ';';
edAttachment.text := edAttachment.text + FileString;
//move objects position down to allow space for attachment line
VisionMail.Height := VisionMail.Height + 25;
Panel1.Height := Panel1.Height + 25;
btnSend.Top := btnSend.Top + 25;
btnExit.Top := btnExit.Top + 25;
StatusMemo.Top := StatusMemo.Top + 25;
Memo1.Top := Memo1.Top + 25;
lblBody.Top := lblBody.Top + 25;
//Allocate memory for arrays
SetLength(newImg, AttCount);
SetLength(newlbl, AttCount);
SetLength(newDel, AttCount);
SetLength(newPin, AttCount);
//create new instance and set parents, positions, color, events
newImg[AttCount]:= TImage.Create(VisionMail);
with newImg[AttCount] do
begin
Parent := Panel1;
Top := Memo1.Top - 25;
Left := 408;
Height := 16;
Width := 16;
end;
newlbl[AttCount]:= TLabel.Create(VisionMail);
with newlbl[AttCount] do
begin
Parent := Panel1;
Top := newImg[I].Top + 2;
Left := 397;
Height := 3;
Width := 13;
BiDiMode := bdRightToLeft;
end;
newDel[AttCount] := TAdvToolButton.Create(VisionMail);
with newDel[AttCount] do
begin
Parent := Panel1;
Top := newImg[I].Top;
Left := 440;
Height := 16;
Width := 16;
color := clBtnFace;
colorChecked := clBtnFace;
colorDown := clBtnFace;
colorHot := clBtnFace;
OnClick := btnDelAttClick;
OnMouseEnter := btnDelAttMouseEnter;
OnMouseLeave := btnDelAttMouseLeave;
end;
newPin[AttCount] := TImage.Create(VisionMail);
with newDel[AttCount] do
begin
Parent := Panel1;
Top := newImg[I].Top;
Left := 425;
Height := 16;
Width := 16;
end;
//get Icon for extension of file
lstIcons.GetBitmap(GetIcon(ExtractFileExt
(OpenDialog1.FileName)),
newImg[AttCount].Picture.Bitmap);
newlbl[AttCount].Caption := ExtractFileName(FileString);
end;
The most obvious flaw is that you are writing off the end of all of your arrays. 最明显的缺陷是您要注销所有数组的末尾。 For example, you write
例如,你写
SetLength(newImg, AttCount);
and that means that the valid indices for newImg
are 0
to AttCount-1
inclusive. 这意味着
newImg
的有效索引为0
到AttCount-1
含)。 But then you write 但是你写
newImg[AttCount] := ...
and that is an out of bounds access because the last index is AttCount-1
. 这是一个无界访问,因为最后一个索引是
AttCount-1
。 You do the same for all your array access. 您对所有阵列访问都执行相同的操作。
If you compile with range checking enabled, the compiler will generate a runtime error that explains what you have done wrong. 如果在启用范围检查的情况下进行编译,则编译器将生成运行时错误,说明您做错了什么。
Personally I think you would be better using a record to hold your four components: 我个人认为,使用记录来保存四个部分会更好:
TAttachmentControls = record
Img: TImage;
Lbl: TLabel;
.. etc.
end;
And use a TList<TAttachmentControls>
as your container. 并使用
TList<TAttachmentControls>
作为您的容器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.