home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C Programming Starter Kit 2.0
/
SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso
/
bc45
/
pstreams.pak
/
STREAM2.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-23
|
73KB
|
1,844 lines
/*------------------------------------------------------------------------*/
/* */
/* STREAM2.CPP */
/* */
/* Copyright Borland International, 1993 */
/* */
/* Streaming example, version 2 */
/* */
/* Streams enhanced objects but stays compatible with streams created */
/* with version 1. */
/* */
/*------------------------------------------------------------------------*/
#include <owl\owlpch.h>
#include <new.h>
#include <cstring.h>
#include <classlib\sets.h>
#include <classlib\objstrm.h>
#include <owl\point.h>
#include <owl\window.h>
#include <owl\dc.h>
#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\dialog.h>
#include <owl\opensave.h>
#include "streams.h"
/*------------------------------------------------------------------------*/
/* */
/* class GraphicalObject */
/* */
/* class GraphicalObject provides the abstract interface */
/* to all of the graphical objects that can be displayed */
/* by this graphical system. It should be a virtual base */
/* of any class derived from it. */
/* */
/* Member functions: */
/* */
/* GraphicalObject(); */
/* */
/* Creates a GraphicalObject with undefined initial */
/* coordinates. Needed only in multiple inheritance when */
/* we know that GraphicalObject(const TRect&) will be used */
/* by derived classes. */
/* */
/* GraphicalObject( TPoint p1, TPoint p2 ); */
/* */
/* Creates a GraphicalObject with the location and size */
/* specified by p1 and p2. */
/* */
/* virtual ~GraphicalObject(); */
/* */
/* Destructor. */
/* */
/* void Draw( TDC& ); */
/* */
/* Does some preliminary setup of the device context, then */
/* calls DoDraw() to draw the object. */
/* */
/* virtual void DoDraw( TDC& ) = 0; */
/* */
/* Draws the object. In GraphicalObject this does */
/* nothing. It should be overridden in any class */
/* that will be displayed on the screen. */
/* */
/* int operator == ( const GraphicalObject& ) const; */
/* */
/* This operator must exist so that we can put GraphicalObjects */
/* into the Set that is used in TGraphWindow. */
/* */
/*------------------------------------------------------------------------*/
class GraphicalObject : public TStreamableBase
{
public:
GraphicalObject();
GraphicalObject( TPoint p1, TPoint p2 );
virtual ~GraphicalObject();
void Draw( TDC& );
int operator == ( const GraphicalObject& obj ) const;
protected:
TRect bbox;
void SetFill(); // Changed
private:
int Filled; // Changed
virtual void DoDraw( TDC& ) = 0;
class GraphicalObjectDC
{
public:
GraphicalObjectDC( TDC& dc, int filled ); // Changed
~GraphicalObjectDC();
operator TDC&() const;
private:
TDC& DC;
};
DECLARE_ABSTRACT_STREAMABLE( , GraphicalObject, 2 );// Changed
};
inline GraphicalObject::GraphicalObject() : Filled(0) // Changed
{
}
inline GraphicalObject::GraphicalObject( TPoint p1, TPoint p2 ) :
bbox( p1, p2 ), Filled(0)
{
}
inline GraphicalObject::~GraphicalObject()
{
}
void GraphicalObject::Draw( TDC& dc )
{
GraphicalObjectDC gdc( dc, Filled ); // Changed
DoDraw( gdc );
}
inline int GraphicalObject::operator == ( const GraphicalObject& obj ) const
{
return this == &obj;
}
// Changed
void GraphicalObject::SetFill()
{
Filled = 1;
}
GraphicalObject::GraphicalObjectDC::GraphicalObjectDC( TDC& dc, int filled ) :
DC(dc)
{
if( filled ) // Changed
DC.SelectStockObject( BLACK_BRUSH );
else
DC.SelectStockObject( NULL_BRUSH );
}
GraphicalObject::GraphicalObjectDC::~GraphicalObjectDC()
{
}
GraphicalObject::GraphicalObjectDC::operator TDC&() const
{
return DC;
}
IMPLEMENT_CASTABLE( GraphicalObject );
IMPLEMENT_ABSTRACT_STREAMABLE( GraphicalObject );
// Changed
void *GraphicalObject::Streamer::Read( ipstream& in, uint32 ver ) const
{
in >> GetObject()->bbox;
if( ver > 1 )
in >> GetObject()->Filled;
else
GetObject()->Filled = 0; // old objects didn't write this field
return GetObject();
}
void GraphicalObject::Streamer::Write( opstream& out ) const
{
out << GetObject()->bbox << GetObject()->Filled; // Changed
}
/*------------------------------------------------------------------------*/
/* */
/* class Line */
/* */
/* class Line draws a line between two specified points. */
/* */
/* Member functions: */
/* */
/* Line( TPoint p1, TPoint p2 ); */
/* */
/* Creates a line between the points p1 and p2. */
/* */
/* void ImplementDraw( TDC& ); */
/* */
/* Draws the line. */
/* */
/* virtual void DoDraw( TDC& ); */
/* */
/* Overrides GraphicalObject::DoDraw and draws the line by */
/* calling ImplementDraw(). */
/* */
/*------------------------------------------------------------------------*/
class Line : public virtual GraphicalObject
{
public:
Line( TPoint p1, TPoint p2 );
protected:
void ImplementDraw( TDC& );
private:
virtual void DoDraw( TDC& );
DECLARE_STREAMABLE_FROM_BASE( , Line, GraphicalObject );
};
inline Line::Line( TPoint p1, TPoint p2 ) : GraphicalObject( p1, p2 )
{
}
void Line::ImplementDraw( TDC& dc )
{
dc.MoveTo( bbox.left, bbox.top );
dc.LineTo( bbox.right, bbox.bottom );
}
void Line::DoDraw( TDC& dc )
{
ImplementDraw( dc );
}
IMPLEMENT_CASTABLE1( Line, GraphicalObject );
IMPLEMENT_STREAMABLE_FROM_BASE( Line, GraphicalObject );
/*------------------------------------------------------------------------*/
/* */
/* class TRectangle */
/* */
/* class TRectangle draws a rectangle. */
/* */
/* Member functions: */
/* */
/* TRectangle( TPoint p1, TPoint p2 ); */
/* */
/* Creates a TRectangle whose upper left corner is at p1 */
/* and whose lower right corner is at p2. */
/* */
/* void ImplementDraw( TDC& ); */
/* */
/* Draws the rectangle. */
/* */
/* virtual void DoDraw( TDC& ); */
/* */
/* Overrides GraphicalObject::DoDraw and draws the rectangle by */
/* calling ImplementDraw(). */
/* */
/*------------------------------------------------------------------------*/
class TRectangle : public virtual GraphicalObject
{
public:
TRectangle( TPoint p1, TPoint p2 );
protected:
void ImplementDraw( TDC& );
private:
virtual void DoDraw( TDC& );
DECLARE_STREAMABLE_FROM_BASE( , TRectangle, GraphicalObject );
};
inline TRectangle::TRectangle( TPoint p1, TPoint p2 ) :
GraphicalObject( p1, p2 )
{
}
void TRectangle::ImplementDraw( TDC& dc )
{
dc.Rectangle( bbox );
}
void TRectangle::DoDraw( TDC& dc )
{
ImplementDraw( dc );
}
IMPLEMENT_CASTABLE1( TRectangle, GraphicalObject );
IMPLEMENT_STREAMABLE_FROM_BASE( TRectangle, GraphicalObject );
/*------------------------------------------------------------------------*/
/* */
/* class TEllipse */
/* */
/* class TEllipse draws an ellipse. */
/* */
/* Member functions: */
/* */
/* TEllipse( TPoint p1, TPoint p2 ); */
/* */
/* Creates a TEllipse whose bounding box is defined by p1 and p2 */
/* */
/* void ImplementDraw( TDC& ); */
/* */
/* Draws the ellipse. */
/* */
/* virtual void DoDraw( TDC& ); */
/* */
/* Overrides GraphicalObject::DoDraw and draws the ellipse by */
/* calling ImplementDraw(). */
/* */
/*------------------------------------------------------------------------*/
class TEllipse : public virtual GraphicalObject
{
public:
TEllipse( TPoint p1, TPoint p2 );
protected:
void ImplementDraw( TDC& );
private:
virtual void DoDraw( TDC& );
DECLARE_STREAMABLE_FROM_BASE( , TEllipse, GraphicalObject );
};
TEllipse::TEllipse( TPoint p1, TPoint p2 ) :
GraphicalObject( p1, p2 )
{
}
void TEllipse::ImplementDraw( TDC& dc )
{
dc.Ellipse( bbox );
}
void TEllipse::DoDraw( TDC& dc )
{
ImplementDraw( dc );
}
IMPLEMENT_CASTABLE1( TEllipse, GraphicalObject );
IMPLEMENT_STREAMABLE_FROM_BASE( TEllipse, GraphicalObject );
/*------------------------------------------------------------------------*/
/* */
/* class Caption */
/* */
/* class Caption draws its text on the screen. */
/* Note that Caption is an abstract class. It */
/* must have a bounding box, but it does not */
/* have a constructor that takes any coordinates. */
/* Each class derived from Caption will provide */
/* a bounding box in the virtual base GraphicalObject. */
/* */
/* Type definitions: */
/* */
/* TextLoc */
/* */
/* An enum used to specify how y-coordinate values */
/* should be interpreted when displaying text. */
/* */
/* Member functions: */
/* */
/* Caption( const string& txt, TextLoc where ); */
/* */
/* Creates a Caption with the specified text, */
/* which will be drawn in its bounding box */
/* at the top, center, or bottom, depending */
/* on the value of its argument 'where'. */
/* */
/* virtual void ImplementDraw( TDC& ); */
/* */
/* Draws the caption. */
/* */
/*------------------------------------------------------------------------*/
class Caption : public virtual GraphicalObject
{
public:
enum TextLoc{ T_TOP, T_CENTER, T_BOTTOM };
Caption( const string& txt, TextLoc where );
protected:
void ImplementDraw( TDC& );
private:
string Text;
TextLoc Where;
DECLARE_ABSTRACT_STREAMABLE( , Caption, 1 );
};
Caption::Caption( const string& text, TextLoc where ) :
Text( text ), Where(where)
{
}
#pragma warn -def
void Caption::ImplementDraw( TDC& dc )
{
TEXTMETRIC tm;
dc.GetTextMetrics(tm);
int textHeight = tm.tmHeight+tm.tmExternalLeading;
int yDelta;
switch( Where )
{
case T_TOP:
yDelta = textHeight/2;
break;
case T_CENTER:
yDelta = (bbox.Height()-textHeight)/2;
break;
case T_BOTTOM:
yDelta = bbox.Height()-3*textHeight/2;
break;
}
dc.TextOut( bbox.left+bbox.Width()/2,
bbox.top+yDelta,
Text.c_str(), Text.length() );
}
#pragma warn .def
IMPLEMENT_CASTABLE1( Caption, GraphicalObject );
IMPLEMENT_ABSTRACT_STREAMABLE1( Caption, GraphicalObject );
void *Caption::Streamer::Read( ipstream& in, uint32 ) const
{
ReadVirtualBase( STATIC_CAST(GraphicalObject *,GetObject()), in );
int temp;
in >> GetObject()->Text >> temp;
GetObject()->Where = TextLoc(temp);
return GetObject();
}
void Caption::Streamer::Write( opstream& out ) const
{
WriteVirtualBase( STATIC_CAST(GraphicalObject *,GetObject()), out );
out << GetObject()->Text << int(GetObject()->Where);
}
/*------------------------------------------------------------------------*/
/* */
/* class CaptionedRectangle */
/* */
/* class CaptionedRectangle draws a rectangle on the */
/* screen, with a caption horizontally centered at the */
/* top, in the center, or at the bottom. */
/* */
/* Member functions: */
/* */
/* CaptionedRectangle( TPoint p1, TPoint p2, */
/* const string& txt, */
/* TextLoc loc = T_TOP ) */
/* */
/* Creates a CaptionedRectangle with the specified */
/* location, size, and text. */
/* */
/* void ImplementDraw( TDC& ); */
/* */
/* Draws the rectangle and its text. */
/* */
/* virtual void DoDraw( TDC& ); */
/* */
/* Overrides GraphicalObject::DoDraw and draws the rectangle by */
/* calling ImplementDraw(). */
/* */
/*------------------------------------------------------------------------*/
class CaptionedRectangle : public TRectangle, public Caption
{
public:
CaptionedRectangle( TPoint p1, TPoint p2,
const string& txt,
TextLoc loc = T_TOP );
protected:
void ImplementDraw( TDC& );
private:
virtual void DoDraw( TDC& );
DECLARE_STREAMABLE( , CaptionedRectangle, 1 );
};
CaptionedRectangle::CaptionedRectangle( TPoint p1, TPoint p2,
const string& txt,
TextLoc loc ) :
GraphicalObject( p1, p2 ),
TRectangle( p1, p2 ),
Caption( txt, loc )
{
}
void CaptionedRectangle::ImplementDraw( TDC& dc )
{
TRectangle::ImplementDraw( dc );
Caption::ImplementDraw( dc );
}
void CaptionedRectangle::DoDraw( TDC& dc )
{
ImplementDraw( dc );
}
IMPLEMENT_CASTABLE2( CaptionedRectangle, TRectangle, Caption );
IMPLEMENT_STREAMABLE3( CaptionedRectangle, TRectangle, Caption, GraphicalObject );
void *CaptionedRectangle::Streamer::Read( ipstream& in, uint32 ) const
{
ReadBaseObject( STATIC_CAST(TRectangle *,GetObject()), in );
ReadBaseObject( STATIC_CAST(Caption *,GetObject()), in );
return GetObject();
}
void CaptionedRectangle::Streamer::Write( opstream& out ) const
{
WriteBaseObject( STATIC_CAST(TRectangle *,GetObject()), out );
WriteBaseObject( STATIC_CAST(Caption *,GetObject()), out );
}
/*------------------------------------------------------------------------*/
/* */
/* class CaptionedEllipse */
/* */
/* class CaptionedEllipse draws an ellipse on the */
/* screen, with a caption centered in the ellipse. */
/* */
/* Member functions: */
/* */
/* CaptionedEllipse( TPoint p1, TPoint p2, */
/* const string& txt ) */
/* */
/* Creates a CaptionedEllipse with the specified */
/* bounding box and text. */
/* */
/* void ImplementDraw( TDC& ); */
/* */
/* Draws the ellipse and its text. */
/* */
/* virtual void DoDraw( TDC& ); */
/* */
/* Overrides GraphicalObject::DoDraw and draws the ellipse by */
/* calling ImplementDraw(). */
/* */
/*------------------------------------------------------------------------*/
class CaptionedEllipse : public TEllipse, public Caption
{
public:
CaptionedEllipse( TPoint p1, TPoint p2, const string& txt );
protected:
void ImplementDraw( TDC& );
private:
virtual void DoDraw( TDC& );
DECLARE_STREAMABLE( , CaptionedEllipse, 1 );
};
CaptionedEllipse::CaptionedEllipse( TPoint p1, TPoint p2, const string& txt ) :
GraphicalObject( p1, p2 ),
TEllipse( p1, p2 ),
Caption( txt, T_CENTER )
{
}
void CaptionedEllipse::ImplementDraw( TDC& dc )
{
TEllipse::ImplementDraw( dc );
Caption::ImplementDraw( dc );
}
void CaptionedEllipse::DoDraw( TDC& dc )
{
ImplementDraw( dc );
}
IMPLEMENT_CASTABLE2( CaptionedEllipse, TEllipse, Caption );
IMPLEMENT_STREAMABLE3( CaptionedEllipse, TEllipse, Caption, GraphicalObject );
void *CaptionedEllipse::Streamer::Read( ipstream& in, uint32 ) const
{
ReadBaseObject( STATIC_CAST(TEllipse *,GetObject()), in );
ReadBaseObject( STATIC_CAST(Caption *,GetObject()), in );
return GetObject();
}
void CaptionedEllipse::Streamer::Write( opstream& out ) const
{
WriteBaseObject( STATIC_CAST(TEllipse *,GetObject()), out );
WriteBaseObject( STATIC_CAST(Caption *,GetObject()), out );
}
/*------------------------------------------------------------------------*/
/* */
/* class TFilledRectangle */
/* */
/* class TFilledRectangle draws a black rectangle on the screen. */
/* */
/* Member functions: */
/* */
/* TFilledRectangle( TPoint p1, TPoint p2 ); */
/* */
/* Creates a TFilledRectangle whose upper left corner is at p1 */
/* and whose lower right corner is at p2. */
/* */
/*------------------------------------------------------------------------*/
class TFilledRectangle : public TRectangle
{
public:
TFilledRectangle::TFilledRectangle( TPoint p1, TPoint p2 );
DECLARE_STREAMABLE_FROM_BASE( , TFilledRectangle, TRectangle );
};
TFilledRectangle::TFilledRectangle( TPoint p1, TPoint p2 ) :
TRectangle( p1, p2 ), GraphicalObject( p1, p2 )
{
SetFill();
}
IMPLEMENT_CASTABLE1( TFilledRectangle, TRectangle );
IMPLEMENT_STREAMABLE_FROM_BASE( TFilledRectangle, TRectangle );
/*------------------------------------------------------------------------*/
/* */
/* class TFilledEllipse */
/* */
/* class TFilledEllipse draws a black ellipse on the screen. */
/* */
/* Member functions: */
/* */
/* TFilledEllipse( TPoint p1, TPoint p2 ); */
/* */
/* Creates a TFilledEllipse whose bounding box is defined by */
/* p1 and p2 */
/* */
/*------------------------------------------------------------------------*/
class TFilledEllipse : public TEllipse
{
public:
TFilledEllipse::TFilledEllipse( TPoint p1, TPoint p2 );
DECLARE_STREAMABLE_FROM_BASE( , TFilledEllipse, TEllipse );
};
TFilledEllipse::TFilledEllipse( TPoint p1, TPoint p2 ) :
TEllipse( p1, p2 ), GraphicalObject( p1, p2 )
{
SetFill();
}
IMPLEMENT_CASTABLE1( TFilledEllipse, TEllipse );
IMPLEMENT_STREAMABLE_FROM_BASE( TFilledEllipse, TEllipse );
/*------------------------------------------------------------------------*/
/* */
/* class TObjectBuilder */
/* */
/* class TObjectBuilder provides the core functionality for */
/* building objects derived from GraphicalObject in a Windows */
/* environment. It handles changing the cursor to one that */
/* indicates the type of object being built, clipping the cursor */
/* so that it stays within the application's client area, */
/* handles anchoring the object's bounding box and dragging the */
/* unanchored corner of the bounding box. */
/* */
/* Public member functions: */
/* */
/* TObjectBuilder( TWindow& owner, int cursorId ); */
/* */
/* Clips the cursor so that it stays within the owner's */
/* client area and replaces the default cursor with the */
/* cursor contained in the resource identified by cursorId. */
/* */
/* ~TObjectBuilder(); */
/* */
/* Restores the default cursor and ends the clipping. */
/* */
/* */
/* void SetAnchor( TPoint pos ); */
/* */
/* Sets the anchor point of the bounding box to the point pos. */
/* */
/* void Drag( TPoint pos ); */
/* */
/* Moves the unanchored corner of the bounding box to the */
/* point pos, drawing the object's skeleton as appropriate. */
/* See DrawSkeleton(). */
/* */
/* GraphicalObject *CreateObject(); */
/* */
/* Returns a pointer to the newly created object derived */
/* from GraphicalObject and contained within the bounding box */
/* delimited by the anchor point and the unanchored corner as */
/* set up by SetAnchor() and Drag() and cleans up whatever */
/* needs to be cleaned up. See BuildObject(). */
/* */
/* void Cancel() */
/* */
/* Cleans up whatever needs to be cleaned up when the object is */
/* not wanted. */
/* */
/* Protected member functions: */
/* */
/* const TWindow& GetOwner() const; */
/* */
/* Returns a reference to the TWindow that owns the client */
/* area that we're drawing to. */
/* */
/* Virtual functions: */
/* */
/* void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const = 0; */
/* */
/* This must be overridden by the derived class. It is called */
/* from Drag() to erase the previously drawn skeleton which */
/* was drawn at p1 and p2, and it is called again to draw the */
/* new skeleton at positions p1 and p2. The skeleton should be */
/* some sort of simple line representation of the object being */
/* built. */
/* */
/* GraphicalObject *BuildObject( TPoint p1, TPoint p2 ) = 0; */
/* */
/* Called from CreateObject() to actually build the desired */
/* object, with its bounding box defined by p1 and p2. Typically */
/* this just calls a constructor for the desired object. */
/* */
/*------------------------------------------------------------------------*/
class TObjectBuilder
{
public:
TObjectBuilder( TWindow& owner, int cursorId );
virtual ~TObjectBuilder();
void SetAnchor( TPoint pos );
void Drag( TPoint pos );
GraphicalObject *CreateObject();
void Cancel() const;
protected:
const TWindow& GetOwner() const { return Owner; }
private:
class BuilderDC : public TClientDC
{
public:
BuilderDC( HWND wnd );
~BuilderDC();
};
virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const = 0;
virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 ) = 0;
TPoint Anchor;
TPoint Current;
int Anchored;
HCURSOR OldCursor;
TWindow& Owner;
TObjectBuilder( const TObjectBuilder& );
const TObjectBuilder& operator = ( const TObjectBuilder& );
};
TObjectBuilder::TObjectBuilder( TWindow& owner, int cursorId ) :
Owner(owner),
Anchored(0)
{
TRect Rect;
Owner.GetWindowRect( Rect );
ClipCursor( &Rect );
Owner.SetCursor( Owner.GetApplication(), cursorId );
}
TObjectBuilder::~TObjectBuilder()
{
Owner.SetCursor( 0, IDC_ARROW );
ClipCursor(0);
}
void TObjectBuilder::SetAnchor( TPoint point )
{
Anchor = Current = point;
BuilderDC dc( Owner );
DrawSkeleton( dc, Anchor, Current );
Anchored = 1;
}
void TObjectBuilder::Drag( TPoint point )
{
if( Anchored )
{
BuilderDC dc( Owner );
DrawSkeleton( dc, Anchor, Current );
Current = point;
DrawSkeleton( dc, Anchor, Current );
}
}
GraphicalObject *TObjectBuilder::CreateObject()
{
return BuildObject( Anchor, Current );
}
void TObjectBuilder::Cancel() const
{
if( Anchored )
{
BuilderDC dc( Owner );
DrawSkeleton( dc, Anchor, Current );
}
}
TObjectBuilder::BuilderDC::BuilderDC( HWND wnd ) : TClientDC( wnd )
{
SelectStockObject(WHITE_PEN);
SetROP2( R2_XORPEN );
SelectStockObject(NULL_BRUSH);
}
TObjectBuilder::BuilderDC::~BuilderDC()
{
}
/*------------------------------------------------------------------------*/
/* */
/* class LineBuilder */
/* */
/* class LineBuilder builds a Line object using the mechanisms */
/* provided by TObjectBuilder. */
/* */
/* Member functions: */
/* */
/* LineBuilder( TWindow& owner ); */
/* */
/* Initializes a LineBuilder that will draw its skeleton inside */
/* the client area of owner. */
/* */
/* void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const; */
/* */
/* Overrides TObjectBuilder::DrawSkeleton to draw the skeleton */
/* for a line, which is just a line from p1 to p2. */
/* */
/* GraphicalObject *BuildObject( TPoint p1, TPoint p2 ); */
/* */
/* Overrides TObjectBuilder::BuildObject to build a Line */
/* object with its endpoints at p1 and p2. */
/* */
/*------------------------------------------------------------------------*/
class LineBuilder : public TObjectBuilder
{
public:
LineBuilder( TWindow& owner );
private:
virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
};
LineBuilder::LineBuilder( TWindow& owner ) :
TObjectBuilder( owner, LINE_CURSOR )
{
}
void LineBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
{
dc.MoveTo( p1.x, p1.y );
dc.LineTo( p2.x, p2.y );
}
GraphicalObject *LineBuilder::BuildObject( TPoint p1, TPoint p2 )
{
return new Line( p1, p2 );
}
/*------------------------------------------------------------------------*/
/* */
/* class RectangleBuilder */
/* */
/* class RectangleBuilder builds a TRectangle object using the */
/* mechanisms provided by TObjectBuilder. */
/* */
/* Member functions: */
/* */
/* RectangleBuilder( TWindow& owner ); */
/* */
/* Initializes a RectangleBuilder that will draw its skeleton */
/* inside the client area of owner. */
/* */
/* void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const; */
/* */
/* Overrides TObjectBuilder::DrawSkeleton to draw the skeleton */
/* for a TRectangle, which is a rectangle whose upper left */
/* corner is at p1 and whose lower right corner is at p2. */
/* */
/* GraphicalObject *BuildObject( TPoint p1, TPoint p2 ); */
/* */
/* Overrides TObjectBuilder::BuildObject to build a TRectangle */
/* object with its upper left corner at p1 and its lower right */
/* corner at p2. */
/* */
/*------------------------------------------------------------------------*/
class RectangleBuilder : public TObjectBuilder
{
public:
RectangleBuilder( TWindow& owner );
private:
virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
};
RectangleBuilder::RectangleBuilder( TWindow& owner ) :
TObjectBuilder( owner, RECT_CURSOR )
{
}
void RectangleBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
{
dc.Rectangle( p1, p2 );
}
GraphicalObject *RectangleBuilder::BuildObject( TPoint p1, TPoint p2 )
{
return new TRectangle( p1, p2 );
}
/*------------------------------------------------------------------------*/
/* */
/* class EllipseBuilder */
/* */
/* class EllipseBuilder builds a TEllipse object using the */
/* mechanisms provided by TObjectBuilder. */
/* */
/* Member functions: */
/* */
/* EllipseBuilder( TWindow& owner ); */
/* */
/* Initializes an EllipseBuilder that will draw its skeleton */
/* inside the client area of owner. */
/* */
/* void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const; */
/* */
/* Overrides TObjectBuilder::DrawSkeleton to draw the skeleton */
/* for a TEllipse, which is an ellipse with a bounding box whose */
/* upper left corner is at p1 and whose lower right corner is */
/* at p2. */
/* */
/* GraphicalObject *BuildObject( TPoint p1, TPoint p2 ); */
/* */
/* Overrides TObjectBuilder::BuildObject to build a TEllipse */
/* object with a bounding box whose upper left corner is at p1 */
/* and whose lower right corner is at p2. */
/* */
/*------------------------------------------------------------------------*/
class EllipseBuilder : public TObjectBuilder
{
public:
EllipseBuilder( TWindow& owner );
private:
virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
};
EllipseBuilder::EllipseBuilder( TWindow& owner ) :
TObjectBuilder( owner, ELLIPSE_CURSOR )
{
}
void EllipseBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
{
dc.Ellipse( p1, p2 );
}
GraphicalObject *EllipseBuilder::BuildObject( TPoint p1, TPoint p2 )
{
return new TEllipse( p1, p2 );
}
/*------------------------------------------------------------------------*/
/* */
/* class CaptionBuilder */
/* */
/* class CaptionBuilder provides a base class for use by builders */
/* of captioned objects. It does not inherit from TObjectBuilder. */
/* It is expected that this class will be mixed in with a class */
/* that does inherit from TObjectBuilder. See, for example, */
/* CaptionedRectangleBuilder. */
/* */
/* Member functions: */
/* */
/* CaptionBuilder( TWindow& owner, int allowPosition ); */
/* */
/* Initializes a CaptionBuilder that will belong to the TWindow */
/* owner. allowPosition is a flag that indicates whether the */
/* user should be allowed to specify the placement of the */
/* caption. If allowPosition is non-zero, the dialog box that */
/* prompts for the caption also allows the user to specify */
/* whether the caption should be at the top, in the center, or */
/* at the bottom of the object. If allowPosition is 0 this */
/* part of the dialog box is grayed out. */
/* */
/* string GetCaption(); */
/* */
/* Retrieves the text of the caption specified by the user. If */
/* the user hasn't been asked for the caption yet GetCaption() */
/* puts up a dialog box requesting input from the user. */
/* */
/* Caption::TextLoc GetLocation(); */
/* */
/* Retrieves the location for the caption specified by the user. */
/* If the user hasn't been asked for the caption yet */
/* GetLocation() puts up a dialog box requesting input from the */
/* user. If allowPosition was 0 GetLocation() returns T_TOP. */
/* */
/*------------------------------------------------------------------------*/
class CaptionBuilder
{
public:
CaptionBuilder( TWindow& owner, int allowPosition = 1 );
string GetCaption();
Caption::TextLoc GetLocation();
private:
void GetData();
int HaveData;
string Caption;
Caption::TextLoc Location;
TWindow& Owner;
int AllowPosition;
class CaptionDialog : public TDialog
{
public:
CaptionDialog( TWindow& parent, CaptionBuilder& builder );
BOOL CanClose();
void SetupWindow();
private:
void TopClicked();
void CenterClicked();
void BottomClicked();
CaptionBuilder& Builder;
DECLARE_RESPONSE_TABLE( CaptionDialog );
};
friend CaptionDialog;
};
CaptionBuilder::CaptionBuilder( TWindow& owner, int allowPosition ) :
HaveData(0),
Location(Caption::T_TOP),
Owner(owner),
AllowPosition(allowPosition)
{
}
void CaptionBuilder::GetData()
{
if( !HaveData )
{
CaptionDialog dialog( Owner, *this );
dialog.Execute();
HaveData = 1;
}
}
string CaptionBuilder::GetCaption()
{
GetData();
return Caption;
}
Caption::TextLoc CaptionBuilder::GetLocation()
{
GetData();
return Location;
}
DEFINE_RESPONSE_TABLE1( CaptionBuilder::CaptionDialog, TDialog )
EV_CHILD_NOTIFY( IDD_TOP, BN_CLICKED, TopClicked ),
EV_CHILD_NOTIFY( IDD_CENTER, BN_CLICKED, CenterClicked ),
EV_CHILD_NOTIFY( IDD_BOTTOM, BN_CLICKED, BottomClicked ),
END_RESPONSE_TABLE;
CaptionBuilder::CaptionDialog::CaptionDialog( TWindow& parent, CaptionBuilder& builder ) :
TDialog( &parent, "CaptionDlg" ),
Builder(builder)
{
}
void CaptionBuilder::CaptionDialog::SetupWindow()
{
if( Builder.AllowPosition )
SendDlgItemMessage( IDD_TOP, BM_SETCHECK, 1, 0L );
else
{
::EnableWindow( GetDlgItem( IDD_TOP ), 0 );
::EnableWindow( GetDlgItem( IDD_CENTER ), 0 );
::EnableWindow( GetDlgItem( IDD_BOTTOM ), 0 );
::EnableWindow( GetDlgItem( IDD_POSITIONBOX ), 0 );
}
}
BOOL CaptionBuilder::CaptionDialog::CanClose()
{
char buf[256];
GetDlgItemText( IDD_INPUTEDITBOX, buf, sizeof(buf) );
Builder.Caption = buf;
return TRUE;
}
void CaptionBuilder::CaptionDialog::TopClicked()
{
Builder.Location = Caption::T_TOP;
}
void CaptionBuilder::CaptionDialog::CenterClicked()
{
Builder.Location = Caption::T_CENTER;
}
void CaptionBuilder::CaptionDialog::BottomClicked()
{
Builder.Location = Caption::T_BOTTOM;
}
/*------------------------------------------------------------------------*/
/* */
/* class CaptionedRectangleBuilder */
/* */
/* class CaptionedRectangleBuilder builds a CaptionedRectangle */
/* object using the mechanisms provided by TObjectBuilder. */
/* */
/* Member functions: */
/* */
/* CaptionedRectangleBuilder( TWindow& owner ); */
/* */
/* Initializes a CaptionedRectangleBuilder that will draw its */
/* skeleton inside the client area of owner and prompt for the */
/* caption after the bounding box has been defined. */
/* */
/* void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const; */
/* */
/* Overrides TObjectBuilder::DrawSkeleton to draw the skeleton */
/* for a CaptionedRectangle, which is a rectangle whose upper */
/* left corner is at p1 and whose lower right corner is at p2. */
/* */
/* GraphicalObject *BuildObject( TPoint p1, TPoint p2 ); */
/* */
/* Overrides TObjectBuilder::BuildObject to build a */
/* CaptionedRectangle object with its upper left corner at p1 */
/* and its lower right corner at p2. */
/* */
/*------------------------------------------------------------------------*/
class CaptionedRectangleBuilder : public RectangleBuilder, private CaptionBuilder
{
public:
CaptionedRectangleBuilder( TWindow& owner );
private:
virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
};
CaptionedRectangleBuilder::CaptionedRectangleBuilder( TWindow& owner ) :
RectangleBuilder( owner ),
CaptionBuilder( owner )
{
}
GraphicalObject *CaptionedRectangleBuilder::BuildObject( TPoint p1, TPoint p2 )
{
return new CaptionedRectangle( p1, p2, GetCaption(), GetLocation() );
}
/*------------------------------------------------------------------------*/
/* */
/* class CaptionedEllipseBuilder */
/* */
/* class CaptionedEllipseBuilder builds a CaptionedEllipse */
/* object using the mechanisms provided by TObjectBuilder. */
/* */
/* Member functions: */
/* */
/* CaptionedEllipseBuilder( TWindow& owner ); */
/* */
/* Initializes a CaptionedRectangleBuilder that will draw its */
/* skeleton inside the client area of owner and prompt for the */
/* caption after the bounding box has been defined. */
/* */
/* void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const; */
/* */
/* Overrides TObjectBuilder::DrawSkeleton to draw the skeleton */
/* for a CaptionedEllipse, which is an ellipse with a bounding */
/* box whose upper left corner is at p1 and whose lower right */
/* corner is at p2. */
/* */
/* GraphicalObject *BuildObject( TPoint p1, TPoint p2 ); */
/* */
/* Overrides TObjectBuilder::BuildObject to build a */
/* CaptionedEllipse object with a bounding box whose upper left */
/* corner is at p1 and whose lower right corner is at p2. */
/* */
/*------------------------------------------------------------------------*/
class CaptionedEllipseBuilder : public EllipseBuilder, public CaptionBuilder
{
public:
CaptionedEllipseBuilder( TWindow& owner );
private:
virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
};
CaptionedEllipseBuilder::CaptionedEllipseBuilder( TWindow& owner ) :
EllipseBuilder( owner ),
CaptionBuilder( owner, 0 )
{
}
GraphicalObject *CaptionedEllipseBuilder::BuildObject( TPoint p1, TPoint p2 )
{
return new CaptionedEllipse( p1, p2, GetCaption() );
}
/*------------------------------------------------------------------------*/
/* */
/* class FilledRectangleBuilder */
/* */
/* class FilledRectangleBuilder builds a TFilledRectangle object. */
/* */
/* Member functions: */
/* */
/* FilledRectangleBuilder( TWindow& owner ); */
/* */
/* Initializes a FilledRectangleBuilder. */
/* */
/* GraphicalObject *BuildObject( TPoint p1, TPoint p2 ); */
/* */
/* Overrides RectangleBuilder::BuildObject to build a */
/* TFilledRectangle object with its upper left corner at p1 and */
/* its lower right corner at p2. */
/* */
/*------------------------------------------------------------------------*/
class FilledRectangleBuilder : public RectangleBuilder
{
public:
FilledRectangleBuilder( TWindow& owner );
private:
virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
};
FilledRectangleBuilder::FilledRectangleBuilder( TWindow& owner ) :
RectangleBuilder( owner )
{
}
GraphicalObject *FilledRectangleBuilder::BuildObject( TPoint p1, TPoint p2 )
{
return new TFilledRectangle( p1, p2 );
}
/*------------------------------------------------------------------------*/
/* */
/* class FilledEllipseBuilder */
/* */
/* class FilledEllipseBuilder builds a TFilledEllipse object. */
/* */
/* Member functions: */
/* */
/* FilledEllipseBuilder( TWindow& owner ); */
/* */
/* Initializes a FilledEllipseBuilder. */
/* */
/* GraphicalObject *BuildObject( TPoint p1, TPoint p2 ); */
/* */
/* Overrides EllipseBuilder::BuildObject to build a */
/* TFilledEllipse object with its bounding box defined by */
/* p1 and p2. */
/* */
/*------------------------------------------------------------------------*/
class FilledEllipseBuilder : public EllipseBuilder
{
public:
FilledEllipseBuilder( TWindow& owner );
private:
virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
};
FilledEllipseBuilder::FilledEllipseBuilder( TWindow& owner ) :
EllipseBuilder( owner )
{
}
GraphicalObject *FilledEllipseBuilder::BuildObject( TPoint p1, TPoint p2 )
{
return new TFilledEllipse( p1, p2 );
}
/*------------------------------------------------------------------------*/
/* */
/* class TGraphWindow */
/* */
/* class TGraphWindow pulls all of the forgoing together into a */
/* rather limited shape editor. It uses a TISetAsVector to hold */
/* the various objects that are in the current drawing. */
/* */
/* Member functions: */
/* */
/* TGraphWindow(); */
/* */
/* Initializes the window. */
/* */
/* void Paint( TDC&, BOOL, TRect& ); */
/* */
/* Called whenever the window receives a WM_PAINT message. Draws */
/* the objects by calling each of their Draw() functions. */
/* */
/* void CmNew(); */
/* */
/* Called when the user selects File/New from the menu. Removes */
/* all objects from the current drawing. */
/* */
/* void CmLine(); */
/* */
/* Called when the user selects Edit/Line from the menu. Adds */
/* a line to the drawing. */
/* */
/* void CmRectangle(); */
/* */
/* Called when the user selects Edit/Rectangle from the menu. */
/* Adds a rectangle to the drawing. */
/* */
/* void CmCaptionedRectangle(); */
/* */
/* Called when the user selects Edit/CaptionedRectangle from the */
/* menu. Adds a captioned rectangle to the drawing. */
/* */
/* void CmEllipse(); */
/* */
/* Called when the user selects Edit/Ellipse from the menu. */
/* Adds an ellipse to the drawing. */
/* */
/* void CmCaptionedEllipse(); */
/* */
/* Called when the user selects Edit/CaptionedEllipse from the */
/* menu. Adds a captioned ellipse to the drawing. */
/* */
/* void CmAbout(); */
/* */
/* Called when the user selects Help/About from the menu. */
/* Displays the About box. */
/* */
/* void EvLButtonDown(); */
/* */
/* Called when the user presses the left mouse button. During */
/* building of an object, this anchors the object's bounding */
/* box at the current position of the mouse. */
/* */
/* void EvLButtonUp(); */
/* */
/* Called when the user releases the left mouse button. During */
/* building of an object, this creates the actual object with */
/* its bounding box defined by the previous anchor position and */
/* the current position of the mouse. */
/* */
/* void EvRButtonDown(); */
/* */
/* Called when the user presses the right mouse button. During */
/* building of an object, this terminates building. */
/* */
/* void EvMouseMove(); */
/* */
/* Called when the user moves the mouse. During building of an */
/* object, if the object's bounding box has been anchored, this */
/* drags the free corner of the bounding box. */
/* */
/*------------------------------------------------------------------------*/
class TGraphWindow : public TWindow
{
public:
TGraphWindow();
void Paint(TDC&, BOOL, TRect&);
void CmNew();
void CmLine();
void CmRectangle();
void CmCaptionedRectangle();
void CmFilledRectangle(); // Changed
void CmEllipse();
void CmCaptionedEllipse();
void CmFilledEllipse(); // Changed
void CmAbout();
void CmFileOpen();
void CmFileSave();
void CmFileSaveAs();
void EvLButtonDown( UINT modKeys, TPoint& point );
void EvLButtonUp( UINT modKeys, TPoint& point );
void EvRButtonDown( UINT modKeys, TPoint& point );
void EvMouseMove( UINT modKeys, TPoint& point );
BOOL CanClose();
TOpenSaveDialog::TData FileData;
private:
int SaveFile();
int SaveFileAs();
void ReadObjects();
void WriteObjects();
int CheckAndClear();
int OkToClear();
static void WriteObject( GraphicalObject &obj, void * );
TObjectBuilder *Builder;
void FlushObjects();
void AddObject( GraphicalObject *obj );
static void DrawObject( GraphicalObject &obj, void * );
TISetAsVector<GraphicalObject> Objects;
int WindowIsDirty;
class GraphWindowDC
{
public:
GraphWindowDC( TDC& );
~GraphWindowDC();
operator TDC&() const;
private:
TDC& DC;
uint OldFlags;
TPen Pen;
};
DECLARE_RESPONSE_TABLE(TGraphWindow);
};
DEFINE_RESPONSE_TABLE1( TGraphWindow, TWindow )
EV_COMMAND( CM_FILENEW, CmNew ),
EV_COMMAND( CM_FILEOPEN, CmFileOpen ),
EV_COMMAND( CM_FILESAVE, CmFileSave ),
EV_COMMAND( CM_FILESAVEAS, CmFileSaveAs ),
EV_COMMAND( CM_EDITLINE, CmLine ),
EV_COMMAND( CM_EDITRECTANGLE, CmRectangle ),
EV_COMMAND( CM_EDITCAPTIONEDRECTANGLE, CmCaptionedRectangle ),
EV_COMMAND( CM_EDITFILLEDRECTANGLE, CmFilledRectangle ), // Changed
EV_COMMAND( CM_EDITELLIPSE, CmEllipse ),
EV_COMMAND( CM_EDITCAPTIONEDELLIPSE, CmCaptionedEllipse ),
EV_COMMAND( CM_EDITFILLEDELLIPSE, CmFilledEllipse ), // Changed
EV_COMMAND( CM_HELPABOUT, CmAbout ),
EV_WM_LBUTTONDOWN,
EV_WM_LBUTTONUP,
EV_WM_RBUTTONDOWN,
EV_WM_MOUSEMOVE,
END_RESPONSE_TABLE;
TGraphWindow::GraphWindowDC::GraphWindowDC( TDC& dc ) :
DC(dc),
Pen(::GetSysColor(COLOR_WINDOWTEXT))
{
OldFlags = DC.SetTextAlign( TA_CENTER );
DC.SelectObject( Pen );
DC.SetBkColor( ::GetSysColor( COLOR_WINDOW ) );
}
TGraphWindow::GraphWindowDC::~GraphWindowDC()
{
DC.RestorePen();
DC.SetTextAlign( OldFlags );
}
TGraphWindow::GraphWindowDC::operator TDC&() const
{
return DC;
}
TGraphWindow::TGraphWindow() :
TWindow( 0, 0, 0 ),
Builder(0),
FileData(OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST,
"Stream Files (*.stm)|*.stm|All Files (*.*)|*.*|",
0, "", "*"),
WindowIsDirty(0)
{
}
void TGraphWindow::DrawObject( GraphicalObject &obj, void *ptr )
{
obj.Draw( *(GraphWindowDC *)ptr );
}
void TGraphWindow::Paint( TDC& dc, BOOL, TRect& )
{
GraphWindowDC gdc(dc);
Objects.ForEach( DrawObject, &gdc );
}
void TGraphWindow::CmNew()
{
if( CheckAndClear() )
Invalidate();
}
void TGraphWindow::CmFileOpen()
{
if( CheckAndClear() )
{
*FileData.FileName = 0;
TFileOpenDialog dlg( this, FileData );
if( dlg.Execute() == IDOK )
{
ReadObjects();
Invalidate();
}
}
}
void TGraphWindow::CmFileSave()
{
SaveFile();
}
int TGraphWindow::SaveFile()
{
if( *FileData.FileName == '\0' )
return SaveFileAs();
else
{
WriteObjects();
return 1;
}
}
void TGraphWindow::CmFileSaveAs()
{
SaveFileAs();
}
int TGraphWindow::SaveFileAs()
{
*FileData.FileName = '\0';
TFileSaveDialog dlg( this, FileData );
if( dlg.Execute() == IDOK )
{
WriteObjects();
return 1;
}
else
return 0;
}
void TGraphWindow::ReadObjects()
{
ifpstream in( FileData.FileName );
int count;
in >> count;
while( count-- != 0 )
{
GraphicalObject *object;
in >> object;
AddObject( object );
}
WindowIsDirty = 0;
}
void TGraphWindow::WriteObject( GraphicalObject& obj, void *data )
{
*(ofpstream *)data << &obj;
}
void TGraphWindow::WriteObjects()
{
ofpstream out( FileData.FileName );
out << Objects.GetItemsInContainer();
Objects.ForEach( WriteObject, &out );
WindowIsDirty = 0;
}
int TGraphWindow::CheckAndClear()
{
if( OkToClear() )
{
FlushObjects();
return 1;
}
else
return 0;
}
int TGraphWindow::OkToClear()
{
if( !WindowIsDirty )
return 1;
else
{
string msg;
if( *FileData.FileName == 0 )
msg = "<untitled>";
else
msg = FileData.FileName;
msg += " has not been saved. Save before closing?";
int res = MessageBox( msg.c_str(), GetApplication()->GetName(),
MB_ICONEXCLAMATION | MB_YESNOCANCEL );
switch( res )
{
case IDYES:
return SaveFile();
case IDNO:
return 1;
case IDCANCEL:
return 0;
}
return 0;
}
}
void TGraphWindow::CmLine()
{
Builder = new LineBuilder( *this );
}
void TGraphWindow::CmRectangle()
{
Builder = new RectangleBuilder( *this );
}
void TGraphWindow::CmCaptionedRectangle()
{
Builder = new CaptionedRectangleBuilder( *this );
}
// Changed
void TGraphWindow::CmFilledRectangle()
{
Builder = new FilledRectangleBuilder( *this );
}
void TGraphWindow::CmEllipse()
{
Builder = new EllipseBuilder( *this );
}
void TGraphWindow::CmCaptionedEllipse()
{
Builder = new CaptionedEllipseBuilder( *this );
}
// Changed
void TGraphWindow::CmFilledEllipse()
{
Builder = new FilledEllipseBuilder( *this );
}
void TGraphWindow::CmAbout()
{
TDialog dlg( this, "About" );
dlg.Execute();
}
BOOL TGraphWindow::CanClose()
{
return CheckAndClear();
}
void TGraphWindow::AddObject( GraphicalObject *object )
{
Objects.Add( object );
WindowIsDirty = 1;
}
void TGraphWindow::FlushObjects()
{
Objects.Flush();
WindowIsDirty = 0;
}
void TGraphWindow::EvLButtonDown( UINT modKeys, TPoint& point )
{
if( Builder == 0 )
TWindow::EvLButtonDown( modKeys, point );
else
Builder->SetAnchor(point);
}
void TGraphWindow::EvLButtonUp( UINT modKeys, TPoint& point )
{
if( Builder == 0 )
TWindow::EvLButtonUp( modKeys, point );
else
{
AddObject( Builder->CreateObject() );
delete Builder;
Builder = 0;
Invalidate();
}
}
void TGraphWindow::EvRButtonDown( UINT modKeys, TPoint& point )
{
if( Builder == 0 )
TWindow::EvRButtonDown( modKeys, point );
else
{
Builder->Cancel();
delete Builder;
Builder = 0;
}
}
void TGraphWindow::EvMouseMove( UINT modKeys, TPoint& point )
{
if( Builder == 0 )
TWindow::EvMouseMove( modKeys, point );
else
Builder->Drag( point );
}
class TStreamApp : public TApplication
{
public:
TStreamApp() : TApplication() {}
void InitMainWindow();
};
void TStreamApp::InitMainWindow()
{
MainWindow = new TFrameWindow( 0, "Streaming Example, version 2",
new TGraphWindow );
MainWindow->AssignMenu("COMMANDS");
}
int OwlMain( int, char ** )
{
TStreamApp app;
return app.Run();
}