Marus Gradinaru
Marus Gradinaru

Reputation: 3022

Why I'm getting "Access Violation" when I put another component as a property in my custom component?

I want my component to have the color properties gruped in one single Colors propery. And I've done in this way, but I'm getting "Access Violation". I don't understand why, because this is the code from many examples posted here on StackOverflow...

unit SuperList;

interface

uses Windows, Controls, Graphics, Classes, SysUtils, StdCtrls;

type

  TListColors = class(TPersistent)
  private
   FNormalBackg:TColor;
   FNormalText:TColor;
   FNormalMark:TColor;
  public
   constructor Create;
   procedure Assign(Source: TPersistent); override;
  published
   property NormalBackg:TColor read FNormalBackg write FNormalBackg default clRed;
   property NormalText:TColor  read FNormalText  write FNormalText  default clRed;
   property NormalMark:TColor  read FNormalMark  write FNormalMark  default clRed;
  end;

  TSuperList = class(TCustomControl)
  private
    FColors: TListColors;
    procedure SetListColors(const Value:TListColors);
  public
    procedure Paint; override;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Colors:TListColors read FColors write SetListColors;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Marus', [TSuperList]);
end;

//------ TListColors -----------------------------------------------------------

constructor TListColors.Create;
begin
 FNormalBackg:=clRed;
 FNormalText :=clRed;
 FNormalMark :=clRed;
end;

procedure TListColors.Assign(Source: TPersistent);
begin
 if Source is TListColors then begin
  FNormalBackg:=TListColors(Source).FNormalBackg;
  FNormalText:= TListColors(Source).FNormalText;
  FNormalMark:= TListColors(Source).FNormalMark;
 end
 else inherited;
end;

//------ TSuperList ------------------------------------------------------------

procedure TSuperList.SetListColors(const Value: TListColors);
begin
 FColors.Assign(Value);
end;

constructor TSuperList.Create(AOwner: TComponent);
begin
 inherited;
 Width:=200;
 Height:=100;
 Color:=clNone; Color:=clWindow;
 Colors:=TListColors.Create;
end;

destructor TSuperList.Destroy;
begin
 Colors.Free;
 inherited;
end;

procedure TSuperList.Paint;
begin
 Canvas.Brush.Color:=Color;
 Canvas.FillRect(Canvas.ClipRect);
end;

end.

Upvotes: 0

Views: 1040

Answers (1)

Keith Miller
Keith Miller

Reputation: 1768

In your constructor you have:

Colors:=TListColors.Create;

Change this to:

FColors:=TListColors.Create;

Your current code is calling the property setter which is trying to assign to the uninitialized FColor.

Upvotes: 7

Related Questions