|
APGen Developer's Guide |
|
See Also: |
Pluggable Streams is a feature of Active Page Generator that allows the developer to:
APGen Output and Log objects have Stream properties that can be used to set or retrieve an object that implements the IStream interface.
In C++, the objects returned from the Stream properties can be QueryInterface()ed (using IID_IStream) to return an IStream*. The objects cannot be accessed by scripting languages or Visual Basic, because the IStream interface is not a COM automation interface. The IStream interface is described in the Microsoft Win32 SDK documentation.
If a Stream property is set to refer to an object, then the object must implement the IStream interface. If the object does not implement the IStream interface, then an error will be raised when the Stream property is set.
If custom streams are not set, then default streams are used. The default streams are streams that write to files: For example, the default Output stream writes to a file with path Output.Path. Similarly, the default Log stream writes to a file with path Log.Path.
The default streams are created automatically under the following conditions:
For example, if Output.Write() or Output.BinaryWrite() are called, and no Output.Stream
currently exists, then a stream is created that writes to the output file.
Essentially, Output.Open() is
implicitly called if no stream exists and content is generated.
Output.Close() releases the current Output stream. There is no equivalent Log object method. However, this code:
Log.Stream = Nothing
releases the Log stream, so it is equivalent to a Log.Close() method.
A reference to a stream is maintained until Output.Close() is called, the containing script is released, or the Stream property is set to point to another object.
When all references to a default stream are released, the file is closed.
The Pluggable Streams feature can be used to share streams between multiple APG scripts. This involves setting a script's Output.Stream (or Log.Stream) property to another script's Output.Stream (or Log.Stream) property.
This example uses the Output.Stream property to share output streams between two APG scripts. Script.apg uses programmatic execution to direct the execution of a second APG script, htmlfrag.apg. All content generated by both APG scripts is sent to the file output.htm.
Script.apg:
<%# ' -- script.apg --
Option Explicit
Output.Filename = "output.htm"
#%>
<HTML><BODY>
First line generated by script.apg<BR>
<%#
Dim oAPGen, oScriptHtmlFrag
Set oAPGen = CreateObject("APGen")
Set oScriptHtmlFrag= oAPGen.OpenScript("htmlfrag.apg")
' This is where the output stream is shared
' Send
htmlfrag.apg's output to script.apg's output stream.
oScriptHtmlFrag.Output.Stream = Output.Stream
' Now, run "htmlfrag.apg"
oScriptHtmlFrag.Run
#%>
</BODY></HTML>
Note that HtmlFrag.apg contains no script blocks. HtmlFrag.apg:
<P>
HTML Fragment
</P>
Together these two scripts create output file output.htm:
<HTML><BODY>
First line generated by script.apg<BR>
<P>
HTML Fragment
</P>
</BODY></HTML>
The line that shares the output stream is:
oScriptHtmlFrag.Output.Stream = Output.Stream
This redirects the output stream for the oScriptHtmlFrag object (which represents HtmlFrag.apg) to the output stream for Script.apg (which writes to output.htm). This line is necessary, else calling
oScriptHtmlFrag.Run
would send output to HtmlFrag.htm.
For another example that shares output streams and utilizes the APGScript.Globals property, see the APGScript.Globals topic.
To send output (Output object output or Log object output) to a custom COM object, the COM object must implement the IStream interface. Since the IStream interface is a non-automation interface, the object must be written in C++, or another language that supports custom COM interfaces.
The IStream interface is described in the Win32 SDK documentation.
Your custom object should implement the following IStream methods:
| Method | Comment |
IStream::Write() |
Must be implemented to receive content. |
IStream::Seek()
|
Required if Append property is True. Otherwise, does not have to be implemented. |
The other IStream methods do not have to be implemented
(they can return E_NOTIMPL). IStream::Seek() is called if
the Append property
(Output.Append
or Log.Append) is
True. Note that the default value for Log.Append is
True, so if you are implementing a custom object that will receive the log
stream, and you want to append information to the stream, then you will need to
implement IStream::Seek().
Once you have written an object that implements IStream, you can use APG script code to place your object on the receiving end of the stream:
' Let's say your object has ProgID "Company.StreamObject"
Dim oStreamObject
Set oStreamObject = Script.CreateObject( "Company.StreamObject" )
' Send output to your object
Output.Stream = oStreamObject
That's all it takes to send output to your object.
The Output object will hold onto your object until the script is released, Output.Close() is called, or Output.Stream is set to point to another object.