Now that we know how to open and create a DocFile, lets create
a stream and save some data to it.
Step 1: Creating a Stream
{Try to create the stream}
Hr := RootStorage.CreateStream( 'MyStream',
STGM_CREATE or STGM_READWRITE or
STGM_DIRECT or STGM_SHARE_EXCLUSIVE,
0,
0,
Stream
);
As you can see CreateStream is a member function of IStorage. The STGM flags are the same as used with StgCreateDocFile. Dont forget to check the Hr result for success.
If successful this will create a stream called MyStream in the RootStorage.
Step 2: Write some data
Well lets first get some data to write! From this point on I'll be building a sample application that will demonstrate some of the more important DocFile concepts.
So create a new Delphi project in which you can test these examples.
For this first example drop a TMemo and a TButton on the form.
| Control | Caption | Name |
| TMemo | mem_Text | |
| TButton | Save | but_Save |
What this simple application will do is save the text from the memo into a stream in the DocFile. Later on we'll read the data back from the stream.
Double click the button to start entering the OnClick code used to save the memo's text
There are as always a number of ways to accomplish anything in programming, I'll show you two methods here. There are probably quite a few more. Chose the method that best suits your needs.
Method 1:
Saving a string
Stream.Write( PChar(mem_Text.Text),
Length( mem_Text.Text ),
@iNumWritten
);
{Was all the data written?}
if( iNumWritten <> MemStream.Size ) then
begin
MessageBeep( -1 );
ShowMessage( 'Not all of data was saved' );
end;
Here the text in the memo's Lines.Text property is used to get the text as a string.
Method 2: Using a TOleStream
This section origionally showed how to use a memory stream as a tempory stream before saving the data to
the actual IStream. This method worked and was quite flexible... however there is a better way. There always
is! In this case the better method is to use a TOleStream.
My thanks to Thaddy de Koning (thaddy@cyco.nl) for bringing this class
to my attention.
TOleStream is defined in AxCtrls.pas. What it does is wrap a IStream and allow you to use the IStream just as you would any normal stream class (eg TStream, TMemoryStream, TFileStream etc..). This makes loading and saving data so much easier.
To use TOleStream you pass an open IStream as the only parameter to its constructor.
For example saving the text from a TMemo to a open IStream.
{Create a memory OleStream}
OleStream := TOleStream.Create( Stream );
{Save the memo's text to the OleStream}
mem_Text.Lines.SaveToStream( OleStream );
{Finished with the OleStream}
OleStream.Free;
I have noticed that TOleStream.Size does not work correctly for a TOleStream. It correctly returns the size of the stream, but changing the value has no effect at all! Use the normal API functions if you need to manualy resize an IStream.
The full source code (using method 2) follows, this is the procedure you would call from the button's OnClick Event
procedure CreateAndSave;
var
Hr : HResult;
Stream : IStream;
OleStream : TOleStream;
RootStorage : IStorage;
begin
{Try create the DocFile}
Hr := StgCreateDocFile( 'c:\Temp\MyDocFile.ole',
STGM_CREATE or STGM_READWRITE or
STGM_DIRECT or STGM_SHARE_EXCLUSIVE,
0,
RootStorage
);
{Was is created?}
if( not SUCCEEDED( Hr ) ) then
begin
(* Fail *)
{D2}//RootStorage.Release;
Exit;
end;
{Try to create the stream}
Hr := RootStorage.CreateStream( 'MyStream',
STGM_CREATE or STGM_READWRITE or
STGM_DIRECT or STGM_SHARE_EXCLUSIVE,
0,
0,
Stream
);
{Was is created?}
if( not SUCCEEDED( Hr ) ) then
begin
(* Fail *)
{D2}//RootStorage.Release;
Exit;
end;
{Create the OleStream}
OleStream := TOleStream.Create( Stream );
{Save the memo's text to the OleStream}
mem_Text.Lines.SaveToStream( OleStream );
{Finished with the OleStream}
OleStream.Free;
{D2}//Stream.Release;
{D2}//RootStorage.Release;
end;
I've included the .Release calls (comment out though) for the Delphi 2 users. If you're using Delphi 3 just ignore these lines.
From now on I'll be leaving out the Delphi 2 Release calls. If you are using Delphi 2 you must remember to call Release when you are finished with a IStorage or IStream.
All information on these www pages is copyright (©) 1997 Andre .v.d. Merwe And may not be copied or mirrored without my permission.