0

我想添加一个附件,并且每次添加附件时表单都会变长,以便为包含带有标签和一些 16X16 图像的附件信息的行腾出空间。为此,我选择使用动态数组(不确定这是否最好)。每次添加附件时,我都想创建这些对象的新实例。我的代码似乎不起作用。以下代码有什么问题?

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; 
4

1 回答 1

1

最明显的缺陷是您正在注销所有数组的末尾。例如,你写

SetLength(newImg, AttCount);

这意味着有效的索引newImg是包容性0的。AttCount-1但是然后你写

newImg[AttCount] := ...

这是一个越界访问,因为最后一个索引是AttCount-1. 您对所有阵列访问执行相同的操作。

如果您在启用范围检查的情况下进行编译,编译器将生成一个运行时错误,解释您做错了什么。

就个人而言,我认为您最好使用记录来保存您的四个组件:

TAttachmentControls = record
  Img: TImage;
  Lbl: TLabel;
  .. etc.
end;

并使用 aTList<TAttachmentControls>作为您的容器。

于 2013-02-26T11:10:14.140 回答