Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 689
  • Last Modified:

How to add Font Property to new component?

I am writing a new component. I want to have  font propery initialized to a default and then changeable from Object Inspector. Can I get an example code on how to initialize? Do I need to free it in destructor as well?

I tried both with no initialization and with initialization but it doesn't work properly. In case of nil, I get can't assign nil from Object Inspector. If I intitialize, I get access violations from IDE.

Please help!
Sanjay
0
skanade
Asked:
skanade
  • 4
  • 4
  • 2
1 Solution
 
kjtengCommented:
1. declare a tfont field in the private section (fMyFont)
2. declare a corresponding property in published section (Myfont)
3. create fMyFont in the constructor
4. destroy fMyFont before calling inherited destructor

sample:

unit Test;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  My = class(TComponent)
  private
    { Private declarations }
    fMyFont: TFont;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor create( aOwner: tComponent); override;
    destructor destroy; override;
  published
    { Published declarations }
    property Myfont: TFont read fMyFont write fMyFont;
  end;

procedure Register;

implementation

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

constructor my.create( aOwner: tComponent);
begin
  inherited create( aOwner);
  fMyFont:= TFont.create;
end;

destructor my.destroy;
begin
  fMyFont.destroy;
  inherited destroy;
end;

end.

0
 
JimBob091197Commented:
Hi

If your component inherits from a TControl (i.e. any "visible" Delphi control) then you can add the following to the published section:  (This works because font is already declared in the Protected section of TControl.)

TMyComponent = class(...)
private
...
public
...
published
  property Font;
end;

If your component does NOT inherit from TControl (e.g. inherits directly from TComponent) then you have to add the font yourself.

E.g.
type
  TMyNewComp = class(TComponent)
  private
    FFont: TFont;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Font: TFont read FFont write SetFont;
  end;

constructor TMyNewComp.Create(AOwner: TComponent);
begin
  inherited;
  FFont := TFont.Create;
end;

destructor TMyNewComp.Destroy;
begin
  FFont.Free;
  inherited;
end;

procedure TMyNewComp.SetFont(Value: TFont);
begin
  FFont.Assign(Value);
end;

Cheers,
JB
0
 
JimBob091197Commented:
(Sorry kjteng, didn't see your answer when I submitted my comment.  -JB)
0
Get 10% Off Your First Squarespace Website

Ready to showcase your work, publish content or promote your business online? With Squarespace’s award-winning templates and 24/7 customer service, getting started is simple. Head to Squarespace.com and use offer code ‘EXPERTS’ to get 10% off your first purchase.

 
kjtengCommented:
Not a problem.
As you have mentioned, Skanade might just want to publish an inherited font property only. I have omitted that.
0
 
skanadeAuthor Commented:
Guys,

Thank you for taking time to give full code. However, I have exactly the same code and it doesn't work. I'll try once more and let you know.

Last time I tried it, it failed to retain the font that I changed from Object Inspector. Also, I started getting access violations from IDE. I even tried initializing the font to a particular name and size. No success.

0
 
skanadeAuthor Commented:
Sorry, I tested again. As I said in my last comment, this is the exact code I am using and it doesn't work in Object Inspector. My component is inherited from TComponent. Rest is same as here.

As soon as I press Font in Object Inspector, I get the font dialog only for the first time. Then, if I change the font and press OK, it closes. After that if I press Font again to check whether it changed it, I start getting access violations in VCL30. You can try it yourself.

Thanks,
Sanjay
0
 
skanadeAuthor Commented:
CORRECT ANSWER:
FYI, here is the edited correct answer which I got from the Delphi newsgroup:

I need to go via a SetFont method where I do this:

        SanjayControl.Font := ObjectInspectorFont;

    After doing the assignment, the Object Inspector will
    free its TFont instance. If your property doesn't have a
    write method, this means that your property will point to
    the Object Inspector's instance, which has been freed,
    which results in an Access Violation. This is a frequent
    cause of AVs in new components.

    With a property write method, we perform a "deep-copy"
    of the properties via the Assign method. This copies the
    property values from the ObjectInspectorFont instance to
    our property, which is  exactly what we want.}
  FDefaultFont.Assign(Value);

0
 
JimBob091197Commented:
Hi skanade

You will notice that in my ORIGINAL comment I declared a property like this:
  property Font: TFont read FFont write SetFont;

It uses a procedure "SetFont" which does exactly what you are now doing, i.e. "Assign":
  procedure TMyNewComp.SetFont(Value: TFont);
  begin
    FFont.Assign(Value);
  end;

So, when you said, "However, I have exactly the same code," you must be referring to kjteng's code, not mine???

Regards,
JB
0
 
skanadeAuthor Commented:
JB,

Sorry, I didn't notice the SetFont in your code. The extra comments put in by TeamB member in Delphi newsgroup forced my attention to it.

If you just put a dummy proposed answer, I'll be glad to give you the points as your solution would have worked for Object Inspector which I really was looking for.

Thanks!
Sanjay
0
 
JimBob091197Commented:
Hi Sanjay,

Usually if a published property is an object you will use "Assign" if you want a "copy" of it.  Thus you will need a Set method (e.g. SetFont) when you declare your property:
  property Font: TFont read FFont write SETFONT;

As you said, if you don't use Assign you will have 2 font variables pointing to ONE instance of the font, but both font variables will try to free the SINGLE instance, hence the access violation.

Cheers,
JB
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get 10% Off Your First Squarespace Website

Ready to showcase your work, publish content or promote your business online? With Squarespace’s award-winning templates and 24/7 customer service, getting started is simple. Head to Squarespace.com and use offer code ‘EXPERTS’ to get 10% off your first purchase.

  • 4
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now