Opening streams
Streams contain the raw data of an OLE object. You would not
want to alter a stream created by a server application. However,
you can add your own streams to storage files. These streams can
store information about the storages. You can write streams that
provide labels for each storage or write a stream that lists the
members of the storage.
To access a stream in an OLE storage file, you define a stream
variable and instantiate it. Then you open a stream from a storage
that has already been opened. Opening a stream establishes a connection
between the stream variable and the stream data within a storage.
The following code declares and creates OLEStorage and OLEStream variables,
opens the storage, and then opens the stream:
1 |
integer result<br>OLEStorage stg_pic<br>OLEStream stm_pic_label<br>/***************************************************<br>Allocate memory for the storage and stream variables<br>***************************************************/<br>stg_pic = CREATE OLEStorage<br>stm_pic_label = CREATE OLEStream<br>/***************************************************<br>Open the storage and check the return value<br>***************************************************/<br>result = stg_prod_pic.Open("picfile.ole")<br>IF result <> 0 THEN RETURN<br>/***************************************************<br>Open the stream and check the return value<br>***************************************************/<br>result = stm_pic_label.Open(stg_prod_pic, &<br>   "pic_label", stgReadWrite!)<br>IF result <> 0 THEN RETURN |
PowerBuilder has several stream functions for opening and
closing a stream and for reading and writing information to and
from the stream.
Function |
Result |
---|---|
Open |
Opens a stream into the specified OLEStream |
Length |
Obtains the length of the stream in bytes. |
Seek |
Positions the read/write pointer |
Read |
Reads data from the stream beginning |
Write |
Writes data to the stream beginning at If the pointer is not at the end, Write overwrites |
Close |
Closes the stream, breaking the connection |
Example: writing and reading streams
This example displays a picture of a product in the OLE control ole_product when
the DataWindow object dw_product displays
that product’s inventory data. It uses the file constructed
with the utility application described in the earlier example (see “Example: building
a storage”). The
pictures are stored in an OLE storage file, and the name of each
picture’s storage is also the product identifier in a database
table. This example adds label information for each picture, stored
in streams whose names are the product ID plus the suffix _lbl.
Figure 19-6 shows
the structure of the file.
Figure 19-6: OLE storage file structure
The example has three scripts:
-
The window’s Open event script opens the storage
file and retrieves data for the DataWindow object. (Note that the
application’s Open event connects to the database.) -
The RowFocusChanged event of the DataWindow object
displays the picture. It also opens a stream with a label for the
picture and displays that label in a StaticText. The name of the
stream is the product identifier plus the suffix _lbl.If the label is empty (its length is zero), the script writes
a label. To keep things simple, the data being written is the same
as the stream name. (Of course, you would probably write the labels
when you build the file and read them when you display it. For the
sake of illustration, reading and writing the stream are both shown
here.) -
The window’s Close event script saves the
storage file and destroys the variable.
The OLEStorage variable stg_prod_pic is
an instance variable of the window:
1 |
OLEStorage stg_prod_pic |
The script for the window’s Open event is:
1 |
integer result<br>stg_prod_pic = CREATE OLEStorage<br>result = stg_prod_pic.Open( is_ole_file) |
The script for the RowFocusChanged event of dw_prod is:
1 |
integer result<br>string prodid, labelid, ls_data<br>long ll_stmlength<br>OLEStream stm_pic_label<br>/***************************************************<br>Create the OLEStream variable.<br>***************************************************/<br>stm_pic_label = CREATE OLEStream<br>/***************************************************<br>Get the product id from the DataWindow.<br>***************************************************/<br>this.Object.prod_id[currentrow]<br>/***************************************************<br>Open the picture in the storage file into the<br>control. The name of the storage is the product id.<br>***************************************************/<br>result = ole_prod.Open(stg_prod_pic, prodid)<br>IF result <> 0 THEN RETURN<br>/***************************************************<br>Construct the name of the product label stream and<br>open the stream.<br>***************************************************/<br> <br>labelid = prodid + "_lbl"<br>result = stm_pic_label.Open( stg_prod_pic, &<br>   labelid, stgReadWrite! )<br>IF result <> 0 THEN RETURN<br>/***************************************************<br>Get the length of the stream. If there is data<br>(length > 0), read it. If not, write a label.<br>***************************************************/<br>result = stm_pic_label.Length(ll_stmlength)<br>IF ll_stmlength > 0 THEN<br>   result = stm_pic_label.Read(ls_data)<br>   IF result <> 0 THEN RETURN<br>   // Display the stream data in st_label<br>   st_label.Text = ls_data<br>ELSE<br>   result = stm_pic_label.Write( labelid )<br>   IF result < 0 THEN RETURN<br>   // Display the written data in st_label<br>   st_label.Text = labelid<br>END IF<br>/****************************************************<br>Close the stream and release the variable's memory.<br>***************************************************/<br>result = stm_pic_label.Close()<br>DESTROY stm_pic_label |
The script for the window’s Close event is:
1 |
integer result<br>result = stg_prod_pic.Save()<br>DESTROY stg_prod_pic |