简体   繁体   English

Delphi中的timage和tlabel动态数组出现问题

[英]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的有效索引为0AttCount-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM