Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix Delphi component with TFont property that gets "cannot assign NIL to a TFont" at design time?

I have started building a new component in Delphi 6 Pro. Currently it just has a single TFont published property. However, when I drop the component on a Form at design time, and click on the edit button for the "textAttr_1" property (ellipsis), I get an Exception saying "cannot assign NIL to a TFont". What am I doing wrong that is causing this error? Below is the code for the component:

unit JvExtendedTextAttributes;

interface

uses
  Windows, Messages, SysUtils, Classes, JvRichEdit, Graphics;

type
  TJvExtendedTextAttributes = class(TComponent)
  private
    { Private declarations }
  protected
    { Protected declarations }
    FTextAttr_1: TFont;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent);
  published
    { Published declarations }
    property textAttr_1: TFont read FTextAttr_1 write FTextAttr_1;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('FAVORITES', [TJvExtendedTextAttributes]);
end;

// ---------------------------------------------------------------

constructor TJvExtendedTextAttributes.Create(AOwner: TComponent);
begin
    inherited Create(AOwner);

    FTextAttr_1 := TFont.Create;
end;

// ---------------------------------------------------------------


end.
like image 374
Robert Oschler Avatar asked Sep 07 '11 21:09

Robert Oschler


1 Answers

Your main problem is that you forgot to add an override to your component's constructor. This means it is not being called because the VCL framework takes advantage of the virtual constructor of TComponent. That explains why your font instance is nil.

You also need a set method that calls Assign to copy the properties of the font, rather than replacing the instance which inevitably leads to memory corruption errors.

The VCL source has countless examples of this pattern. It looks like this:

property Font: TFont read FFont write SetFont;
...
procedure TMyComponent.SetFont(Value: TFont);
begin
  FFont.Assign(Value);
end;
like image 55
David Heffernan Avatar answered Sep 21 '22 12:09

David Heffernan