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