Solved

How to add Font Property to new component?

Posted on 1998-06-02
10
533 Views
Last Modified: 2013-12-03
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
Comment
Question by:skanade
  • 4
  • 4
  • 2
10 Comments
 
LVL 2

Expert Comment

by:kjteng
ID: 1349815
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
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1349816
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
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1349817
(Sorry kjteng, didn't see your answer when I submitted my comment.  -JB)
0
 
LVL 2

Expert Comment

by:kjteng
ID: 1349818
Not a problem.
As you have mentioned, Skanade might just want to publish an inherited font property only. I have omitted that.
0
 

Author Comment

by:skanade
ID: 1349819
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:skanade
ID: 1349820
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
 

Author Comment

by:skanade
ID: 1349821
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
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1349822
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
 

Author Comment

by:skanade
ID: 1349823
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
 
LVL 5

Accepted Solution

by:
JimBob091197 earned 50 total points
ID: 1349824
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

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now