Solved

Simple OOP question from OOP-newbie

Posted on 1997-09-10
8
169 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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
 

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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …

726 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