Solved

Simple OOP question from OOP-newbie

Posted on 1997-09-10
8
164 Views
Last Modified: 2013-11-23
I don't now how to perform this basic OOP operation:

I have a object called: BLA
BLA has a public field FONT of type TFONT

Somewhere in a procedure or 'global' a the unit level
I declare a variable
var GETIT: TFont;

Now I want to do this:
I want to copy all the VALUES (in one assignmentstatement)
of BLA.FONT to GETIT (that is Style and Color and Size and
Name and so forth)

1) GETIT:=BLA.FONT works, but when I change e.g.
GETIT.SIZE, BLA.FONT.SIZE will change as well, and I
don't want that. I want a value assignment not a
reference assignment.

2) GETIT:=ASSIGN(BLA.FONT) doesn't work, because BLA.FONT
isn't accepted as a type.

3) GETIT.Style:=BLA.FONT.Style;
   GETIT.Name:=BLA.FONT.NAME etc, works but I think
   I shouldn't have to be typing so much assignments.

Ofcourse, it can be done faster (being totally new
to OOP).
How can I do this? (DO NOT BE AFRAID TO USE TOO MANY
WORD WHILE EXPLAINING, I'M RATHER A NEWBIE).

0
Comment
Question by:fritsvee
8 Comments
 
LVL 3

Expert Comment

by:mirek071497
ID: 1344579
This is not OOP problem but problem with implementation cpecific knowledge.

You must use Assign in other Way;

BLA.Font.Assign( GetTT ) or GetTT.Assign( BLA.Font );

Assign is a method of object not a global procedure.

Regards Mirek
0
 

Author Comment

by:fritsvee
ID: 1344580
Yes, you are right Mirek, I made an typing error.

But changing it to GetIT.Assign( BLA.Font )
gave me the following Delphi message:

" Project MIREK.EXE raised exception class EAccessViolation
with message 'Access violation at address 00435B90.
Read of addres 02745861'. Process stopped. Use Step or Run
to continue"

Please give more info Mirek!


0
 
LVL 2

Expert Comment

by:icampbe1
ID: 1344581
You have to create the target instance first.

Getit := TFont.Create;     {This object must exist to call its method}
Getit.Assign( Bla.Font);  {Assign the values to it}

etc... etc...

Remember to free the Getit instance when you're done.

Cheers,
Ian C.

0
 

Author Comment

by:fritsvee
ID: 1344582
Thanks mirek and Ian C. but I still get EAccess violation
after adding Get:=TFont.Create (I thought this wasn't
necessary because Delphi autocreates his standaard elements).

I tried to cut away all the irrelevant code to put an example
here: but after doing that I get another error (click
on button1) I didn't get before. I post the source here. Please help.
//---------------MAIN FORM----------------
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls,Settoop;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
  public
  end;
var
  Form1: TForm1;
  Bla: TBla;
implementation
 {$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var COPYFONT: TFONT;
begin
Bla.Create;CopyFOnt.Create;
COPYFONT.ASSIGN(Bla.FONT);
//THE ASSIGNMENT WILL BE DO DONE
//in another unit which USES Form1, I hope this doesn't
// mess up the example
end;
end.

//-----------DEFINITION OF CLASS
unit settoop;
interface
uses Forms,Windows,Inifiles, Graphics;
type
  TBla = class
  public
    Font: TFont;
    constructor Create;
  private
  end;
implementation
uses Unit1;
constructor TBla.Create;
begin
 Font:=Form1.Button1.Font;
 Font.Name:='Arial';
 Font.Size:=10;
 Font.Style:=[fsItalic];
 Font.Color:=clRed;
end;
end.

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

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Expert Comment

by:jorgen.hojdmo
ID: 1344583
This code works.
-------------------------------------------------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
      GetIt: TFont;
begin
  GetIt := TFont.Create;
  GetIt.Assign(Form1.Font);
  GetIt.Free;
end;

end.
----------------------------------------------
0
 

Author Comment

by:fritsvee
ID: 1344584
Yes it works, but that is besides the point,
so I have to reject your answer. I want to
know how I can get MY code to work.

I want to read the value of the object I've created.
Maybe this is the same to you, but it isn't to me.

Can you or anyone get my code working?
0
 
LVL 12

Accepted Solution

by:
andrewjb earned 100 total points
ID: 1344585
You don't get things automatically created, except for buttons etc. that you put on the form. These get created as the form is used.

So, you have several errors.

A variable of whatever object type is only a container that can be used to store an object. It isn't automatically an actual object, ready to be used. You have to create an object and set the variable to point to it. This is done by using a construction of the form :

VariableName := tObject.Create;

The right hand side creates the object, then assigns it to the variable.

In your example you need to do this in the tBLA object, for the font it contains

Once created, the objects must be destroyed by some point. Things like buttons can be destroyed automatically as they have 'owners' and 'parents', and they get destroyed when either the owner or parent is destroy. Other objects ( like the fonts you are creating ) must be destroyed youself, in code.

Good practice is to call the .Free method of an object that you want to destroy.

So you need to have a destructor in the tBLA object, which frees the font.


I'm not sure exactly what you were trying to do, but the code below will change the font on the button.


/***************************************/

Here is a version that works OK ( I've tried it )

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;




type
  TBla = class
  public
    Font: TFont;
    constructor Create;
    destructor Destroy; override; { Destructors should always 'override' }
  private
  end;


type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;
  Bla: TBla;

implementation
{$R *.DFM}


procedure TForm1.Button1Click(Sender: TObject);
begin
  Bla := tBla.Create;
  Button1.Font.ASSIGN( Bla.Font );
  Bla.Free; { Need to free the font, otherwise we'll eventually run out of memory! }
end;


constructor TBla.Create;
begin
  inherited Create;    { Always good practice to call inherited Create first }

  Font := TFont.Create;     { Need to create an instance of a font }

  { Now we can set some of the parameters }
 Font.Name:='Arial';
 Font.Size:=10;
 Font.Style:=[fsItalic];
 Font.Color:=clRed;
end;

destructor tBla.Destroy;
begin
  Font.Free;    { Destroy the font we created }
  inherited Destroy;  { Do any other cleaning up }
end;


end.


0
 

Author Comment

by:fritsvee
ID: 1344586
Thank you all. Everyone gave some info to the solution, but I
found andrewjb's answer most useful/explaning.

The point was: how to set of a global variabele which
font values I can copy to screenelements.



-----for those as ignorant as I am/was ----------
The error in unit 2 was
constructor TBla.Create;
begin
  Font:=Form1.Button1.Font; <- Wrong: any change to BLA.FONT
                               will get Button1.Font changed
  Font:=TFont.Create        <- Right

And Unit 1 must read:
..
var
  Form1: TForm1;
  Bla: TBla;
implementation
 {$R *.DFM}
 var GETIT: Tfont;
procedure SETVARIABELE;
begin GETIT.ASSIGN(Bla.FONT);end;
procedure TForm1.Button1Click(Sender: TObject);
begin SetVariabele;end;
procedure TForm1.FormCreate(Sender: TObject);
begin Bla:=TBla.Create; GetIt:=TFont.Create;
/// *.Free will be done someelse in FormDestroy
end;
0

Featured Post

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!

Join & Write a Comment

Suggested Solutions

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

706 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

16 Experts available now in Live!

Get 1:1 Help Now