Solved

Saving a fonts properties

Posted on 2001-08-15
10
247 Views
Last Modified: 2013-12-02
Hi,

I have a record the among other contains a font.

TRecType = record
  ...
  font : TFont;
end;

I'm trying to save the TRecType in a filestream, but when I reload it none of the font properties are restored.

My code look something like this :

Saving :
---
Rec : TRecType;
F : TFileStream.Create( 'filename', fmOpenWrite );
F.write( Rec, SizeOf(Rec) );
F.Destroy;
---

And when I reload the record :
---
Rec : TRecType;
Rec.Font.create;
F : TFileStream.Create( 'filename', fmOpenRead );
F.read( Rec, SizeOf(Rec) );
F.Destroy;
---

Howcome the font props are not loaded, and how can I do this.

Regards,

Johnny
0
Comment
Question by:JustinCase
  • 5
  • 5
10 Comments
 
LVL 9

Expert Comment

by:ITugay
ID: 6388002
Hi JustinCase,

"Howcome the font props are not loaded" - because you saved memory address where Font located instead of it's property.

Can you be more specific? How Rec.Font created? It's important to know to save and load font properly.

------
Igor.
0
 

Author Comment

by:JustinCase
ID: 6388057
Well, the record is declared somewhat as above (though the record contains other records. As this :

TRecType1 = record
  ... (ints and strings)
  font : TFont;
end;
 

TRecType2 = record
  ... (ints and strings)
  props : TRectType1;
end;

--------


In my units private interface I have declared

Setup : TRecType2;


In my Forms OnCreate Event I initialize as this :

Setup.props.font := TFont.Create;

-----------

And when assigning style and color to Setup.props.font I use a TFontDialog and assign like this :

Setup.props.font := FormDialog.Font;

-----------

Is this enough info ? I'll gladly provide more, but I do not know what. I've never worked with streams before.

/Johnny

0
 

Author Comment

by:JustinCase
ID: 6388167
Oh, I should properpluy mention that I save as the record like this :

F.Write( Setup, SizeOf(Setup) );
0
 
LVL 9

Expert Comment

by:ITugay
ID: 6388220
Hi JustinCase,

I think that way you use to store your data is not good enought. First of all it would be good to convert your record to class and write somemethods to store and load from/to stream.

Anyway, you should store members of your record one by one, otherwise you can override font address.

Here is sample how to write/read font's properties to/from stream:


type
   //  class to access protected TWriter.WriteProperties method
 TXWriter = class(TWriter)
 end;

  // class to access protected TReader.ReadProperty method
 TXReader = class(TReader)
 end;

// write Font's properties to the stream
procedure WriteFontToStream(Font: TFont; Stream: TStream);
var
  Writer: TXWriter;
begin
  Writer := TXWriter.Create(Stream, 1024);
  Writer.WriteListBegin;
  Writer.WriteProperties(Font);
  Writer.WriteListEnd;
  Writer.Free;
end;


// read Font's properties from stream
// Font must be created before!!!
procedure ReadFontFromStream(Font: TFont; Stream: TStream);
var
  Reader: TXReader;
begin
  Reader := TXReader.Create(Stream, 1024);
  Reader.ReadListBegin;
  try
    while not Reader.EndOfList do
      Reader.ReadProperty(Font);
    Reader.ReadListEnd;
  finally
    Reader.Free;
  end;
end;

------
Igor.
0
 

Author Comment

by:JustinCase
ID: 6388309
Thanks Igor,

I did not know of the TWriter/reader classes. I'll read up on it today, and then I'll properply have some questions to your example when I test it.

Thanks,
/Johnny
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 9

Expert Comment

by:ITugay
ID: 6388349
OK.

But there may be problem. WriteProperties method doesn't saves property that has default for component value. So, only modifyed values are stored and loaded. Let say if your Font.Color property = clWindowText then it will not be stored. As result it will not restore Font.Color property changed by user to clRed. To avoid of this situation it is necessary to store/load all properties. Seems you have to write your own mechanism to store/load properties.

------
Igor
0
 

Author Comment

by:JustinCase
ID: 6391928
Hi Igor,

Honestly I cannot find head nor tail in this.

TWriter does not have a WriteProperties method. (I use Delphi4) It does however have a WriteProperty method. But the method looks like this :
WriteProperty( Instance: TPersistent; PropInfo: TPointer);
I do not know how to assign this pointer to the the font properties and WritePropery is not documented in the helpfile. But this should not be a lesson in pointers.

I found something else though.

If I create a TXFont class, I can assign a TFiler and read/write through it.

From the helpfile :
"Provides an interface for a method that reads and writes otherwise unpublished data."


I did like this :
TXFont = class( TFont )
end;

Font := TXFont.Create;
Font.Assign( Setup.props.Font );
Font.DefineProperties( Writer );

But I cannot figure out how to get the writer to read and write the data.

Am I on the wrong track here ?? This is very much unchartered waters for me.
0
 
LVL 9

Accepted Solution

by:
ITugay earned 100 total points
ID: 6391963
OK, let make your life easy.

procedure SaveFont(F: TFont; S: TStream);
var
  W: TWriter;
begin
  W := TWriter.Create(S, 1024);
  W.WriteInteger(Integer(F.CharSet));
  W.WriteInteger(F.Color);
  W.WriteInteger(F.Height);
  W.WriteString(F.Name);
  W.WriteInteger(Integer(F.Pitch));
  W.WriteInteger(F.Size);
  W.Free;
end;

procedure LoadFont(F: TFont; S: TStream);
var
  R: TReader;
begin
  R := TReader.Create(S, 1024);
  F.CharSet := TFontCharSet(R.ReadInteger);
  F.Color := R.ReadInteger;
  F.Height := R.ReadInteger;
  F.Name := R.ReadString;
  F.Pitch := TFontPitch(R.ReadInteger);
  F.Size := R.ReadInteger;
  R.Free;
end;

0
 

Author Comment

by:JustinCase
ID: 6391997
Thanks,

I still want to understand though.

Can you suggest any reading ? Or maybe a tutorial link or the like.

Again thanks for the help,
Johnny
0
 
LVL 9

Expert Comment

by:ITugay
ID: 6392142
Hi Johny,

thanx for the points with "A" grade.

reading....
to tell you trust I prefer to explore VCL source code. Most of my knowelege is from there. Really :-)

Regards,
Igor.

PS: if you have some question, then you can ask me here or directly  igor@novell.kz
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

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…
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…
This video discusses moving either the default database or any database to a new volume.
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…

747 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

10 Experts available now in Live!

Get 1:1 Help Now