首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用自定义组件的Delphi 7无效指针操作

使用自定义组件的Delphi 7无效指针操作
EN

Stack Overflow用户
提问于 2013-09-26 23:04:34
回答 1查看 870关注 0票数 0

我有一个自定义组件类,我使用它作为框架将注释和用户详细信息等加载到表单上。这个类是一个面板的子类,包含3个标签和一个备忘录.

关闭窗体或试图释放对象时,会出现“无效指针操作”错误。我知道这是因为尝试释放一个对象两次,或者访问不可用的RAM。但是,我不知道怎么解决它。它阻碍了我的很多,因为我必须加载不同的评论对不同的主题,我不能,直到我澄清了当前的评论形式。

下面是与类相关的代码:

代码语言:javascript
复制
    type
      TSkeleton = class(TPanel)
        private
        fName : TLabel;
        fStudNo : TLabel;
        fTimeAndDate : TLabel;
        fComment : TMemo;
     public
       Constructor Create (AOwner: TComponent); overload; override;
       constructor Create(AOwner:TForm; sName, sStudNo, sTime, sDate, sComment: string; ComCount: integer); overload;
 end;
{ TSkeleton }

constructor TSkeleton.Create(AOwner: TComponent);
begin
//
end;

constructor TSkeleton.Create(AOwner: TForm; sName, sStudNo, sTime, sDate,
  sComment: string; ComCount: integer);
begin
  inherited Create(AOwner);
  Parent := AOwner;
  Width := 800;
  Height := 250;
  Top := 448+((ComCount-1)*250);
  Left := 16;
  BevelInner := bvSpace;
  BevelOuter := bvLowered;

  fName := TLabel.Create(fName);
  self.InsertControl(fName);
  with fName do
  begin
   Caption := sName;
   Font.Name := 'Garamond';
   Font.Size  := 30;
   Left := 7;
   Top := 4;
  end;

  fStudNo := TLabel.Create(fStudNo);
  self.InsertControl(fStudNo);
    with fStudNo do
      begin
       Caption := sStudNo;
       Font.Name := 'Garamond';
       Font.Size  := 15;
       Left := 15;
       Top := 52;
      end;

  fTimeAndDate := TLabel.Create(fTimeAndDate);
  self.InsertControl(fTimeAndDate);
    with fTimeAndDate do
      begin
       Caption := sTime + ' ' + sDate;
       Font.Name := 'Garamond';
       Font.Size  := 20;
       Left := 583;
       Top := 4;
      end;

  fComment := TMemo.Create(fComment);
  self.InsertControl(fComment);
    with fComment do
      begin
       Lines.Add(sComment);
       Font.Name := 'Garamond';
       Font.Size  := 12;
       Left := 152;
       Top := 56;
       Height := 161;
       Width := 633;
       ReadOnly := True;
       ScrollBars := ssVertical;
      end;

end;

如果您希望看到使用的其他代码(读取文本文件、创建对象数组等),请这样说。这与全班没有直接关系,所以我不认为这是必要的。

提前谢谢你。

编辑:基于@Remy的代码和@NGLN的评论,我决定发布一切必要的信息。

在根据@Remy的代码修复了类之后,我仍然收到了错误信息。这使我相信错误是我使用类的地方,特别是在我正在创建的对象数组中。

以前,我的代码是

代码语言:javascript
复制
  for i := 0 to ComCount-1 do
  begin
    fArrObjects[i+1] :=  TSkeleton.Create(TargetForm);
    with fArrObjects[i+1] do
    begin
      Parent := TargetForm;
      TheName := fArrComments[i][0];
      StudNo := fArrComments[i][1];
      Time := fArrComments[i][2];
      Date := fArrComments[i][3];
      Comment := fArrComments[i][4];
      ComCount := i+1;
    end;

改变

代码语言:javascript
复制
fArrObjects[i+1]

代码语言:javascript
复制
 fArrObjects[i]

解决了这个问题。

谢谢你@雷米纠正课堂上的错误。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-27 00:19:55

您的代码有一些问题。

代码语言:javascript
复制
Parent := AOwner;

不要从构造函数内部设置Parent。在对象完全构建之后,调用方有责任设置Parent

您没有定义析构函数,而是使用nil所有者创建子对象。TSkeleton应该是业主,如:

代码语言:javascript
复制
//fName := TLabel.Create(fName);
fName := TLabel.Create(Self);
...

