home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / PSTREAM.PAK / STREAM1.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  64.0 KB  |  1,683 lines

  1. /*------------------------------------------------------------------------*/
  2. /*                                                                        */
  3. /*  STREAM1.CPP                                                           */
  4. /*                                                                        */
  5. /*  Copyright Borland International, 1993                                 */
  6. /*                                                                        */
  7. /*  Streaming example, version 1                                          */
  8. /*                                                                        */
  9. /*  Streams objects.                                                      */
  10. /*                                                                        */
  11. /*------------------------------------------------------------------------*/
  12. #include <owl/pch.h>
  13. #include <owl/window.h>
  14. #include <owl/dc.h>
  15. #include <owl/applicat.h>
  16. #include <owl/framewin.h>
  17. #include <owl/dialog.h>
  18. #include <owl/opensave.h>       // Changed
  19.  
  20. #include <winsys/wsyscls.h>
  21. #include <winsys/geometry.h>
  22.  
  23. #include <classlib/sets.h>
  24. #include <classlib/objstrm.h>   // Changed
  25.  
  26. #include <new.h>
  27. #include <cstring.h>
  28.  
  29. #include "streams.h"
  30.  
  31. /*------------------------------------------------------------------------*/
  32. /*                                                                        */
  33. /*  class GraphicalObject                                                 */
  34. /*                                                                        */
  35. /*      class GraphicalObject provides the abstract interface             */
  36. /*      to all of the graphical objects that can be displayed             */
  37. /*      by this graphical system.  It should be a virtual base            */
  38. /*      of any class derived from it.                                     */
  39. /*                                                                        */
  40. /*  Member functions:                                                     */
  41. /*                                                                        */
  42. /*      GraphicalObject();                                                */
  43. /*                                                                        */
  44. /*          Creates a GraphicalObject with undefined initial              */
  45. /*          coordinates. Needed only in multiple inheritance when         */
  46. /*          we know that GraphicalObject(const TRect&) will be used       */
  47. /*          by derived classes.                                           */
  48. /*                                                                        */
  49. /*      GraphicalObject( TPoint p1, TPoint p2 );                          */
  50. /*                                                                        */
  51. /*          Creates a GraphicalObject with the location and size          */
  52. /*          specified by p1 and p2.                                       */
  53. /*                                                                        */
  54. /*      virtual ~GraphicalObject();                                       */
  55. /*                                                                        */
  56. /*          Destructor.                                                   */
  57. /*                                                                        */
  58. /*      void Draw( TDC& );                                                */
  59. /*                                                                        */
  60. /*          Does some preliminary setup of the device context, then       */
  61. /*          calls DoDraw() to draw the object.                            */
  62. /*                                                                        */
  63. /*      virtual void DoDraw( TDC& ) = 0;                                  */
  64. /*                                                                        */
  65. /*          Draws the object.  In GraphicalObject this does               */
  66. /*          nothing.  It should be overridden in any class                */
  67. /*          that will be displayed on the screen.                         */
  68. /*                                                                        */
  69. /*      int operator == ( const GraphicalObject& ) const;                 */
  70. /*                                                                        */
  71. /*          This operator must exist so that we can put GraphicalObjects  */
  72. /*          into the Set that is used in TGraphWindow.                    */
  73. /*                                                                        */
  74. /*------------------------------------------------------------------------*/
  75.  
  76. class GraphicalObject : public TStreamableBase  // Changed
  77. {
  78.  
  79. public:
  80.  
  81.     GraphicalObject();
  82.     GraphicalObject( TPoint p1, TPoint p2 );
  83.     virtual ~GraphicalObject();
  84.  
  85.     void Draw( TDC& );
  86.     int operator == ( const GraphicalObject& obj ) const;
  87.  
  88. protected:
  89.  
  90.     TRect bbox;
  91.  
  92. private:
  93.  
  94.     virtual void DoDraw( TDC& ) = 0;
  95.  
  96.     class GraphicalObjectDC
  97.     {
  98.     public:
  99.         GraphicalObjectDC( TDC& dc );
  100.         ~GraphicalObjectDC();
  101.         operator TDC&() const;
  102.     private:
  103.         TDC& DC;
  104.     };
  105.  
  106.     DECLARE_ABSTRACT_STREAMABLE( , GraphicalObject, 1 );// Changed
  107.  
  108. };
  109.  
  110. inline GraphicalObject::GraphicalObject()
  111. {
  112. }
  113.  
  114. inline GraphicalObject::GraphicalObject( TPoint p1, TPoint p2 ) :
  115.     bbox( p1, p2 )
  116. {
  117. }
  118.  
  119. inline GraphicalObject::~GraphicalObject()
  120. {
  121. }
  122.  
  123. void GraphicalObject::Draw( TDC& dc )
  124. {
  125.     GraphicalObjectDC gdc( dc );
  126.     DoDraw( gdc );
  127. }
  128.  
  129. inline int GraphicalObject::operator == ( const GraphicalObject& obj ) const
  130. {
  131.     return this == &obj;
  132. }
  133.  
  134.  
  135. GraphicalObject::GraphicalObjectDC::GraphicalObjectDC( TDC& dc ) : DC(dc)
  136. {
  137.     DC.SelectStockObject( NULL_BRUSH );
  138. }
  139.  
  140. GraphicalObject::GraphicalObjectDC::~GraphicalObjectDC()
  141. {
  142. }
  143.  
  144. GraphicalObject::GraphicalObjectDC::operator TDC&() const
  145. {
  146.     return DC;
  147. }
  148.  
  149. // Changed
  150. IMPLEMENT_CASTABLE( GraphicalObject );
  151. IMPLEMENT_ABSTRACT_STREAMABLE( GraphicalObject );
  152.  
  153. // Changed
  154. void *GraphicalObject::Streamer::Read( ipstream& in, uint32 ) const
  155. {
  156.     in >> GetObject()->bbox;
  157.     return GetObject();
  158. }
  159.  
  160. // Changed
  161. void GraphicalObject::Streamer::Write( opstream& out ) const
  162. {
  163.     out << GetObject()->bbox;
  164. }
  165.  
  166. /*------------------------------------------------------------------------*/
  167. /*                                                                        */
  168. /*  class Line                                                            */
  169. /*                                                                        */
  170. /*      class Line draws a line between two specified points.             */
  171. /*                                                                        */
  172. /*  Member functions:                                                     */
  173. /*                                                                        */
  174. /*      Line( TPoint p1, TPoint p2 );                                     */
  175. /*                                                                        */
  176. /*          Creates a line between the points p1 and p2.                  */
  177. /*                                                                        */
  178. /*      void ImplementDraw( TDC& );                                       */
  179. /*                                                                        */
  180. /*          Draws the line.                                               */
  181. /*                                                                        */
  182. /*      virtual void DoDraw( TDC& );                                      */
  183. /*                                                                        */
  184. /*          Overrides GraphicalObject::DoDraw and draws the line by       */
  185. /*          calling ImplementDraw().                                      */
  186. /*                                                                        */
  187. /*------------------------------------------------------------------------*/
  188.  
  189. class Line : public virtual GraphicalObject
  190. {
  191.  
  192. public:
  193.  
  194.     Line( TPoint p1, TPoint p2 );
  195.  
  196. protected:
  197.  
  198.     void ImplementDraw( TDC& );
  199.  
  200. private:
  201.  
  202.     virtual void DoDraw( TDC& );
  203.  
  204.     DECLARE_STREAMABLE_FROM_BASE( , Line, GraphicalObject );    // Changed
  205.  
  206. };
  207.  
  208. inline Line::Line( TPoint p1, TPoint p2 ) : GraphicalObject( p1, p2 )
  209. {
  210. }
  211.  
  212. void Line::ImplementDraw( TDC& dc )
  213. {
  214.     dc.MoveTo( bbox.left, bbox.top );
  215.     dc.LineTo( bbox.right, bbox.bottom );
  216. }
  217.  
  218. void Line::DoDraw( TDC& dc )
  219. {
  220.     ImplementDraw( dc );
  221. }
  222.  
  223. // Changed
  224. IMPLEMENT_CASTABLE1( Line, GraphicalObject );
  225. IMPLEMENT_STREAMABLE_FROM_BASE( Line, GraphicalObject );
  226.  
  227. /*------------------------------------------------------------------------*/
  228. /*                                                                        */
  229. /*  class TRectangle                                                      */
  230. /*                                                                        */
  231. /*      class TRectangle draws a rectangle.                               */
  232. /*                                                                        */
  233. /*  Member functions:                                                     */
  234. /*                                                                        */
  235. /*      TRectangle( TPoint p1, TPoint p2 );                               */
  236. /*                                                                        */
  237. /*          Creates a TRectangle whose upper left corner is at p1         */
  238. /*          and whose lower right corner is at p2.                        */
  239. /*                                                                        */
  240. /*      void ImplementDraw( TDC& );                                       */
  241. /*                                                                        */
  242. /*          Draws the rectangle.                                          */
  243. /*                                                                        */
  244. /*      virtual void DoDraw( TDC& );                                      */
  245. /*                                                                        */
  246. /*          Overrides GraphicalObject::DoDraw and draws the rectangle by  */
  247. /*          calling ImplementDraw().                                      */
  248. /*                                                                        */
  249. /*------------------------------------------------------------------------*/
  250.  
  251. class TRectangle : public virtual GraphicalObject
  252. {
  253.  
  254. public:
  255.  
  256.     TRectangle( TPoint p1, TPoint p2 );
  257.  
  258. protected:
  259.  
  260.     void ImplementDraw( TDC& );
  261.  
  262. private:
  263.  
  264.     virtual void DoDraw( TDC& );
  265.  
  266.     DECLARE_STREAMABLE_FROM_BASE( , TRectangle, GraphicalObject );  // Changed
  267.  
  268. };
  269.  
  270. inline TRectangle::TRectangle( TPoint p1, TPoint p2 ) :
  271.     GraphicalObject( p1, p2 )
  272. {
  273. }
  274.  
  275. void TRectangle::ImplementDraw( TDC& dc )
  276. {
  277.     dc.Rectangle( bbox );
  278. }
  279.  
  280. void TRectangle::DoDraw( TDC& dc )
  281. {
  282.     ImplementDraw( dc );
  283. }
  284.  
  285. // Changed
  286. IMPLEMENT_CASTABLE1( TRectangle, GraphicalObject );
  287. IMPLEMENT_STREAMABLE_FROM_BASE( TRectangle, GraphicalObject );
  288.  
  289. /*------------------------------------------------------------------------*/
  290. /*                                                                        */
  291. /*  class TEllipse                                                        */
  292. /*                                                                        */
  293. /*      class TEllipse draws an ellipse.                                  */
  294. /*                                                                        */
  295. /*  Member functions:                                                     */
  296. /*                                                                        */
  297. /*      TEllipse( TPoint p1, TPoint p2 );                                 */
  298. /*                                                                        */
  299. /*          Creates a TEllipse whose bounding box is defined by p1 and p2 */
  300. /*                                                                        */
  301. /*      void ImplementDraw( TDC& );                                       */
  302. /*                                                                        */
  303. /*          Draws the ellipse.                                            */
  304. /*                                                                        */
  305. /*      virtual void DoDraw( TDC& );                                      */
  306. /*                                                                        */
  307. /*          Overrides GraphicalObject::DoDraw and draws the ellipse by    */
  308. /*          calling ImplementDraw().                                      */
  309. /*                                                                        */
  310. /*------------------------------------------------------------------------*/
  311.  
  312. class TEllipse : public virtual GraphicalObject
  313. {
  314.  
  315. public:
  316.  
  317.     TEllipse( TPoint p1, TPoint p2 );
  318.  
  319. protected:
  320.  
  321.     void ImplementDraw( TDC& );
  322.  
  323. private:
  324.  
  325.     virtual void DoDraw( TDC& );
  326.  
  327.     DECLARE_STREAMABLE_FROM_BASE( , TEllipse, GraphicalObject );    // Changed
  328.  
  329. };
  330.  
  331. TEllipse::TEllipse( TPoint p1, TPoint p2 ) :
  332.     GraphicalObject( p1, p2 )
  333. {
  334. }
  335.  
  336. void TEllipse::ImplementDraw( TDC& dc )
  337. {
  338.     dc.Ellipse( bbox );
  339. }
  340.  
  341. void TEllipse::DoDraw( TDC& dc )
  342. {
  343.     ImplementDraw( dc );
  344. }
  345.  
  346. // Changed
  347. IMPLEMENT_CASTABLE1( TEllipse, GraphicalObject );
  348. IMPLEMENT_STREAMABLE_FROM_BASE( TEllipse, GraphicalObject );
  349.  
  350. /*------------------------------------------------------------------------*/
  351. /*                                                                        */
  352. /*  class Caption                                                         */
  353. /*                                                                        */
  354. /*      class Caption draws its text on the screen.                       */
  355. /*      Note that Caption is an abstract class.  It                       */
  356. /*      must have a bounding box, but it does not                         */
  357. /*      have a constructor that takes any coordinates.                    */
  358. /*      Each class derived from Caption will provide                      */
  359. /*      a bounding box in the virtual base GraphicalObject.               */
  360. /*                                                                        */
  361. /*  Type definitions:                                                     */
  362. /*                                                                        */
  363. /*      TextLoc                                                           */
  364. /*                                                                        */
  365. /*          An enum used to specify how y-coordinate values               */
  366. /*          should be interpreted when displaying text.                   */
  367. /*                                                                        */
  368. /*  Member functions:                                                     */
  369. /*                                                                        */
  370. /*      Caption( const string& txt, TextLoc where );                      */
  371. /*                                                                        */
  372. /*          Creates a Caption with the specified text,                    */
  373. /*          which will be drawn in its bounding box                       */
  374. /*          at the top, center, or bottom, depending                      */
  375. /*          on the value of its argument 'where'.                         */
  376. /*                                                                        */
  377. /*      virtual void ImplementDraw( TDC& );                               */
  378. /*                                                                        */
  379. /*          Draws the caption.                                            */
  380. /*                                                                        */
  381. /*------------------------------------------------------------------------*/
  382.  
  383. class Caption : public virtual GraphicalObject
  384. {
  385.  
  386. public:
  387.  
  388.     enum TextLoc{ T_TOP, T_CENTER, T_BOTTOM };
  389.  
  390.     Caption( const string& txt, TextLoc where );
  391.  
  392. protected:
  393.  
  394.     void ImplementDraw( TDC& );
  395.  
  396. private:
  397.  
  398.     string Text;
  399.     TextLoc Where;
  400.  
  401.     DECLARE_ABSTRACT_STREAMABLE( , Caption, 1 );// Changed
  402.  
  403. };
  404.  
  405. Caption::Caption( const string& text, TextLoc where ) :
  406.     Text( text ), Where(where)
  407. {
  408. }
  409.  
  410. #pragma warn -def
  411. void Caption::ImplementDraw( TDC& dc )
  412. {
  413.     TEXTMETRIC tm;
  414.     dc.GetTextMetrics(tm);
  415.     int textHeight = tm.tmHeight+tm.tmExternalLeading;
  416.  
  417.     int yDelta;
  418.     switch( Where )
  419.     {
  420.     case T_TOP:
  421.         yDelta = textHeight/2;
  422.         break;
  423.     case T_CENTER:
  424.         yDelta = (bbox.Height()-textHeight)/2;
  425.         break;
  426.     case T_BOTTOM:
  427.         yDelta = bbox.Height()-3*textHeight/2;
  428.         break;
  429.     }
  430.     dc.TextOut( bbox.left+bbox.Width()/2,
  431.                 bbox.top+yDelta,
  432.                 Text.c_str(), Text.length() );
  433. }
  434. #pragma warn .def
  435.  
  436. // Changed
  437. IMPLEMENT_CASTABLE1( Caption, GraphicalObject );
  438. IMPLEMENT_ABSTRACT_STREAMABLE1( Caption, GraphicalObject );
  439.  
  440. // Changed
  441. void *Caption::Streamer::Read( ipstream& in, uint32 ) const
  442. {
  443.     ReadVirtualBase( STATIC_CAST(GraphicalObject *,GetObject()), in );
  444.     int temp;
  445.     in >> GetObject()->Text >> temp;
  446.     GetObject()->Where = TextLoc(temp);
  447.     return GetObject();
  448. }
  449.  
  450. // Changed
  451. void Caption::Streamer::Write( opstream& out ) const
  452. {
  453.     WriteVirtualBase( STATIC_CAST(GraphicalObject *,GetObject()), out );
  454.     out << GetObject()->Text << int(GetObject()->Where);
  455. }
  456.  
  457. /*------------------------------------------------------------------------*/
  458. /*                                                                        */
  459. /*  class CaptionedRectangle                                              */
  460. /*                                                                        */
  461. /*      class CaptionedRectangle draws a rectangle on the                 */
  462. /*      screen, with a caption horizontally centered at the               */
  463. /*      top, in the center, or at the bottom.                             */
  464. /*                                                                        */
  465. /*  Member functions:                                                     */
  466. /*                                                                        */
  467. /*      CaptionedRectangle( TPoint p1, TPoint p2,                         */
  468. /*                          const string& txt,                            */
  469. /*                          TextLoc loc = T_TOP )                         */
  470. /*                                                                        */
  471. /*          Creates a CaptionedRectangle with the specified               */
  472. /*          location, size, and text.                                     */
  473. /*                                                                        */
  474. /*      void ImplementDraw( TDC& );                                       */
  475. /*                                                                        */
  476. /*          Draws the rectangle and its text.                             */
  477. /*                                                                        */
  478. /*      virtual void DoDraw( TDC& );                                      */
  479. /*                                                                        */
  480. /*          Overrides GraphicalObject::DoDraw and draws the rectangle by  */
  481. /*          calling ImplementDraw().                                      */
  482. /*                                                                        */
  483. /*------------------------------------------------------------------------*/
  484.  
  485. class CaptionedRectangle : public TRectangle, public Caption
  486. {
  487.  
  488. public:
  489.  
  490.     CaptionedRectangle( TPoint p1, TPoint p2,
  491.                         const string& txt,
  492.                         TextLoc loc = T_TOP );
  493.  
  494. protected:
  495.  
  496.     void ImplementDraw( TDC& );
  497.  
  498. private:
  499.  
  500.     virtual void DoDraw( TDC& );
  501.  
  502.     DECLARE_STREAMABLE( , CaptionedRectangle, 1 );  // Changed
  503.  
  504. };
  505.  
  506. CaptionedRectangle::CaptionedRectangle( TPoint p1, TPoint p2,
  507.                                         const string& txt,
  508.                                         TextLoc loc ) :
  509.     GraphicalObject( p1, p2 ),
  510.     TRectangle( p1, p2 ),
  511.     Caption( txt, loc )
  512. {
  513. }
  514.  
  515. void CaptionedRectangle::ImplementDraw( TDC& dc )
  516. {
  517.     TRectangle::ImplementDraw( dc );
  518.     Caption::ImplementDraw( dc );
  519. }
  520.  
  521. void CaptionedRectangle::DoDraw( TDC& dc )
  522. {
  523.     ImplementDraw( dc );
  524. }
  525.  
  526. // Changed
  527. IMPLEMENT_CASTABLE2( CaptionedRectangle, TRectangle, Caption );
  528. IMPLEMENT_STREAMABLE3( CaptionedRectangle, TRectangle, Caption, GraphicalObject );
  529.  
  530. // Changed
  531. void *CaptionedRectangle::Streamer::Read( ipstream& in, uint32 ) const
  532. {
  533.     ReadBaseObject( STATIC_CAST(TRectangle *,GetObject()), in );
  534.     ReadBaseObject( STATIC_CAST(Caption *,GetObject()), in );
  535.     return GetObject();
  536. }
  537.  
  538. // Changed
  539. void CaptionedRectangle::Streamer::Write( opstream& out ) const
  540. {
  541.     WriteBaseObject( STATIC_CAST(TRectangle *,GetObject()), out );
  542.     WriteBaseObject( STATIC_CAST(Caption *,GetObject()), out );
  543. }
  544.  
  545. /*------------------------------------------------------------------------*/
  546. /*                                                                        */
  547. /*  class CaptionedEllipse                                                */
  548. /*                                                                        */
  549. /*      class CaptionedEllipse draws an ellipse on the                    */
  550. /*      screen, with a caption centered in the ellipse.                   */
  551. /*                                                                        */
  552. /*  Member functions:                                                     */
  553. /*                                                                        */
  554. /*      CaptionedEllipse( TPoint p1, TPoint p2,                           */
  555. /*                        const string& txt )                             */
  556. /*                                                                        */
  557. /*          Creates a CaptionedEllipse with the specified                 */
  558. /*          bounding box and text.                                        */
  559. /*                                                                        */
  560. /*      void ImplementDraw( TDC& );                                       */
  561. /*                                                                        */
  562. /*          Draws the ellipse and its text.                               */
  563. /*                                                                        */
  564. /*      virtual void DoDraw( TDC& );                                      */
  565. /*                                                                        */
  566. /*          Overrides GraphicalObject::DoDraw and draws the ellipse by    */
  567. /*          calling ImplementDraw().                                      */
  568. /*                                                                        */
  569. /*------------------------------------------------------------------------*/
  570.  
  571. class CaptionedEllipse : public TEllipse, public Caption
  572. {
  573.  
  574. public:
  575.  
  576.     CaptionedEllipse( TPoint p1, TPoint p2, const string& txt );
  577.  
  578. protected:
  579.  
  580.     void ImplementDraw( TDC& );
  581.  
  582. private:
  583.  
  584.     virtual void DoDraw( TDC& );
  585.  
  586.     DECLARE_STREAMABLE( , CaptionedEllipse, 1 );    // Changed
  587.  
  588. };
  589.  
  590. CaptionedEllipse::CaptionedEllipse( TPoint p1, TPoint p2, const string& txt ) :
  591.     GraphicalObject( p1, p2 ),
  592.     TEllipse( p1, p2 ),
  593.     Caption( txt, T_CENTER )
  594. {
  595. }
  596.  
  597. void CaptionedEllipse::ImplementDraw( TDC& dc )
  598. {
  599.     TEllipse::ImplementDraw( dc );
  600.     Caption::ImplementDraw( dc );
  601. }
  602.  
  603. void CaptionedEllipse::DoDraw( TDC& dc )
  604. {
  605.     ImplementDraw( dc );
  606. }
  607.  
  608. // Changed
  609. IMPLEMENT_CASTABLE2( CaptionedEllipse, TEllipse, Caption );
  610. IMPLEMENT_STREAMABLE3( CaptionedEllipse, TEllipse, Caption, GraphicalObject );
  611.  
  612. // Changed
  613. void *CaptionedEllipse::Streamer::Read( ipstream& in, uint32 ) const
  614. {
  615.     ReadBaseObject( STATIC_CAST(TEllipse *,GetObject()), in );
  616.     ReadBaseObject( STATIC_CAST(Caption *,GetObject()), in );
  617.     return GetObject();
  618. }
  619.  
  620. // Changed
  621. void CaptionedEllipse::Streamer::Write( opstream& out ) const
  622. {
  623.     WriteBaseObject( STATIC_CAST(TEllipse *,GetObject()), out );
  624.     WriteBaseObject( STATIC_CAST(Caption *,GetObject()), out );
  625. }
  626.  
  627. /*------------------------------------------------------------------------*/
  628. /*                                                                        */
  629. /*  class TObjectBuilder                                                  */
  630. /*                                                                        */
  631. /*      class TObjectBuilder provides the core functionality for          */
  632. /*      building objects derived from GraphicalObject in a Windows        */
  633. /*      environment. It handles changing the cursor to one that           */
  634. /*      indicates the type of object being built, clipping the cursor     */
  635. /*      so that it stays within the application's client area,            */
  636. /*      handles anchoring the object's bounding box and dragging the      */
  637. /*      unanchored corner of the bounding box.                            */
  638. /*                                                                        */
  639. /*  Public member functions:                                              */
  640. /*                                                                        */
  641. /*      TObjectBuilder( TWindow& owner, int cursorId );                   */
  642. /*                                                                        */
  643. /*          Clips the cursor so that it stays within the owner's          */
  644. /*          client area and replaces the default cursor with the          */
  645. /*          cursor contained in the resource identified by cursorId.      */
  646. /*                                                                        */
  647. /*      ~TObjectBuilder();                                                */
  648. /*                                                                        */
  649. /*          Restores the default cursor and ends the clipping.            */
  650. /*                                                                        */
  651. /*                                                                        */
  652. /*      void SetAnchor( TPoint pos );                                     */
  653. /*                                                                        */
  654. /*          Sets the anchor point of the bounding box to the point pos.   */
  655. /*                                                                        */
  656. /*      void Drag( TPoint pos );                                          */
  657. /*                                                                        */
  658. /*          Moves the unanchored corner of the bounding box to the        */
  659. /*          point pos, drawing the object's skeleton as appropriate.      */
  660. /*          See DrawSkeleton().                                           */
  661. /*                                                                        */
  662. /*      GraphicalObject *CreateObject();                                  */
  663. /*                                                                        */
  664. /*          Returns a pointer to the newly created object derived         */
  665. /*          from GraphicalObject and contained within the bounding box    */
  666. /*          delimited by the anchor point and the unanchored corner as    */
  667. /*          set up by SetAnchor() and Drag() and cleans up whatever       */
  668. /*          needs to be cleaned up. See BuildObject().                    */
  669. /*                                                                        */
  670. /*      void Cancel()                                                     */
  671. /*                                                                        */
  672. /*          Cleans up whatever needs to be cleaned up when the object is  */
  673. /*          not wanted.                                                   */
  674. /*                                                                        */
  675. /*  Protected member functions:                                           */
  676. /*                                                                        */
  677. /*      const TWindow& GetOwner() const;                                  */
  678. /*                                                                        */
  679. /*          Returns a reference to the TWindow that owns the client       */
  680. /*          area that we're drawing to.                                   */
  681. /*                                                                        */
  682. /*  Virtual functions:                                                    */
  683. /*                                                                        */
  684. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const = 0;     */
  685. /*                                                                        */
  686. /*          This must be overridden by the derived class. It is called    */
  687. /*          from Drag() to erase the previously drawn skeleton which      */
  688. /*          was drawn at p1 and p2, and it is called again to draw the    */
  689. /*          new skeleton at positions p1 and p2. The skeleton should be   */
  690. /*          some sort of simple line representation of the object being   */
  691. /*          built.                                                        */
  692. /*                                                                        */
  693. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 ) = 0;         */
  694. /*                                                                        */
  695. /*          Called from CreateObject() to actually build the desired      */
  696. /*          object, with its bounding box defined by p1 and p2. Typically */
  697. /*          this just calls a constructor for the desired object.         */
  698. /*                                                                        */
  699. /*------------------------------------------------------------------------*/
  700.  
  701. class TObjectBuilder
  702. {
  703.  
  704. public:
  705.  
  706.     TObjectBuilder( TWindow& owner, int cursorId );
  707.     virtual ~TObjectBuilder();
  708.  
  709.     void SetAnchor( TPoint pos );
  710.     void Drag( TPoint pos );
  711.     GraphicalObject *CreateObject();
  712.     void Cancel() const;
  713.  
  714. protected:
  715.  
  716.     const TWindow& GetOwner() const { return Owner; }
  717.  
  718.  
  719. private:
  720.  
  721.     class BuilderDC : public TClientDC
  722.     {
  723.     public:
  724.         BuilderDC( HWND wnd );
  725.         ~BuilderDC();
  726.     };
  727.  
  728.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const = 0;
  729.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 ) = 0;
  730.  
  731.     TPoint Anchor;
  732.     TPoint Current;
  733.     int Anchored;
  734.  
  735.     HCURSOR OldCursor;
  736.     TWindow& Owner;
  737.  
  738.     TObjectBuilder( const TObjectBuilder& );
  739.     const TObjectBuilder& operator = ( const TObjectBuilder& );
  740.  
  741. };
  742.  
  743. TObjectBuilder::TObjectBuilder( TWindow& owner, int cursorId ) :
  744.     Owner(owner),
  745.     Anchored(0)
  746. {
  747.     TRect Rect;
  748.     Owner.GetWindowRect( Rect );
  749.     ClipCursor( &Rect );
  750.     Owner.SetCursor( Owner.GetApplication(), cursorId );
  751. }
  752.  
  753. TObjectBuilder::~TObjectBuilder()
  754. {
  755.     Owner.SetCursor( 0, IDC_ARROW );
  756.     ClipCursor(0);
  757. }
  758.  
  759. void TObjectBuilder::SetAnchor( TPoint point )
  760. {
  761.     Anchor = Current = point;
  762.     BuilderDC dc( Owner );
  763.     DrawSkeleton( dc, Anchor, Current );
  764.     Anchored = 1;
  765. }
  766.  
  767. void TObjectBuilder::Drag( TPoint point )
  768. {
  769.     if( Anchored )
  770.         {
  771.         BuilderDC dc( Owner );
  772.         DrawSkeleton( dc, Anchor, Current );
  773.         Current = point;
  774.         DrawSkeleton( dc, Anchor, Current );
  775.         }
  776. }
  777.  
  778. GraphicalObject *TObjectBuilder::CreateObject()
  779. {
  780.     return BuildObject( Anchor, Current );
  781. }
  782.  
  783. void TObjectBuilder::Cancel() const
  784. {
  785.     if( Anchored )
  786.         {
  787.         BuilderDC dc( Owner );
  788.         DrawSkeleton( dc, Anchor, Current );
  789.         }
  790. }
  791.  
  792. TObjectBuilder::BuilderDC::BuilderDC( HWND wnd ) : TClientDC( wnd )
  793. {
  794.     SelectStockObject(WHITE_PEN);
  795.     SetROP2( R2_XORPEN );
  796.     SelectStockObject(NULL_BRUSH);
  797. }
  798.  
  799. TObjectBuilder::BuilderDC::~BuilderDC()
  800. {
  801. }
  802.  
  803. /*------------------------------------------------------------------------*/
  804. /*                                                                        */
  805. /*  class LineBuilder                                                     */
  806. /*                                                                        */
  807. /*      class LineBuilder builds a Line object using the mechanisms       */
  808. /*      provided by TObjectBuilder.                                       */
  809. /*                                                                        */
  810. /*  Member functions:                                                     */
  811. /*                                                                        */
  812. /*      LineBuilder( TWindow& owner );                                    */
  813. /*                                                                        */
  814. /*          Initializes a LineBuilder that will draw its skeleton inside  */
  815. /*          the client area of owner.                                     */
  816. /*                                                                        */
  817. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  818. /*                                                                        */
  819. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  820. /*          for a line, which is just a line from p1 to p2.               */
  821. /*                                                                        */
  822. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  823. /*                                                                        */
  824. /*          Overrides TObjectBuilder::BuildObject to build a Line         */
  825. /*          object with its endpoints at p1 and p2.                       */
  826. /*                                                                        */
  827. /*------------------------------------------------------------------------*/
  828.  
  829. class LineBuilder : public TObjectBuilder
  830. {
  831.  
  832. public:
  833.  
  834.     LineBuilder( TWindow& owner );
  835.  
  836. private:
  837.  
  838.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
  839.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  840.  
  841. };
  842.  
  843. LineBuilder::LineBuilder( TWindow& owner ) :
  844.     TObjectBuilder( owner, LINE_CURSOR )
  845. {
  846. }
  847.  
  848. void LineBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
  849. {
  850.     dc.MoveTo( p1.x, p1.y );
  851.     dc.LineTo( p2.x, p2.y );
  852. }
  853.  
  854. GraphicalObject *LineBuilder::BuildObject( TPoint p1, TPoint p2 )
  855. {
  856.     return new Line( p1, p2 );
  857. }
  858.  
  859. /*------------------------------------------------------------------------*/
  860. /*                                                                        */
  861. /*  class RectangleBuilder                                                */
  862. /*                                                                        */
  863. /*      class RectangleBuilder builds a TRectangle object using the       */
  864. /*      mechanisms provided by TObjectBuilder.                            */
  865. /*                                                                        */
  866. /*  Member functions:                                                     */
  867. /*                                                                        */
  868. /*      RectangleBuilder( TWindow& owner );                               */
  869. /*                                                                        */
  870. /*          Initializes a RectangleBuilder that will draw its skeleton    */
  871. /*          inside the client area of owner.                              */
  872. /*                                                                        */
  873. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  874. /*                                                                        */
  875. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  876. /*          for a TRectangle, which is a rectangle whose upper left       */
  877. /*          corner is at p1 and whose lower right corner is at p2.        */
  878. /*                                                                        */
  879. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  880. /*                                                                        */
  881. /*          Overrides TObjectBuilder::BuildObject to build a TRectangle   */
  882. /*          object with its upper left corner at p1 and its lower right   */
  883. /*          corner at p2.                                                 */
  884. /*                                                                        */
  885. /*------------------------------------------------------------------------*/
  886.  
  887. class RectangleBuilder : public TObjectBuilder
  888. {
  889.  
  890. public:
  891.  
  892.     RectangleBuilder( TWindow& owner );
  893.  
  894. private:
  895.  
  896.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
  897.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  898.  
  899. };
  900.  
  901. RectangleBuilder::RectangleBuilder( TWindow& owner ) :
  902.     TObjectBuilder( owner, RECT_CURSOR )
  903. {
  904. }
  905.  
  906. void RectangleBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
  907. {
  908.     dc.Rectangle( p1, p2 );
  909. }
  910.  
  911. GraphicalObject *RectangleBuilder::BuildObject( TPoint p1, TPoint p2 )
  912. {
  913.     return new TRectangle( p1, p2 );
  914. }
  915.  
  916. /*------------------------------------------------------------------------*/
  917. /*                                                                        */
  918. /*  class EllipseBuilder                                                  */
  919. /*                                                                        */
  920. /*      class EllipseBuilder builds a TEllipse object using the           */
  921. /*      mechanisms provided by TObjectBuilder.                            */
  922. /*                                                                        */
  923. /*  Member functions:                                                     */
  924. /*                                                                        */
  925. /*      EllipseBuilder( TWindow& owner );                                 */
  926. /*                                                                        */
  927. /*          Initializes an EllipseBuilder that will draw its skeleton     */
  928. /*          inside the client area of owner.                              */
  929. /*                                                                        */
  930. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  931. /*                                                                        */
  932. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  933. /*          for a TEllipse, which is an ellipse with a bounding box whose */
  934. /*          upper left corner is at p1 and whose lower right corner is    */
  935. /*          at p2.                                                        */
  936. /*                                                                        */
  937. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  938. /*                                                                        */
  939. /*          Overrides TObjectBuilder::BuildObject to build a TEllipse     */
  940. /*          object with a bounding box whose upper left corner is at p1   */
  941. /*          and whose lower right corner is at p2.                        */
  942. /*                                                                        */
  943. /*------------------------------------------------------------------------*/
  944.  
  945. class EllipseBuilder : public TObjectBuilder
  946. {
  947.  
  948. public:
  949.  
  950.     EllipseBuilder( TWindow& owner );
  951.  
  952. private:
  953.  
  954.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
  955.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  956.  
  957. };
  958.  
  959. EllipseBuilder::EllipseBuilder( TWindow& owner ) :
  960.     TObjectBuilder( owner, ELLIPSE_CURSOR )
  961. {
  962. }
  963.  
  964. void EllipseBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
  965.  
  966. {
  967.     dc.Ellipse( p1, p2 );
  968. }
  969.  
  970. GraphicalObject *EllipseBuilder::BuildObject( TPoint p1, TPoint p2 )
  971. {
  972.     return new TEllipse( p1, p2 );
  973. }
  974.  
  975. /*------------------------------------------------------------------------*/
  976. /*                                                                        */
  977. /*  class CaptionBuilder                                                  */
  978. /*                                                                        */
  979. /*      class CaptionBuilder provides a base class for use by builders    */
  980. /*      of captioned objects. It does not inherit from TObjectBuilder.    */
  981. /*      It is expected that this class will be mixed in with a class      */
  982. /*      that does inherit from TObjectBuilder. See, for example,          */
  983. /*      CaptionedRectangleBuilder.                                        */
  984. /*                                                                        */
  985. /*  Member functions:                                                     */
  986. /*                                                                        */
  987. /*      CaptionBuilder( TWindow& owner, int allowPosition );              */
  988. /*                                                                        */
  989. /*          Initializes a CaptionBuilder that will belong to the TWindow  */
  990. /*          owner. allowPosition is a flag that indicates whether the     */
  991. /*          user should be allowed to specify the placement of the        */
  992. /*          caption. If allowPosition is non-zero, the dialog box that    */
  993. /*          prompts for the caption also allows the user to specify       */
  994. /*          whether the caption should be at the top, in the center, or   */
  995. /*          at the bottom of the object. If allowPosition is 0 this       */
  996. /*          part of the dialog box is grayed out.                         */
  997. /*                                                                        */
  998. /*      string GetCaption();                                              */
  999. /*                                                                        */
  1000. /*          Retrieves the text of the caption specified by the user. If   */
  1001. /*          the user hasn't been asked for the caption yet GetCaption()   */
  1002. /*          puts up a dialog box requesting input from the user.          */
  1003. /*                                                                        */
  1004. /*      Caption::TextLoc GetLocation();                                   */
  1005. /*                                                                        */
  1006. /*          Retrieves the location for the caption specified by the user. */
  1007. /*          If the user hasn't been asked for the caption yet             */
  1008. /*          GetLocation() puts up a dialog box requesting input from the  */
  1009. /*          user. If allowPosition was 0 GetLocation() returns T_TOP.     */
  1010. /*                                                                        */
  1011. /*------------------------------------------------------------------------*/
  1012.  
  1013. class CaptionBuilder
  1014. {
  1015.  
  1016. public:
  1017.  
  1018.     CaptionBuilder( TWindow& owner, int allowPosition = 1 );
  1019.     string GetCaption();
  1020.     Caption::TextLoc GetLocation();
  1021.  
  1022. private:
  1023.  
  1024.     void GetData();
  1025.     int HaveData;
  1026.     string Caption;
  1027.     Caption::TextLoc Location;
  1028.     TWindow& Owner;
  1029.     int AllowPosition;
  1030.  
  1031. public:
  1032.     class CaptionDialog : public TDialog
  1033.     {
  1034.     public:
  1035.         CaptionDialog( TWindow& parent, CaptionBuilder& builder );
  1036.         bool CanClose();
  1037.         void SetupWindow();
  1038.     private:
  1039.         void TopClicked();
  1040.         void CenterClicked();
  1041.         void BottomClicked();
  1042.         CaptionBuilder& Builder;
  1043.     DECLARE_RESPONSE_TABLE( CaptionDialog );
  1044.     };
  1045.  
  1046.     friend CaptionDialog;
  1047.  
  1048. };
  1049.  
  1050. CaptionBuilder::CaptionBuilder( TWindow& owner, int allowPosition ) :
  1051.     HaveData(0),
  1052.     Location(Caption::T_TOP),
  1053.     Owner(owner),
  1054.     AllowPosition(allowPosition)
  1055. {
  1056. }
  1057.  
  1058. void CaptionBuilder::GetData()
  1059. {
  1060.     if( !HaveData )
  1061.         {
  1062.         CaptionDialog dialog( Owner, *this );
  1063.         dialog.Execute();
  1064.         HaveData = 1;
  1065.         }
  1066. }
  1067.  
  1068. string CaptionBuilder::GetCaption()
  1069. {
  1070.     GetData();
  1071.     return Caption;
  1072. }
  1073.  
  1074. Caption::TextLoc CaptionBuilder::GetLocation()
  1075. {
  1076.     GetData();
  1077.     return Location;
  1078. }
  1079.  
  1080. DEFINE_RESPONSE_TABLE1( CaptionBuilder::CaptionDialog, TDialog )
  1081.     EV_CHILD_NOTIFY( IDD_TOP, BN_CLICKED, TopClicked ),
  1082.     EV_CHILD_NOTIFY( IDD_CENTER, BN_CLICKED, CenterClicked ),
  1083.     EV_CHILD_NOTIFY( IDD_BOTTOM, BN_CLICKED, BottomClicked ),
  1084. END_RESPONSE_TABLE;
  1085.  
  1086. CaptionBuilder::CaptionDialog::CaptionDialog( TWindow& parent, CaptionBuilder& builder ) :
  1087.     TDialog( &parent, "CaptionDlg" ),
  1088.     Builder(builder)
  1089. {
  1090. }
  1091.  
  1092. void CaptionBuilder::CaptionDialog::SetupWindow()
  1093. {
  1094.     if( Builder.AllowPosition )
  1095.         SendDlgItemMessage( IDD_TOP, BM_SETCHECK, 1, 0L );
  1096.     else
  1097.         {
  1098.         ::EnableWindow( GetDlgItem( IDD_TOP ), 0 );
  1099.         ::EnableWindow( GetDlgItem( IDD_CENTER ), 0 );
  1100.         ::EnableWindow( GetDlgItem( IDD_BOTTOM ), 0 );
  1101.         ::EnableWindow( GetDlgItem( IDD_POSITIONBOX ), 0 );
  1102.         }
  1103. }
  1104.  
  1105. bool CaptionBuilder::CaptionDialog::CanClose()
  1106. {
  1107.     char buf[256];
  1108.     GetDlgItemText( IDD_INPUTEDITBOX, buf, sizeof(buf) );
  1109.     Builder.Caption = buf;
  1110.     return true;
  1111. }
  1112.  
  1113. void CaptionBuilder::CaptionDialog::TopClicked()
  1114. {
  1115.     Builder.Location = Caption::T_TOP;
  1116. }
  1117.  
  1118. void CaptionBuilder::CaptionDialog::CenterClicked()
  1119. {
  1120.     Builder.Location = Caption::T_CENTER;
  1121. }
  1122.  
  1123. void CaptionBuilder::CaptionDialog::BottomClicked()
  1124. {
  1125.     Builder.Location = Caption::T_BOTTOM;
  1126. }
  1127.  
  1128. /*------------------------------------------------------------------------*/
  1129. /*                                                                        */
  1130. /*  class CaptionedRectangleBuilder                                       */
  1131. /*                                                                        */
  1132. /*      class CaptionedRectangleBuilder builds a CaptionedRectangle       */
  1133. /*      object using the mechanisms provided by TObjectBuilder.           */
  1134. /*                                                                        */
  1135. /*  Member functions:                                                     */
  1136. /*                                                                        */
  1137. /*      CaptionedRectangleBuilder( TWindow& owner );                      */
  1138. /*                                                                        */
  1139. /*          Initializes a CaptionedRectangleBuilder that will draw its    */
  1140. /*          skeleton inside the client area of owner and prompt for the   */
  1141. /*          caption after the bounding box has been defined.              */
  1142. /*                                                                        */
  1143. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  1144. /*                                                                        */
  1145. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  1146. /*          for a CaptionedRectangle, which is a rectangle whose upper    */
  1147. /*          left corner is at p1 and whose lower right corner is at p2.   */
  1148. /*                                                                        */
  1149. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  1150. /*                                                                        */
  1151. /*          Overrides TObjectBuilder::BuildObject to build a              */
  1152. /*          CaptionedRectangle object with its upper left corner at p1    */
  1153. /*          and its lower right corner at p2.                             */
  1154. /*                                                                        */
  1155. /*------------------------------------------------------------------------*/
  1156.  
  1157. class CaptionedRectangleBuilder : public RectangleBuilder, private CaptionBuilder
  1158. {
  1159.  
  1160. public:
  1161.  
  1162.     CaptionedRectangleBuilder( TWindow& owner );
  1163.  
  1164. private:
  1165.  
  1166.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  1167.  
  1168. };
  1169.  
  1170. CaptionedRectangleBuilder::CaptionedRectangleBuilder( TWindow& owner ) :
  1171.     RectangleBuilder( owner ),
  1172.     CaptionBuilder( owner )
  1173. {
  1174. }
  1175.  
  1176. GraphicalObject *CaptionedRectangleBuilder::BuildObject( TPoint p1, TPoint p2 )
  1177. {
  1178.     return new CaptionedRectangle( p1, p2, GetCaption(), GetLocation() );
  1179. }
  1180.  
  1181. /*------------------------------------------------------------------------*/
  1182. /*                                                                        */
  1183. /*  class CaptionedEllipseBuilder                                         */
  1184. /*                                                                        */
  1185. /*      class CaptionedEllipseBuilder builds a CaptionedEllipse           */
  1186. /*      object using the mechanisms provided by TObjectBuilder.           */
  1187. /*                                                                        */
  1188. /*  Member functions:                                                     */
  1189. /*                                                                        */
  1190. /*      CaptionedEllipseBuilder( TWindow& owner );                        */
  1191. /*                                                                        */
  1192. /*          Initializes a CaptionedRectangleBuilder that will draw its    */
  1193. /*          skeleton inside the client area of owner and prompt for the   */
  1194. /*          caption after the bounding box has been defined.              */
  1195. /*                                                                        */
  1196. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  1197. /*                                                                        */
  1198. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  1199. /*          for a CaptionedEllipse, which is an ellipse with a bounding   */
  1200. /*          box whose upper left corner is at p1 and whose lower right    */
  1201. /*          corner is at p2.                                              */
  1202. /*                                                                        */
  1203. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  1204. /*                                                                        */
  1205. /*          Overrides TObjectBuilder::BuildObject to build a              */
  1206. /*          CaptionedEllipse object with a bounding box whose upper left  */
  1207. /*          corner is at p1 and whose lower right corner is at p2.        */
  1208. /*                                                                        */
  1209. /*------------------------------------------------------------------------*/
  1210.  
  1211. class CaptionedEllipseBuilder : public EllipseBuilder, public CaptionBuilder
  1212. {
  1213.  
  1214. public:
  1215.  
  1216.     CaptionedEllipseBuilder( TWindow& owner );
  1217.  
  1218. private:
  1219.  
  1220.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  1221.  
  1222. };
  1223.  
  1224. CaptionedEllipseBuilder::CaptionedEllipseBuilder( TWindow& owner ) :
  1225.     EllipseBuilder( owner ),
  1226.     CaptionBuilder( owner, 0 )
  1227. {
  1228. }
  1229.  
  1230. GraphicalObject *CaptionedEllipseBuilder::BuildObject( TPoint p1, TPoint p2 )
  1231. {
  1232.     return new CaptionedEllipse( p1, p2, GetCaption() );
  1233. }
  1234.  
  1235. /*------------------------------------------------------------------------*/
  1236. /*                                                                        */
  1237. /*  class TGraphWindow                                                    */
  1238. /*                                                                        */
  1239. /*      class TGraphWindow pulls all of the forgoing together into a      */
  1240. /*      rather limited shape editor. It uses a TISetAsVector to hold      */
  1241. /*      the various objects that are in the current drawing.              */
  1242. /*                                                                        */
  1243. /*  Member functions:                                                     */
  1244. /*                                                                        */
  1245. /*      TGraphWindow();                                                   */
  1246. /*                                                                        */
  1247. /*          Initializes the window.                                       */
  1248. /*                                                                        */
  1249. /*      void Paint( TDC&, bool, TRect& );                                 */
  1250. /*                                                                        */
  1251. /*          Called whenever the window receives a WM_PAINT message. Draws */
  1252. /*          the objects by calling each of their Draw() functions.        */
  1253. /*                                                                        */
  1254. /*      void CmNew();                                                     */
  1255. /*                                                                        */
  1256. /*          Called when the user selects File/New from the menu. Removes  */
  1257. /*          all objects from the current drawing.                         */
  1258. /*                                                                        */
  1259. /*      void CmLine();                                                    */
  1260. /*                                                                        */
  1261. /*          Called when the user selects Edit/Line from the menu. Adds    */
  1262. /*          a line to the drawing.                                        */
  1263. /*                                                                        */
  1264. /*      void CmRectangle();                                               */
  1265. /*                                                                        */
  1266. /*          Called when the user selects Edit/Rectangle from the menu.    */
  1267. /*          Adds a rectangle to the drawing.                              */
  1268. /*                                                                        */
  1269. /*      void CmCaptionedRectangle();                                      */
  1270. /*                                                                        */
  1271. /*          Called when the user selects Edit/CaptionedRectangle from the */
  1272. /*          menu. Adds a captioned rectangle to the drawing.              */
  1273. /*                                                                        */
  1274. /*      void CmEllipse();                                                 */
  1275. /*                                                                        */
  1276. /*          Called when the user selects Edit/Ellipse from the menu.      */
  1277. /*          Adds an ellipse to the drawing.                               */
  1278. /*                                                                        */
  1279. /*      void CmCaptionedEllipse();                                        */
  1280. /*                                                                        */
  1281. /*          Called when the user selects Edit/CaptionedEllipse from the   */
  1282. /*          menu. Adds a captioned ellipse to the drawing.                */
  1283. /*                                                                        */
  1284. /*      void CmAbout();                                                   */
  1285. /*                                                                        */
  1286. /*          Called when the user selects Help/About from the menu.        */
  1287. /*          Displays the About box.                                       */
  1288. /*                                                                        */
  1289. /*      void EvLButtonDown();                                             */
  1290. /*                                                                        */
  1291. /*          Called when the user presses the left mouse button. During    */
  1292. /*          building of an object, this anchors the object's bounding     */
  1293. /*          box at the current position of the mouse.                     */
  1294. /*                                                                        */
  1295. /*      void EvLButtonUp();                                               */
  1296. /*                                                                        */
  1297. /*          Called when the user releases the left mouse button. During   */
  1298. /*          building of an object, this creates the actual object with    */
  1299. /*          its bounding box defined by the previous anchor position and  */
  1300. /*          the current position of the mouse.                            */
  1301. /*                                                                        */
  1302. /*      void EvRButtonDown();                                             */
  1303. /*                                                                        */
  1304. /*          Called when the user presses the right mouse button. During   */
  1305. /*          building of an object, this terminates building.              */
  1306. /*                                                                        */
  1307. /*      void EvMouseMove();                                               */
  1308. /*                                                                        */
  1309. /*          Called when the user moves the mouse. During building of an   */
  1310. /*          object, if the object's bounding box has been anchored, this  */
  1311. /*          drags the free corner of the bounding box.                    */
  1312. /*                                                                        */
  1313. /*------------------------------------------------------------------------*/
  1314.  
  1315. class TGraphWindow : public TWindow
  1316. {
  1317.  
  1318. public:
  1319.  
  1320.     TGraphWindow();
  1321.  
  1322.     void Paint(TDC&, bool, TRect&);
  1323.  
  1324.     void CmNew();
  1325.     void CmLine();
  1326.     void CmRectangle();
  1327.     void CmCaptionedRectangle();
  1328.     void CmEllipse();
  1329.     void CmCaptionedEllipse();
  1330.     void CmAbout();
  1331.  
  1332.     void CmFileOpen();      // Changed
  1333.     void CmFileSave();      // Changed
  1334.     void CmFileSaveAs();    // Changed
  1335.  
  1336.     void EvLButtonDown( UINT modKeys, TPoint& point );
  1337.     void EvLButtonUp( UINT modKeys, TPoint& point );
  1338.     void EvRButtonDown( UINT modKeys, TPoint& point );
  1339.     void EvMouseMove( UINT modKeys, TPoint& point );
  1340.  
  1341.     bool CanClose();    // Changed
  1342.  
  1343.     TOpenSaveDialog::TData FileData;    // Changed
  1344.  
  1345. private:
  1346.  
  1347.     int SaveFile();         // Changed
  1348.     int SaveFileAs();       // Changed
  1349.     void ReadObjects();     // Changed
  1350.     void WriteObjects();    // Changed
  1351.     int CheckAndClear();    // Changed
  1352.     int OkToClear();        // Changed
  1353.     static void WriteObject( GraphicalObject &obj, void * );    // Changed
  1354.  
  1355.     TObjectBuilder *Builder;
  1356.  
  1357.     void FlushObjects();
  1358.     void AddObject( GraphicalObject *obj );
  1359.     static void DrawObject( GraphicalObject &obj, void * );
  1360.     TISetAsVector<GraphicalObject> Objects;
  1361.  
  1362.     int WindowIsDirty;          // Changed
  1363.  
  1364.     class GraphWindowDC
  1365.     {
  1366.     public:
  1367.         GraphWindowDC( TDC& );
  1368.         ~GraphWindowDC();
  1369.         operator TDC&() const;
  1370.     private:
  1371.         TDC& DC;
  1372.         uint OldFlags;
  1373.         TPen Pen;
  1374.     };
  1375.  
  1376.     DECLARE_RESPONSE_TABLE(TGraphWindow);
  1377.  
  1378. };
  1379.  
  1380. DEFINE_RESPONSE_TABLE1( TGraphWindow, TWindow )
  1381.     EV_COMMAND( CM_FILENEW, CmNew ),
  1382.     EV_COMMAND( CM_FILEOPEN, CmFileOpen ),      // Changed
  1383.     EV_COMMAND( CM_FILESAVE, CmFileSave ),      // Changed
  1384.     EV_COMMAND( CM_FILESAVEAS, CmFileSaveAs ),  // Changed
  1385.     EV_COMMAND( CM_EDITLINE, CmLine ),
  1386.     EV_COMMAND( CM_EDITRECTANGLE, CmRectangle ),
  1387.     EV_COMMAND( CM_EDITCAPTIONEDRECTANGLE, CmCaptionedRectangle ),
  1388.     EV_COMMAND( CM_EDITELLIPSE, CmEllipse ),
  1389.     EV_COMMAND( CM_EDITCAPTIONEDELLIPSE, CmCaptionedEllipse ),
  1390.     EV_COMMAND( CM_HELPABOUT, CmAbout ),
  1391.     EV_WM_LBUTTONDOWN,
  1392.     EV_WM_LBUTTONUP,
  1393.     EV_WM_RBUTTONDOWN,
  1394.     EV_WM_MOUSEMOVE,
  1395. END_RESPONSE_TABLE;
  1396.  
  1397. TGraphWindow::GraphWindowDC::GraphWindowDC( TDC& dc ) :
  1398.     DC(dc),
  1399.     Pen(::GetSysColor(COLOR_WINDOWTEXT))
  1400. {
  1401.     OldFlags = DC.SetTextAlign( TA_CENTER );
  1402.     DC.SelectObject( Pen );
  1403.     DC.SetBkColor( ::GetSysColor( COLOR_WINDOW ) );
  1404. }
  1405.  
  1406. TGraphWindow::GraphWindowDC::~GraphWindowDC()
  1407. {
  1408.     DC.RestorePen();
  1409.     DC.SetTextAlign( OldFlags );
  1410. }
  1411.  
  1412. TGraphWindow::GraphWindowDC::operator TDC&() const
  1413. {
  1414.     return DC;
  1415. }
  1416.  
  1417. // Changed
  1418. TGraphWindow::TGraphWindow() :
  1419.     TWindow( 0, 0, 0 ),
  1420.     Builder(0),
  1421.     FileData(OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST,
  1422.              "Stream Files (*.stm)|*.stm|All Files (*.*)|*.*|",
  1423.              0, "", "*"),
  1424.     WindowIsDirty(0)
  1425. {
  1426. }
  1427.  
  1428. void TGraphWindow::DrawObject( GraphicalObject &obj, void *ptr )
  1429. {
  1430.     obj.Draw( *(GraphWindowDC *)ptr );
  1431. }
  1432.  
  1433. void TGraphWindow::Paint( TDC& dc, bool, TRect& )
  1434. {
  1435.     GraphWindowDC gdc(dc);
  1436.     Objects.ForEach( DrawObject, &gdc );
  1437. }
  1438.  
  1439. void TGraphWindow::CmNew()
  1440. {
  1441.     if( CheckAndClear() )
  1442.         Invalidate();
  1443. }
  1444.  
  1445. // Changed
  1446. void TGraphWindow::CmFileOpen()
  1447. {
  1448.     if( CheckAndClear() )
  1449.         {
  1450.         *FileData.FileName = 0;
  1451.         TFileOpenDialog dlg( this, FileData );
  1452.         if( dlg.Execute() == IDOK )
  1453.             {
  1454.             ReadObjects();
  1455.             Invalidate();
  1456.             }
  1457.         }
  1458. }
  1459.  
  1460. // Changed
  1461. void TGraphWindow::CmFileSave()
  1462. {
  1463.     SaveFile();
  1464. }
  1465.  
  1466. // Changed
  1467. int TGraphWindow::SaveFile()
  1468. {
  1469.     if( *FileData.FileName == '\0' )
  1470.         return SaveFileAs();
  1471.     else
  1472.         {
  1473.         WriteObjects();
  1474.         return 1;
  1475.         }
  1476. }
  1477.  
  1478. // Changed
  1479. void TGraphWindow::CmFileSaveAs()
  1480. {
  1481.     SaveFileAs();
  1482. }
  1483.  
  1484. // Changed
  1485. int TGraphWindow::SaveFileAs()
  1486. {
  1487.     *FileData.FileName = '\0';
  1488.     TFileSaveDialog dlg( this, FileData );
  1489.     if( dlg.Execute() == IDOK )
  1490.         {
  1491.         WriteObjects();
  1492.         return 1;
  1493.         }
  1494.     else
  1495.         return 0;
  1496. }
  1497.  
  1498. // Changed
  1499. void TGraphWindow::ReadObjects()
  1500. {
  1501.     ifpstream in( FileData.FileName );
  1502.     int count;
  1503.     in >> count;
  1504.     while( count-- != 0 )
  1505.         {
  1506.         GraphicalObject *object;
  1507.         in >> object;
  1508.         AddObject( object );
  1509.         }
  1510.     WindowIsDirty = 0;
  1511. }
  1512.  
  1513. // Changed
  1514. void TGraphWindow::WriteObject( GraphicalObject& obj, void *data )
  1515. {
  1516.     *(ofpstream *)data << &obj;
  1517. }
  1518.  
  1519. // Changed
  1520. void TGraphWindow::WriteObjects()
  1521. {
  1522.     ofpstream out( FileData.FileName );
  1523.     out << Objects.GetItemsInContainer();
  1524.     Objects.ForEach( WriteObject, &out );
  1525.     WindowIsDirty = 0;
  1526. }
  1527.  
  1528. // Changed
  1529. int TGraphWindow::CheckAndClear()
  1530. {
  1531.     if( OkToClear() )
  1532.         {
  1533.         FlushObjects();
  1534.         return 1;
  1535.         }
  1536.     else
  1537.         return 0;
  1538. }
  1539.  
  1540. // Changed
  1541. int TGraphWindow::OkToClear()
  1542. {
  1543.     if( !WindowIsDirty )
  1544.         return 1;
  1545.     else
  1546.         {
  1547.         string msg;
  1548.         if( *FileData.FileName == 0 )
  1549.             msg = "<untitled>";
  1550.         else
  1551.             msg = FileData.FileName;
  1552.         msg += " has not been saved. Save before closing?";
  1553.         int res = MessageBox( msg.c_str(), GetApplication()->GetName(),
  1554.                               MB_ICONEXCLAMATION | MB_YESNOCANCEL );
  1555.         switch( res )
  1556.             {
  1557.             case IDYES:
  1558.                 return SaveFile();
  1559.             case IDNO:
  1560.                 return 1;
  1561.             case IDCANCEL:
  1562.                 return 0;
  1563.             }
  1564.         return 0;
  1565.         }
  1566. }
  1567.  
  1568. void TGraphWindow::CmLine()
  1569. {
  1570.     Builder = new LineBuilder( *this );
  1571. }
  1572.  
  1573. void TGraphWindow::CmRectangle()
  1574. {
  1575.     Builder = new RectangleBuilder( *this );
  1576. }
  1577.  
  1578. void TGraphWindow::CmCaptionedRectangle()
  1579. {
  1580.     Builder = new CaptionedRectangleBuilder( *this );
  1581. }
  1582.  
  1583. void TGraphWindow::CmEllipse()
  1584. {
  1585.     Builder = new EllipseBuilder( *this );
  1586. }
  1587.  
  1588. void TGraphWindow::CmCaptionedEllipse()
  1589. {
  1590.     Builder = new CaptionedEllipseBuilder( *this );
  1591. }
  1592.  
  1593. void TGraphWindow::CmAbout()
  1594. {
  1595.     TDialog dlg( this, "About" );
  1596.     dlg.Execute();
  1597. }
  1598.  
  1599. // Changed
  1600. bool TGraphWindow::CanClose()
  1601. {
  1602.     return CheckAndClear();
  1603. }
  1604.  
  1605. void TGraphWindow::AddObject( GraphicalObject *object )
  1606. {
  1607.     Objects.Add( object );
  1608.     WindowIsDirty = 1;      // Changed
  1609. }
  1610.  
  1611. void TGraphWindow::FlushObjects()
  1612. {
  1613.     Objects.Flush();
  1614.     WindowIsDirty = 0;      // Changed
  1615. }
  1616.  
  1617. void TGraphWindow::EvLButtonDown( UINT modKeys, TPoint& point )
  1618. {
  1619.     if( Builder == 0 )
  1620.         TWindow::EvLButtonDown( modKeys, point );
  1621.     else
  1622.         Builder->SetAnchor(point);
  1623. }
  1624.  
  1625. void TGraphWindow::EvLButtonUp( UINT modKeys, TPoint& point )
  1626. {
  1627.     if( Builder == 0 )
  1628.         TWindow::EvLButtonUp( modKeys, point );
  1629.     else
  1630.         {
  1631.         AddObject( Builder->CreateObject() );
  1632.         delete Builder;
  1633.         Builder = 0;
  1634.         Invalidate();
  1635.         }
  1636. }
  1637.  
  1638. void TGraphWindow::EvRButtonDown( UINT modKeys, TPoint& point )
  1639. {
  1640.     if( Builder == 0 )
  1641.         TWindow::EvRButtonDown( modKeys, point );
  1642.     else
  1643.         {
  1644.         Builder->Cancel();
  1645.         delete Builder;
  1646.         Builder = 0;
  1647.         }
  1648. }
  1649.  
  1650. void TGraphWindow::EvMouseMove( UINT modKeys, TPoint& point )
  1651. {
  1652.     if( Builder == 0 )
  1653.         TWindow::EvMouseMove( modKeys, point );
  1654.     else
  1655.         Builder->Drag( point );
  1656. }
  1657.  
  1658. class TStreamApp : public TApplication
  1659. {
  1660.  
  1661. public:
  1662.  
  1663.     TStreamApp() : TApplication() {}
  1664.  
  1665.     void InitMainWindow();
  1666.  
  1667. };
  1668.  
  1669. void TStreamApp::InitMainWindow()
  1670. {
  1671.     MainWindow = new TFrameWindow( 0, "Streaming Example, version 1",
  1672.                                    new TGraphWindow );
  1673.     MainWindow->AssignMenu("COMMANDS");
  1674. }
  1675.  
  1676. int OwlMain( int, char ** )
  1677. {
  1678.     TStreamApp app;
  1679.     return app.Run();
  1680. }
  1681.  
  1682.  
  1683.