Solved

Saving a fonts properties

Posted on 2001-08-15
10
255 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
[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
  • 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
Independent Software Vendors: 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!

 
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
 
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

Technology Partners: 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!

Question has a verified solution.

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

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
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…
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…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

717 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