您不应该直接调用InsertControl()。使用Parent属性代替,例如:

代码语言:javascript
复制
//self.InsertControl(fName);
fName.Parent := Self;
...

你为什么有两个构造函数?您的重写构造函数不会执行任何操作,甚至不会调用基本构造函数,并且您的自定义构造函数也不会在设计时被调用(除非您有其他代码可以编程地创建TSkeleton实例)。我建议您摆脱自定义构造函数,并根据需要公开已发布的属性来操作子控件。

最后,由于您正在创建子组件,您应该通过TComponent.SetSubComponen()将它们标记为子组件。

说到这里,尝试更像这样的东西:

代码语言:javascript
复制
type
  TSkeleton = class(TPanel)
  private
    fName : TLabel;
    fStudNo : TLabel;
    fTimeAndDate : TLabel;
    fComment : TMemo;

    fTime: string;
    fDate: string;
    fComCount: Integer;

    function GetTheName: string;
    procedure SetTheName(const AValue: string);
    function GetStudNo: string;
    procedure SetStudNo(const AValue: string);
    procedure SetTime(const AValue: string);
    procedure SetDate(const AValue: string);
    function GetComment: string;
    procedure SetComment(const AValue: string);
    procedure SetComCount(AValue: integer);

  public
    constructor Create (AOwner: TComponent); override;

  published
    property TheName: string read GetTheName write SetTheName;
    property StudNo: string read GetStudNo write SetStudNo;
    property Time: string read fTime write SetTime;
    property Date: string read fDate write SetDate;
    property Comment: string read GetComment write SetComment;
    property ComCount: integer read fComCount write SetComCount;
  end;

代码语言:javascript
复制
constructor TSkeleton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  Width := 800;
  Height := 250;
  Left := 16;
  BevelInner := bvSpace;
  BevelOuter := bvLowered;

  fName := TLabel.Create(Self);
  fName.SetSubComponent(True);
  fName.Parent := Self;
  fName.Font.Name := 'Garamond';
  fName.Font.Size  := 30;
  fName.Left := 7;
  fName.Top := 4;

  fStudNo := TLabel.Create(Self);
  fStudNo.SetSubComponent(True);
  fStudNo.Parent := Self;
  fStudNo.Font.Name := 'Garamond';
  fStudNo.Font.Size  := 15;
  fStudNo.Left := 15;
  fStudNo.Top := 52;

  fTimeAndDate := TLabel.Create(Self);
  fTimeAndDate.SetSubComponent(True);
  fTimeAndDate.Parent := Self;
  fTimeAndDate.Font.Name := 'Garamond';
  fTimeAndDate.Font.Size  := 20;
  fTimeAndDate.Left := 583;
  fTimeAndDate.Top := 4;

  fComment := TMemo.Create(Self);
  fComment.SetSubComponent(True);
  fComment.Parent := Self;
  fComment.Font.Name := 'Garamond';
  fComment.Font.Size  := 12;
  fComment.Left := 152;
  fComment.Top := 56;
  fComment.Height := 161;
  fComment.Width := 633;
  fComment.ReadOnly := True;
  fComment.ScrollBars := ssVertical;
end;

function TSkeleton.GetTheName: string;
begin
  Result := fName.Caption;
end;

procedure TSkeleton.SetTheName(const AValue: string);
begin
  fName.Caption := AValue;
end;

function TSkeleton.GetStudNo: string;
begin
  Result := fStudNo.Caption;
end;

procedure TSkeleton.SetStudNo(const AValue: string);
begin
  fStudNo.Caption := AValue;
end;

procedure TSkeleton.SetTime(const AValue: string);
begin
  if fTime <> AValue then
  begin
    fTime := AValue;
    fTimeAndDate.Caption := fTime + ' ' + fDate;
  end;
end;

procedure TSkeleton.SetDate(const AValue: string);
begin
  if fDate <> AValue then
  begin
    fDate := AValue;
    fTimeAndDate.Caption := fTime + ' ' + fDate;
  end;
end;

function TSkeleton.GetComment: string;
begin
  Result := fComment.Text;
end;

procedure TSkeleton.SetComment(const AValue: string);
begin
  fComment.Text := AValue;
end;

procedure TSkeleton.SetComCount(AValue: integer);
begin
  if fComCount <> AValue then
  begin
    fComCount := AValue;
    Top := 448+((FComCount-1)*250);
  end;
end;
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19040116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档