Delphi7Personal EAccessViolation 同时创建从 TImage 派生的组件

Posted

技术标签:

【中文标题】Delphi7Personal EAccessViolation 同时创建从 TImage 派生的组件【英文标题】:Delphi7Personal EAccessViolation while creating component derived from TImage 【发布时间】:2013-06-15 08:07:07 【问题描述】:

我有一个任务是在 Delphi 中创建一个游戏,因为棋盘的大小是 7x7,我想通过从 TImage 派生我自己的组件来完成。由于我想在数组中获得板上所有图块的位置,并且我想使用 Create 方法来做到这一点,但是每当我尝试时,我在调用 .Create(self) 时遇到了 EAccessViolation

这是我的组件的代码:

        unit iles1;

       interface

         SysUtils, Classes, Controls, ExtCtrls;

type
  Tiles1 = class(TImage)
  private
      FPlayer:Boolean; //determines whether it is an empty field or a player
      FTeam:Boolean;   //determines the team the tile belogns to
      FBall:Boolean;   //posession of the ball
      FBackLight : whether it is available to interact  with this component,
      with the method on click after one of the tiles has already been chosen,
      if it is not lit but belongs to the same team, it is flagged as chosen
      but not as lit, this field is used to determine whether i can pass a ball
      to this direction or swap places with other player from the same team
      FBackLight:Boolean;
      FChosen:Boolean; //whether the player decided to click on it
      FPostion determines where it is in a table, it ranges from
      36 to 0 where  its position divided by 10 determines the column
      and position mod 10 determines the row
      FPosition:Byte;
     Private declarations 
  protected
     Protected declarations 
  public
     constructor Create(AOwner : TComponent);  override;
     Public declarations 
  published
     property Team: boolean
        read FTeam
        write FTeam;
     property Ball: boolean
       read FBall
       write FBall;
     property Player:boolean
       read FPlayer
       write FPlayer;
     property BackLight:boolean
       read FBackLight
       write FBackLight;
     property Chosen:boolean
      read FChosen
      write FChosen;
     property Position:byte
      read FPosition
      write FPosition;
     end;

     property Ball: Boolean;
     //read FHasBall
     //write FSetBall;
     end;
     Published declarations 

procedure Register;

implementation
procedure Register;
begin
  RegisterComponents('Samples', [Tiles1]);
end;

Creator procedure calling the Timage creator
and setting parent to self(impossible here, then i will do it in
 main window), visible to true

constructor Tiles1.Create(AOwner:TComponent); 
begin
  inherited;
   FPlayer:=false;
   FTeam:=false;
   FBall:=false;
   FBackLight:=false;
   FChosen:=false;
   FPosition:=0;
 end;
end.

这里我有使用它的主菜单方法:

procedure TForm1.FormCreate(Sender: TObject);
var x,y:Integer;
begin
  for y:=1 to INAROW do begin
    for x:=1 to INAROW do begin
      tiles[x,y].Create(self);
      tiles[x,y].Parent:=self;
      tiles[x,y].Visible:=true;
      tiles[x,y].Top:=(y-1)*(GAPBETWEEN+TILES1HEIGHT)+GAPTOP;
      tiles[x,y].Left:=GAPLEFT+(x-1)*(GAPBETWEEN+TILES1WIDTH);
      tiles[x,y].Width:=TILES1WIDTH;
      tiles[x,y].Height:=TILES1HEIGHT;
      tiles[x,y].Position:=10*x+y;
      tiles[x,y].BackLight:=false;
      tiles[x,y].Ball:=false;
      tiles[x,y].Player:=false;
      tiles[x,y].Chosen:=false;
     end;
  end;
  setAlphaTeam;
  setBetaTeam;
  setTiles;
end;

【问题讨论】:

@mbratch:Bzzt!错误的答案。 :-) inherited; 的工作原理完全相同,如果构造函数具有相同的签名,则会自动将 AOwner 传递给祖先。 @KenWhite 好的,抱歉。我见过的所有例子都是明确的。 @mbratch:没问题。我只是想纠正你对这个问题的误解。 (请注意我之前评论中的 :-)。) 这种设计可能会让你的生活更加艰难。画整个板子会容易得多。带有您自己的绘画事件或绘画方法的单个绘画框甚至是一个空表单可能是最好的。 同意大卫关于实现板而不是瓷砖形式的观点。例如,如果单击一个图块将其选中,则需要连接 49 个处理程序,但如果您有一个带有一个 OnClick 的板,然后使用坐标来确定哪个图块。在绘画方面也可以得到很多的效率,可以减少闪烁等 【参考方案1】:
tiles[X,Y] := Tiles1.Create(self);

假设tiles是一个Tiles1数组。

构造函数实际上是类方法,您在类而不是实例上调用它们。

由于tiles[X,Y] 为nil,您遇到了访问冲突。如果您注释掉了创建行,您会尝试设置父属性。

【讨论】:

感谢您的帮助,我完全忘记了这件事,因为我对 Delphi 没有太多经验...

以上是关于Delphi7Personal EAccessViolation 同时创建从 TImage 派生的组件的主要内容,如果未能解决你的问题,请参考以下文章