Board index » cppbuilder » How to save TFont * to Stream?

How to save TFont * to Stream?


2003-09-17 03:12:30 PM
cppbuilder55
I think it's a TPersistent descendant, but how to save it to disk file?
 
 

Re:How to save TFont * to Stream?

"Jiqing Tang" < XXXX@XXXXX.COM >wrote in message
Quote
I think it's a TPersistent descendant, but how to save it to disk file?
TFont is indeed a TPersistent-decendant. However, this does not imply the fact
that the object can be saved to file or stream directly.
FYI, classes derived from TPersistent can be streamed from/to a .dfm resource by
the VCL streaming system. However, this behaviour is not supported by the class
itself. The VCL streaming system mainly uses the RTTI generated for the class.
On top of that, TPersistent introduces DefineProperties() to read/write
unpublished properties. Unpublished properties are in fact properties where no
RTTI has been generated for. TPersistent-descendants can override
DefineProperties() in order to stream data for unpublished properties.
VCLs built-in streaming facilities for a class like TFont aren't readily
available for you to use. You'd better write your own functions which deal with
that. Something like;
void __fastcall SaveFontToStream(TFont* Font,TStream* S)
{
int i;
// Name
i = Font->Name.Length();
S->Write(&i, sizeof(int));
S->Write(Font->Name.c_str(), i);
// Height
i = Font->Height;
S->Write(&i, sizeof(int));
// Color
i = static_cast<int>(Font->Color);
S->Write(&i, sizeof(int));
// Style
i = 0;
if(Font->Style.Contains(fsBold)) i |= 1;
if(Font->Style.Contains(fsItalic)) i |= 2;
if(Font->Style.Contains(fsUnderline)) i |= 4;
if(Font->Style.Contains(fsStrikeOut)) i |= 8;
S->Write(&i, sizeof(int));
// write additional properties as you see fit
}
void __fastcall LoadFontFromStream(TFont* Font,TStream* S)
{
int i;
// Name
S->Read(&i, sizeof(int));
char* buf = new char[i];
S->Read(buf, i);
Font->Name = buf;
delete[] buf;
// Height
S->Read(&i, sizeof(int));
Font->Height = i;
// Color
S->Read(&i, sizeof(int));
Font->Color = static_cast<TColor>(i);
// Style
S->Read(&i, sizeof(int));
TFontStyles fs;
if(i & 1) fs << fsBold;
if(i & 2) fs << fsItalic;
if(i & 4) fs << fsUnderline;
if(i & 8) fs << fsStrikeOut;
Font->Style = fs;
// read additional properties as you see fit
}
Usage;
std::auto_ptr<TFileStream>FS(new TFileStream("C:\\font.dat",fmCreate));
SaveFontToStream( Button1->Font, FS.get() );
...
std::auto_ptr<TFileStream>FS(new TFileStream("C:\\font.dat",fmCreate));
LoadFontFromStream( Button1->Font, FS.get() );
Ralph
 

Re:How to save TFont * to Stream?

"Ralph Kazemier" < XXXX@XXXXX.COM >wrote in message
Quote
Usage;

std::auto_ptr<TFileStream>FS(new TFileStream("C:\\font.dat",fmCreate));
SaveFontToStream( Button1->Font, FS.get() );

...

std::auto_ptr<TFileStream>FS(new TFileStream("C:\\font.dat",fmCreate));
LoadFontFromStream( Button1->Font, FS.get() );
The latter should have been;
std::auto_ptr<TFileStream>FS(new TFileStream("C:\\font.dat",fmOpenRead));
LoadFontFromStream( Button1->Font, FS.get() );
Ralph
 

{smallsort}

Re:How to save TFont * to Stream?

Thx very much, I see what you mean ....
But, I think it's easier to write in this way,
void __fastcall SaveFontToStream(TFont* Font,TStream* S)
{
TWriter *Writer=new TWriter(S,1024);
Writer->WriteString(Font->Name);
Writer->WriteInteger(Font->Size);
Writer->WriteInteger(Font->Color);
i = 0;
if(Font->Style.Contains(fsBold)) i |= 1;
if(Font->Style.Contains(fsItalic)) i |= 2;
if(Font->Style.Contains(fsUnderline)) i |= 4;
if(Font->Style.Contains(fsStrikeOut)) i |= 8;
Writer->WriteInteger(i);
// write additional properties as you see fit
//etc ....
}
does it work for me? I havn't tried out myself yet ...
"Ralph Kazemier" < XXXX@XXXXX.COM >wrote in message
Quote

"Ralph Kazemier" < XXXX@XXXXX.COM >wrote in message
news:3f681522$ XXXX@XXXXX.COM ...

>Usage;
>
>std::auto_ptr<TFileStream>FS(new
TFileStream("C:\\font.dat",fmCreate));
>SaveFontToStream( Button1->Font, FS.get() );
>
>...
>
>std::auto_ptr<TFileStream>FS(new
TFileStream("C:\\font.dat",fmCreate));
>LoadFontFromStream( Button1->Font, FS.get() );

The latter should have been;

std::auto_ptr<TFileStream>FS(new
TFileStream("C:\\font.dat",fmOpenRead));
LoadFontFromStream( Button1->Font, FS.get() );


Ralph



 

Re:How to save TFont * to Stream?

I see,
I hate to write any utility class because the VCL itself is already large
enough, actually too complex for me to learn. I always expect to get things
directly from it.
But unfortunately, sometimes I fail to find a solution in VCL, and have to
do the work by myself,
Thank you very much!
"Ralph Kazemier" < XXXX@XXXXX.COM >wrote in message
Quote

"Jiqing Tang" < XXXX@XXXXX.COM >wrote in message
news:3f681903$ XXXX@XXXXX.COM ...

>does it work for me? I havn't tried out myself yet ...

I have never used TWriter directly, thus I have no idea. I see your
point,
though. I find TStream too 'low-level', so I have made wrapper class,
which
allows me to write things like;

TStreamWrapper sw( Stream );

sw << Font->Name;
sw << Font->Height;

...
AnsiString fn;

sw>>fn;
Font->Name = fn;


Ralph