home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 20.ddi / PSTREAMS.PAK / STREAM1.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  63.9 KB  |  1,679 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. void Caption::ImplementDraw( TDC& dc )
  410. {
  411.     TEXTMETRIC tm;
  412.     dc.GetTextMetrics(tm);
  413.     WORD textHeight = tm.tmHeight+tm.tmExternalLeading;
  414.  
  415.     int yDelta;
  416.     switch( Where )
  417.     {
  418.     case T_TOP:
  419.         yDelta = textHeight/2;
  420.         break;
  421.     case T_CENTER:
  422.         yDelta = (bbox.Height()-textHeight)/2;
  423.         break;
  424.     case T_BOTTOM:
  425.         yDelta = bbox.Height()-3*textHeight/2;
  426.         break;
  427.     }
  428.     dc.TextOut( bbox.left+bbox.Width()/2,
  429.                 bbox.top+yDelta,
  430.                 Text.c_str(), Text.length() );
  431. }
  432.  
  433. // Changed
  434. IMPLEMENT_CASTABLE1( Caption, GraphicalObject );
  435. IMPLEMENT_ABSTRACT_STREAMABLE1( Caption, GraphicalObject );
  436.  
  437. // Changed
  438. void *Caption::Streamer::Read( ipstream& in, uint32 ) const
  439. {
  440.     ReadVirtualBase( STATIC_CAST(GraphicalObject *,GetObject()), in );
  441.     int temp;
  442.     in >> GetObject()->Text >> temp;
  443.     GetObject()->Where = TextLoc(temp);
  444.     return GetObject();
  445. }
  446.  
  447. // Changed
  448. void Caption::Streamer::Write( opstream& out ) const
  449. {
  450.     WriteVirtualBase( STATIC_CAST(GraphicalObject *,GetObject()), out );
  451.     out << GetObject()->Text << int(GetObject()->Where);
  452. }
  453.  
  454. /*------------------------------------------------------------------------*/
  455. /*                                                                        */
  456. /*  class CaptionedRectangle                                              */
  457. /*                                                                        */
  458. /*      class CaptionedRectangle draws a rectangle on the                 */
  459. /*      screen, with a caption horizontally centered at the               */
  460. /*      top, in the center, or at the bottom.                             */
  461. /*                                                                        */
  462. /*  Member functions:                                                     */
  463. /*                                                                        */
  464. /*      CaptionedRectangle( TPoint p1, TPoint p2,                         */
  465. /*                          const string& txt,                            */
  466. /*                          TextLoc loc = T_TOP )                         */
  467. /*                                                                        */
  468. /*          Creates a CaptionedRectangle with the specified               */
  469. /*          location, size, and text.                                     */
  470. /*                                                                        */
  471. /*      void ImplementDraw( TDC& );                                       */
  472. /*                                                                        */
  473. /*          Draws the rectangle and its text.                             */
  474. /*                                                                        */
  475. /*      virtual void DoDraw( TDC& );                                      */
  476. /*                                                                        */
  477. /*          Overrides GraphicalObject::DoDraw and draws the rectangle by  */
  478. /*          calling ImplementDraw().                                      */
  479. /*                                                                        */
  480. /*------------------------------------------------------------------------*/
  481.  
  482. class CaptionedRectangle : public TRectangle, public Caption
  483. {
  484.  
  485. public:
  486.  
  487.     CaptionedRectangle( TPoint p1, TPoint p2,
  488.                         const string& txt,
  489.                         TextLoc loc = T_TOP );
  490.  
  491. protected:
  492.  
  493.     void ImplementDraw( TDC& );
  494.  
  495. private:
  496.  
  497.     virtual void DoDraw( TDC& );
  498.  
  499.     DECLARE_STREAMABLE( , CaptionedRectangle, 1 );  // Changed
  500.  
  501. };
  502.  
  503. CaptionedRectangle::CaptionedRectangle( TPoint p1, TPoint p2,
  504.                                         const string& txt,
  505.                                         TextLoc loc ) :
  506.     GraphicalObject( p1, p2 ),
  507.     TRectangle( p1, p2 ),
  508.     Caption( txt, loc )
  509. {
  510. }
  511.  
  512. void CaptionedRectangle::ImplementDraw( TDC& dc )
  513. {
  514.     TRectangle::ImplementDraw( dc );
  515.     Caption::ImplementDraw( dc );
  516. }
  517.  
  518. void CaptionedRectangle::DoDraw( TDC& dc )
  519. {
  520.     ImplementDraw( dc );
  521. }
  522.  
  523. // Changed
  524. IMPLEMENT_CASTABLE2( CaptionedRectangle, TRectangle, Caption );
  525. IMPLEMENT_STREAMABLE3( CaptionedRectangle, TRectangle, Caption, GraphicalObject );
  526.  
  527. // Changed
  528. void *CaptionedRectangle::Streamer::Read( ipstream& in, uint32 ) const
  529. {
  530.     ReadBaseObject( STATIC_CAST(TRectangle *,GetObject()), in );
  531.     ReadBaseObject( STATIC_CAST(Caption *,GetObject()), in );
  532.     return GetObject();
  533. }
  534.  
  535. // Changed
  536. void CaptionedRectangle::Streamer::Write( opstream& out ) const
  537. {
  538.     WriteBaseObject( STATIC_CAST(TRectangle *,GetObject()), out );
  539.     WriteBaseObject( STATIC_CAST(Caption *,GetObject()), out );
  540. }
  541.  
  542. /*------------------------------------------------------------------------*/
  543. /*                                                                        */
  544. /*  class CaptionedEllipse                                                */
  545. /*                                                                        */
  546. /*      class CaptionedEllipse draws an ellipse on the                    */
  547. /*      screen, with a caption centered in the ellipse.                   */
  548. /*                                                                        */
  549. /*  Member functions:                                                     */
  550. /*                                                                        */
  551. /*      CaptionedEllipse( TPoint p1, TPoint p2,                           */
  552. /*                        const string& txt )                             */
  553. /*                                                                        */
  554. /*          Creates a CaptionedEllipse with the specified                 */
  555. /*          bounding box and text.                                        */
  556. /*                                                                        */
  557. /*      void ImplementDraw( TDC& );                                       */
  558. /*                                                                        */
  559. /*          Draws the ellipse and its text.                               */
  560. /*                                                                        */
  561. /*      virtual void DoDraw( TDC& );                                      */
  562. /*                                                                        */
  563. /*          Overrides GraphicalObject::DoDraw and draws the ellipse by    */
  564. /*          calling ImplementDraw().                                      */
  565. /*                                                                        */
  566. /*------------------------------------------------------------------------*/
  567.  
  568. class CaptionedEllipse : public TEllipse, public Caption
  569. {
  570.  
  571. public:
  572.  
  573.     CaptionedEllipse( TPoint p1, TPoint p2, const string& txt );
  574.  
  575. protected:
  576.  
  577.     void ImplementDraw( TDC& );
  578.  
  579. private:
  580.  
  581.     virtual void DoDraw( TDC& );
  582.  
  583.     DECLARE_STREAMABLE( , CaptionedEllipse, 1 );    // Changed
  584.  
  585. };
  586.  
  587. CaptionedEllipse::CaptionedEllipse( TPoint p1, TPoint p2, const string& txt ) :
  588.     GraphicalObject( p1, p2 ),
  589.     TEllipse( p1, p2 ),
  590.     Caption( txt, T_CENTER )
  591. {
  592. }
  593.  
  594. void CaptionedEllipse::ImplementDraw( TDC& dc )
  595. {
  596.     TEllipse::ImplementDraw( dc );
  597.     Caption::ImplementDraw( dc );
  598. }
  599.  
  600. void CaptionedEllipse::DoDraw( TDC& dc )
  601. {
  602.     ImplementDraw( dc );
  603. }
  604.  
  605. // Changed
  606. IMPLEMENT_CASTABLE2( CaptionedEllipse, TEllipse, Caption );
  607. IMPLEMENT_STREAMABLE3( CaptionedEllipse, TEllipse, Caption, GraphicalObject );
  608.  
  609. // Changed
  610. void *CaptionedEllipse::Streamer::Read( ipstream& in, uint32 ) const
  611. {
  612.     ReadBaseObject( STATIC_CAST(TEllipse *,GetObject()), in );
  613.     ReadBaseObject( STATIC_CAST(Caption *,GetObject()), in );
  614.     return GetObject();
  615. }
  616.  
  617. // Changed
  618. void CaptionedEllipse::Streamer::Write( opstream& out ) const
  619. {
  620.     WriteBaseObject( STATIC_CAST(TEllipse *,GetObject()), out );
  621.     WriteBaseObject( STATIC_CAST(Caption *,GetObject()), out );
  622. }
  623.  
  624. /*------------------------------------------------------------------------*/
  625. /*                                                                        */
  626. /*  class TObjectBuilder                                                  */
  627. /*                                                                        */
  628. /*      class TObjectBuilder provides the core functionality for          */
  629. /*      building objects derived from GraphicalObject in a Windows        */
  630. /*      environment. It handles changing the cursor to one that           */
  631. /*      indicates the type of object being built, clipping the cursor     */
  632. /*      so that it stays within the application's client area,            */
  633. /*      handles anchoring the object's bounding box and dragging the      */
  634. /*      unanchored corner of the bounding box.                            */
  635. /*                                                                        */
  636. /*  Public member functions:                                              */
  637. /*                                                                        */
  638. /*      TObjectBuilder( TWindow& owner, int cursorId );                   */
  639. /*                                                                        */
  640. /*          Clips the cursor so that it stays within the owner's          */
  641. /*          client area and replaces the default cursor with the          */
  642. /*          cursor contained in the resource identified by cursorId.      */
  643. /*                                                                        */
  644. /*      ~TObjectBuilder();                                                */
  645. /*                                                                        */
  646. /*          Restores the default cursor and ends the clipping.            */
  647. /*                                                                        */
  648. /*                                                                        */
  649. /*      void SetAnchor( TPoint pos );                                     */
  650. /*                                                                        */
  651. /*          Sets the anchor point of the bounding box to the point pos.   */
  652. /*                                                                        */
  653. /*      void Drag( TPoint pos );                                          */
  654. /*                                                                        */
  655. /*          Moves the unanchored corner of the bounding box to the        */
  656. /*          point pos, drawing the object's skeleton as appropriate.      */
  657. /*          See DrawSkeleton().                                           */
  658. /*                                                                        */
  659. /*      GraphicalObject *CreateObject();                                  */
  660. /*                                                                        */
  661. /*          Returns a pointer to the newly created object derived         */
  662. /*          from GraphicalObject and contained within the bounding box    */
  663. /*          delimited by the anchor point and the unanchored corner as    */
  664. /*          set up by SetAnchor() and Drag() and cleans up whatever       */
  665. /*          needs to be cleaned up. See BuildObject().                    */
  666. /*                                                                        */
  667. /*      void Cancel()                                                     */
  668. /*                                                                        */
  669. /*          Cleans up whatever needs to be cleaned up when the object is  */
  670. /*          not wanted.                                                   */
  671. /*                                                                        */
  672. /*  Protected member functions:                                           */
  673. /*                                                                        */
  674. /*      const TWindow& GetOwner() const;                                  */
  675. /*                                                                        */
  676. /*          Returns a reference to the TWindow that owns the client       */
  677. /*          area that we're drawing to.                                   */
  678. /*                                                                        */
  679. /*  Virtual functions:                                                    */
  680. /*                                                                        */
  681. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const = 0;     */
  682. /*                                                                        */
  683. /*          This must be overridden by the derived class. It is called    */
  684. /*          from Drag() to erase the previously drawn skeleton which      */
  685. /*          was drawn at p1 and p2, and it is called again to draw the    */
  686. /*          new skeleton at positions p1 and p2. The skeleton should be   */
  687. /*          some sort of simple line representation of the object being   */
  688. /*          built.                                                        */
  689. /*                                                                        */
  690. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 ) = 0;         */
  691. /*                                                                        */
  692. /*          Called from CreateObject() to actually build the desired      */
  693. /*          object, with its bounding box defined by p1 and p2. Typically */
  694. /*          this just calls a constructor for the desired object.         */
  695. /*                                                                        */
  696. /*------------------------------------------------------------------------*/
  697.  
  698. class TObjectBuilder
  699. {
  700.  
  701. public:
  702.  
  703.     TObjectBuilder( TWindow& owner, int cursorId );
  704.     virtual ~TObjectBuilder();
  705.  
  706.     void SetAnchor( TPoint pos );
  707.     void Drag( TPoint pos );
  708.     GraphicalObject *CreateObject();
  709.     void Cancel() const;
  710.  
  711. protected:
  712.  
  713.     const TWindow& GetOwner() const { return Owner; }
  714.  
  715.  
  716. private:
  717.  
  718.     class BuilderDC : public TClientDC
  719.     {
  720.     public:
  721.         BuilderDC( HWND wnd );
  722.         ~BuilderDC();
  723.     };
  724.  
  725.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const = 0;
  726.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 ) = 0;
  727.  
  728.     TPoint Anchor;
  729.     TPoint Current;
  730.     int Anchored;
  731.  
  732.     HCURSOR OldCursor;
  733.     TWindow& Owner;
  734.  
  735.     TObjectBuilder( const TObjectBuilder& );
  736.     const TObjectBuilder& operator = ( const TObjectBuilder& );
  737.  
  738. };
  739.  
  740. TObjectBuilder::TObjectBuilder( TWindow& owner, int cursorId ) :
  741.     Owner(owner),
  742.     Anchored(0)
  743. {
  744.     TRect Rect;
  745.     Owner.GetWindowRect( Rect );
  746.     ClipCursor( &Rect );
  747.     Owner.SetCursor( Owner.GetApplication(), cursorId );
  748. }
  749.  
  750. TObjectBuilder::~TObjectBuilder()
  751. {
  752.     Owner.SetCursor( 0, IDC_ARROW );
  753.     ClipCursor(0);
  754. }
  755.  
  756. void TObjectBuilder::SetAnchor( TPoint point )
  757. {
  758.     Anchor = Current = point;
  759.     BuilderDC dc( Owner );
  760.     DrawSkeleton( dc, Anchor, Current );
  761.     Anchored = 1;
  762. }
  763.  
  764. void TObjectBuilder::Drag( TPoint point )
  765. {
  766.     if( Anchored )
  767.         {
  768.         BuilderDC dc( Owner );
  769.         DrawSkeleton( dc, Anchor, Current );
  770.         Current = point;
  771.         DrawSkeleton( dc, Anchor, Current );
  772.         }
  773. }
  774.  
  775. GraphicalObject *TObjectBuilder::CreateObject()
  776. {
  777.     return BuildObject( Anchor, Current );
  778. }
  779.  
  780. void TObjectBuilder::Cancel() const
  781. {
  782.     if( Anchored )
  783.         {
  784.         BuilderDC dc( Owner );
  785.         DrawSkeleton( dc, Anchor, Current );
  786.         }
  787. }
  788.  
  789. TObjectBuilder::BuilderDC::BuilderDC( HWND wnd ) : TClientDC( wnd )
  790. {
  791.     SelectStockObject(WHITE_PEN);
  792.     SetROP2( R2_XORPEN );
  793.     SelectStockObject(NULL_BRUSH);
  794. }
  795.  
  796. TObjectBuilder::BuilderDC::~BuilderDC()
  797. {
  798. }
  799.  
  800. /*------------------------------------------------------------------------*/
  801. /*                                                                        */
  802. /*  class LineBuilder                                                     */
  803. /*                                                                        */
  804. /*      class LineBuilder builds a Line object using the mechanisms       */
  805. /*      provided by TObjectBuilder.                                       */
  806. /*                                                                        */
  807. /*  Member functions:                                                     */
  808. /*                                                                        */
  809. /*      LineBuilder( TWindow& owner );                                    */
  810. /*                                                                        */
  811. /*          Initializes a LineBuilder that will draw its skeleton inside  */
  812. /*          the client area of owner.                                     */
  813. /*                                                                        */
  814. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  815. /*                                                                        */
  816. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  817. /*          for a line, which is just a line from p1 to p2.               */
  818. /*                                                                        */
  819. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  820. /*                                                                        */
  821. /*          Overrides TObjectBuilder::BuildObject to build a Line         */
  822. /*          object with its endpoints at p1 and p2.                       */
  823. /*                                                                        */
  824. /*------------------------------------------------------------------------*/
  825.  
  826. class LineBuilder : public TObjectBuilder
  827. {
  828.  
  829. public:
  830.  
  831.     LineBuilder( TWindow& owner );
  832.  
  833. private:
  834.  
  835.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
  836.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  837.  
  838. };
  839.  
  840. LineBuilder::LineBuilder( TWindow& owner ) :
  841.     TObjectBuilder( owner, LINE_CURSOR )
  842. {
  843. }
  844.  
  845. void LineBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
  846. {
  847.     dc.MoveTo( p1.x, p1.y );
  848.     dc.LineTo( p2.x, p2.y );
  849. }
  850.  
  851. GraphicalObject *LineBuilder::BuildObject( TPoint p1, TPoint p2 )
  852. {
  853.     return new Line( p1, p2 );
  854. }
  855.  
  856. /*------------------------------------------------------------------------*/
  857. /*                                                                        */
  858. /*  class RectangleBuilder                                                */
  859. /*                                                                        */
  860. /*      class RectangleBuilder builds a TRectangle object using the       */
  861. /*      mechanisms provided by TObjectBuilder.                            */
  862. /*                                                                        */
  863. /*  Member functions:                                                     */
  864. /*                                                                        */
  865. /*      RectangleBuilder( TWindow& owner );                               */
  866. /*                                                                        */
  867. /*          Initializes a RectangleBuilder that will draw its skeleton    */
  868. /*          inside the client area of owner.                              */
  869. /*                                                                        */
  870. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  871. /*                                                                        */
  872. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  873. /*          for a TRectangle, which is a rectangle whose upper left       */
  874. /*          corner is at p1 and whose lower right corner is at p2.        */
  875. /*                                                                        */
  876. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  877. /*                                                                        */
  878. /*          Overrides TObjectBuilder::BuildObject to build a TRectangle   */
  879. /*          object with its upper left corner at p1 and its lower right   */
  880. /*          corner at p2.                                                 */
  881. /*                                                                        */
  882. /*------------------------------------------------------------------------*/
  883.  
  884. class RectangleBuilder : public TObjectBuilder
  885. {
  886.  
  887. public:
  888.  
  889.     RectangleBuilder( TWindow& owner );
  890.  
  891. private:
  892.  
  893.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
  894.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  895.  
  896. };
  897.  
  898. RectangleBuilder::RectangleBuilder( TWindow& owner ) :
  899.     TObjectBuilder( owner, RECT_CURSOR )
  900. {
  901. }
  902.  
  903. void RectangleBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
  904. {
  905.     dc.Rectangle( p1, p2 );
  906. }
  907.  
  908. GraphicalObject *RectangleBuilder::BuildObject( TPoint p1, TPoint p2 )
  909. {
  910.     return new TRectangle( p1, p2 );
  911. }
  912.  
  913. /*------------------------------------------------------------------------*/
  914. /*                                                                        */
  915. /*  class EllipseBuilder                                                  */
  916. /*                                                                        */
  917. /*      class EllipseBuilder builds a TEllipse object using the           */
  918. /*      mechanisms provided by TObjectBuilder.                            */
  919. /*                                                                        */
  920. /*  Member functions:                                                     */
  921. /*                                                                        */
  922. /*      EllipseBuilder( TWindow& owner );                                 */
  923. /*                                                                        */
  924. /*          Initializes an EllipseBuilder that will draw its skeleton     */
  925. /*          inside the client area of owner.                              */
  926. /*                                                                        */
  927. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  928. /*                                                                        */
  929. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  930. /*          for a TEllipse, which is an ellipse with a bounding box whose */
  931. /*          upper left corner is at p1 and whose lower right corner is    */
  932. /*          at p2.                                                        */
  933. /*                                                                        */
  934. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  935. /*                                                                        */
  936. /*          Overrides TObjectBuilder::BuildObject to build a TEllipse     */
  937. /*          object with a bounding box whose upper left corner is at p1   */
  938. /*          and whose lower right corner is at p2.                        */
  939. /*                                                                        */
  940. /*------------------------------------------------------------------------*/
  941.  
  942. class EllipseBuilder : public TObjectBuilder
  943. {
  944.  
  945. public:
  946.  
  947.     EllipseBuilder( TWindow& owner );
  948.  
  949. private:
  950.  
  951.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
  952.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  953.  
  954. };
  955.  
  956. EllipseBuilder::EllipseBuilder( TWindow& owner ) :
  957.     TObjectBuilder( owner, ELLIPSE_CURSOR )
  958. {
  959. }
  960.  
  961. void EllipseBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
  962.  
  963. {
  964.     dc.Ellipse( p1, p2 );
  965. }
  966.  
  967. GraphicalObject *EllipseBuilder::BuildObject( TPoint p1, TPoint p2 )
  968. {
  969.     return new TEllipse( p1, p2 );
  970. }
  971.  
  972. /*------------------------------------------------------------------------*/
  973. /*                                                                        */
  974. /*  class CaptionBuilder                                                  */
  975. /*                                                                        */
  976. /*      class CaptionBuilder provides a base class for use by builders    */
  977. /*      of captioned objects. It does not inherit from TObjectBuilder.    */
  978. /*      It is expected that this class will be mixed in with a class      */
  979. /*      that does inherit from TObjectBuilder. See, for example,          */
  980. /*      CaptionedRectangleBuilder.                                        */
  981. /*                                                                        */
  982. /*  Member functions:                                                     */
  983. /*                                                                        */
  984. /*      CaptionBuilder( TWindow& owner, int allowPosition );              */
  985. /*                                                                        */
  986. /*          Initializes a CaptionBuilder that will belong to the TWindow  */
  987. /*          owner. allowPosition is a flag that indicates whether the     */
  988. /*          user should be allowed to specify the placement of the        */
  989. /*          caption. If allowPosition is non-zero, the dialog box that    */
  990. /*          prompts for the caption also allows the user to specify       */
  991. /*          whether the caption should be at the top, in the center, or   */
  992. /*          at the bottom of the object. If allowPosition is 0 this       */
  993. /*          part of the dialog box is grayed out.                         */
  994. /*                                                                        */
  995. /*      string GetCaption();                                              */
  996. /*                                                                        */
  997. /*          Retrieves the text of the caption specified by the user. If   */
  998. /*          the user hasn't been asked for the caption yet GetCaption()   */
  999. /*          puts up a dialog box requesting input from the user.          */
  1000. /*                                                                        */
  1001. /*      Caption::TextLoc GetLocation();                                   */
  1002. /*                                                                        */
  1003. /*          Retrieves the location for the caption specified by the user. */
  1004. /*          If the user hasn't been asked for the caption yet             */
  1005. /*          GetLocation() puts up a dialog box requesting input from the  */
  1006. /*          user. If allowPosition was 0 GetLocation() returns T_TOP.     */
  1007. /*                                                                        */
  1008. /*------------------------------------------------------------------------*/
  1009.  
  1010. class CaptionBuilder
  1011. {
  1012.  
  1013. public:
  1014.  
  1015.     CaptionBuilder( TWindow& owner, int allowPosition = 1 );
  1016.     string GetCaption();
  1017.     Caption::TextLoc GetLocation();
  1018.  
  1019. private:
  1020.  
  1021.     void GetData();
  1022.     int HaveData;
  1023.     string Caption;
  1024.     Caption::TextLoc Location;
  1025.     TWindow& Owner;
  1026.     int AllowPosition;
  1027.  
  1028.     class CaptionDialog : public TDialog
  1029.     {
  1030.     public:
  1031.         CaptionDialog( TWindow& parent, CaptionBuilder& builder );
  1032.         BOOL CanClose();
  1033.         void SetupWindow();
  1034.     private:
  1035.         void TopClicked();
  1036.         void CenterClicked();
  1037.         void BottomClicked();
  1038.         CaptionBuilder& Builder;
  1039.     DECLARE_RESPONSE_TABLE( CaptionDialog );
  1040.     };
  1041.  
  1042.     friend CaptionDialog;
  1043.  
  1044. };
  1045.  
  1046. CaptionBuilder::CaptionBuilder( TWindow& owner, int allowPosition ) :
  1047.     HaveData(0),
  1048.     Location(Caption::T_TOP),
  1049.     Owner(owner),
  1050.     AllowPosition(allowPosition)
  1051. {
  1052. }
  1053.  
  1054. void CaptionBuilder::GetData()
  1055. {
  1056.     if( !HaveData )
  1057.         {
  1058.         CaptionDialog dialog( Owner, *this );
  1059.         dialog.Execute();
  1060.         HaveData = 1;
  1061.         }
  1062. }
  1063.  
  1064. string CaptionBuilder::GetCaption()
  1065. {
  1066.     GetData();
  1067.     return Caption;
  1068. }
  1069.  
  1070. Caption::TextLoc CaptionBuilder::GetLocation()
  1071. {
  1072.     GetData();
  1073.     return Location;
  1074. }
  1075.  
  1076. DEFINE_RESPONSE_TABLE1( CaptionBuilder::CaptionDialog, TDialog )
  1077.     EV_CHILD_NOTIFY( IDD_TOP, BN_CLICKED, TopClicked ),
  1078.     EV_CHILD_NOTIFY( IDD_CENTER, BN_CLICKED, CenterClicked ),
  1079.     EV_CHILD_NOTIFY( IDD_BOTTOM, BN_CLICKED, BottomClicked ),
  1080. END_RESPONSE_TABLE;
  1081.  
  1082. CaptionBuilder::CaptionDialog::CaptionDialog( TWindow& parent, CaptionBuilder& builder ) :
  1083.     TDialog( &parent, "CaptionDlg" ),
  1084.     Builder(builder)
  1085. {
  1086. }
  1087.  
  1088. void CaptionBuilder::CaptionDialog::SetupWindow()
  1089. {
  1090.     if( Builder.AllowPosition )
  1091.         SendDlgItemMessage( IDD_TOP, BM_SETCHECK, 1, 0L );
  1092.     else
  1093.         {
  1094.         ::EnableWindow( GetDlgItem( IDD_TOP ), 0 );
  1095.         ::EnableWindow( GetDlgItem( IDD_CENTER ), 0 );
  1096.         ::EnableWindow( GetDlgItem( IDD_BOTTOM ), 0 );
  1097.         ::EnableWindow( GetDlgItem( IDD_POSITIONBOX ), 0 );
  1098.         }
  1099. }
  1100.  
  1101. BOOL CaptionBuilder::CaptionDialog::CanClose()
  1102. {
  1103.     char buf[256];
  1104.     GetDlgItemText( IDD_INPUTEDITBOX, buf, sizeof(buf) );
  1105.     Builder.Caption = buf;
  1106.     return TRUE;
  1107. }
  1108.  
  1109. void CaptionBuilder::CaptionDialog::TopClicked()
  1110. {
  1111.     Builder.Location = Caption::T_TOP;
  1112. }
  1113.  
  1114. void CaptionBuilder::CaptionDialog::CenterClicked()
  1115. {
  1116.     Builder.Location = Caption::T_CENTER;
  1117. }
  1118.  
  1119. void CaptionBuilder::CaptionDialog::BottomClicked()
  1120. {
  1121.     Builder.Location = Caption::T_BOTTOM;
  1122. }
  1123.  
  1124. /*------------------------------------------------------------------------*/
  1125. /*                                                                        */
  1126. /*  class CaptionedRectangleBuilder                                       */
  1127. /*                                                                        */
  1128. /*      class CaptionedRectangleBuilder builds a CaptionedRectangle       */
  1129. /*      object using the mechanisms provided by TObjectBuilder.           */
  1130. /*                                                                        */
  1131. /*  Member functions:                                                     */
  1132. /*                                                                        */
  1133. /*      CaptionedRectangleBuilder( TWindow& owner );                      */
  1134. /*                                                                        */
  1135. /*          Initializes a CaptionedRectangleBuilder that will draw its    */
  1136. /*          skeleton inside the client area of owner and prompt for the   */
  1137. /*          caption after the bounding box has been defined.              */
  1138. /*                                                                        */
  1139. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  1140. /*                                                                        */
  1141. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  1142. /*          for a CaptionedRectangle, which is a rectangle whose upper    */
  1143. /*          left corner is at p1 and whose lower right corner is at p2.   */
  1144. /*                                                                        */
  1145. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  1146. /*                                                                        */
  1147. /*          Overrides TObjectBuilder::BuildObject to build a              */
  1148. /*          CaptionedRectangle object with its upper left corner at p1    */
  1149. /*          and its lower right corner at p2.                             */
  1150. /*                                                                        */
  1151. /*------------------------------------------------------------------------*/
  1152.  
  1153. class CaptionedRectangleBuilder : public RectangleBuilder, private CaptionBuilder
  1154. {
  1155.  
  1156. public:
  1157.  
  1158.     CaptionedRectangleBuilder( TWindow& owner );
  1159.  
  1160. private:
  1161.  
  1162.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  1163.  
  1164. };
  1165.  
  1166. CaptionedRectangleBuilder::CaptionedRectangleBuilder( TWindow& owner ) :
  1167.     RectangleBuilder( owner ),
  1168.     CaptionBuilder( owner )
  1169. {
  1170. }
  1171.  
  1172. GraphicalObject *CaptionedRectangleBuilder::BuildObject( TPoint p1, TPoint p2 )
  1173. {
  1174.     return new CaptionedRectangle( p1, p2, GetCaption(), GetLocation() );
  1175. }
  1176.  
  1177. /*------------------------------------------------------------------------*/
  1178. /*                                                                        */
  1179. /*  class CaptionedEllipseBuilder                                         */
  1180. /*                                                                        */
  1181. /*      class CaptionedEllipseBuilder builds a CaptionedEllipse           */
  1182. /*      object using the mechanisms provided by TObjectBuilder.           */
  1183. /*                                                                        */
  1184. /*  Member functions:                                                     */
  1185. /*                                                                        */
  1186. /*      CaptionedEllipseBuilder( TWindow& owner );                        */
  1187. /*                                                                        */
  1188. /*          Initializes a CaptionedRectangleBuilder that will draw its    */
  1189. /*          skeleton inside the client area of owner and prompt for the   */
  1190. /*          caption after the bounding box has been defined.              */
  1191. /*                                                                        */
  1192. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  1193. /*                                                                        */
  1194. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  1195. /*          for a CaptionedEllipse, which is an ellipse with a bounding   */
  1196. /*          box whose upper left corner is at p1 and whose lower right    */
  1197. /*          corner is at p2.                                              */
  1198. /*                                                                        */
  1199. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  1200. /*                                                                        */
  1201. /*          Overrides TObjectBuilder::BuildObject to build a              */
  1202. /*          CaptionedEllipse object with a bounding box whose upper left  */
  1203. /*          corner is at p1 and whose lower right corner is at p2.        */
  1204. /*                                                                        */
  1205. /*------------------------------------------------------------------------*/
  1206.  
  1207. class CaptionedEllipseBuilder : public EllipseBuilder, public CaptionBuilder
  1208. {
  1209.  
  1210. public:
  1211.  
  1212.     CaptionedEllipseBuilder( TWindow& owner );
  1213.  
  1214. private:
  1215.  
  1216.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  1217.  
  1218. };
  1219.  
  1220. CaptionedEllipseBuilder::CaptionedEllipseBuilder( TWindow& owner ) :
  1221.     EllipseBuilder( owner ),
  1222.     CaptionBuilder( owner, 0 )
  1223. {
  1224. }
  1225.  
  1226. GraphicalObject *CaptionedEllipseBuilder::BuildObject( TPoint p1, TPoint p2 )
  1227. {
  1228.     return new CaptionedEllipse( p1, p2, GetCaption() );
  1229. }
  1230.  
  1231. /*------------------------------------------------------------------------*/
  1232. /*                                                                        */
  1233. /*  class TGraphWindow                                                    */
  1234. /*                                                                        */
  1235. /*      class TGraphWindow pulls all of the forgoing together into a      */
  1236. /*      rather limited shape editor. It uses a TISetAsVector to hold      */
  1237. /*      the various objects that are in the current drawing.              */
  1238. /*                                                                        */
  1239. /*  Member functions:                                                     */
  1240. /*                                                                        */
  1241. /*      TGraphWindow();                                                   */
  1242. /*                                                                        */
  1243. /*          Initializes the window.                                       */
  1244. /*                                                                        */
  1245. /*      void Paint( TDC&, BOOL, TRect& );                                 */
  1246. /*                                                                        */
  1247. /*          Called whenever the window receives a WM_PAINT message. Draws */
  1248. /*          the objects by calling each of their Draw() functions.        */
  1249. /*                                                                        */
  1250. /*      void CmNew();                                                     */
  1251. /*                                                                        */
  1252. /*          Called when the user selects File/New from the menu. Removes  */
  1253. /*          all objects from the current drawing.                         */
  1254. /*                                                                        */
  1255. /*      void CmLine();                                                    */
  1256. /*                                                                        */
  1257. /*          Called when the user selects Edit/Line from the menu. Adds    */
  1258. /*          a line to the drawing.                                        */
  1259. /*                                                                        */
  1260. /*      void CmRectangle();                                               */
  1261. /*                                                                        */
  1262. /*          Called when the user selects Edit/Rectangle from the menu.    */
  1263. /*          Adds a rectangle to the drawing.                              */
  1264. /*                                                                        */
  1265. /*      void CmCaptionedRectangle();                                      */
  1266. /*                                                                        */
  1267. /*          Called when the user selects Edit/CaptionedRectangle from the */
  1268. /*          menu. Adds a captioned rectangle to the drawing.              */
  1269. /*                                                                        */
  1270. /*      void CmEllipse();                                                 */
  1271. /*                                                                        */
  1272. /*          Called when the user selects Edit/Ellipse from the menu.      */
  1273. /*          Adds an ellipse to the drawing.                               */
  1274. /*                                                                        */
  1275. /*      void CmCaptionedEllipse();                                        */
  1276. /*                                                                        */
  1277. /*          Called when the user selects Edit/CaptionedEllipse from the   */
  1278. /*          menu. Adds a captioned ellipse to the drawing.                */
  1279. /*                                                                        */
  1280. /*      void CmAbout();                                                   */
  1281. /*                                                                        */
  1282. /*          Called when the user selects Help/About from the menu.        */
  1283. /*          Displays the About box.                                       */
  1284. /*                                                                        */
  1285. /*      void EvLButtonDown();                                             */
  1286. /*                                                                        */
  1287. /*          Called when the user presses the left mouse button. During    */
  1288. /*          building of an object, this anchors the object's bounding     */
  1289. /*          box at the current position of the mouse.                     */
  1290. /*                                                                        */
  1291. /*      void EvLButtonUp();                                               */
  1292. /*                                                                        */
  1293. /*          Called when the user releases the left mouse button. During   */
  1294. /*          building of an object, this creates the actual object with    */
  1295. /*          its bounding box defined by the previous anchor position and  */
  1296. /*          the current position of the mouse.                            */
  1297. /*                                                                        */
  1298. /*      void EvRButtonDown();                                             */
  1299. /*                                                                        */
  1300. /*          Called when the user presses the right mouse button. During   */
  1301. /*          building of an object, this terminates building.              */
  1302. /*                                                                        */
  1303. /*      void EvMouseMove();                                               */
  1304. /*                                                                        */
  1305. /*          Called when the user moves the mouse. During building of an   */
  1306. /*          object, if the object's bounding box has been anchored, this  */
  1307. /*          drags the free corner of the bounding box.                    */
  1308. /*                                                                        */
  1309. /*------------------------------------------------------------------------*/
  1310.  
  1311. class TGraphWindow : public TWindow
  1312. {
  1313.  
  1314. public:
  1315.  
  1316.     TGraphWindow();
  1317.  
  1318.     void Paint(TDC&, BOOL, TRect&);
  1319.  
  1320.     void CmNew();
  1321.     void CmLine();
  1322.     void CmRectangle();
  1323.     void CmCaptionedRectangle();
  1324.     void CmEllipse();
  1325.     void CmCaptionedEllipse();
  1326.     void CmAbout();
  1327.  
  1328.     void CmFileOpen();      // Changed
  1329.     void CmFileSave();      // Changed
  1330.     void CmFileSaveAs();    // Changed
  1331.  
  1332.     void EvLButtonDown( UINT modKeys, TPoint& point );
  1333.     void EvLButtonUp( UINT modKeys, TPoint& point );
  1334.     void EvRButtonDown( UINT modKeys, TPoint& point );
  1335.     void EvMouseMove( UINT modKeys, TPoint& point );
  1336.  
  1337.     BOOL CanClose();    // Changed
  1338.  
  1339.     TOpenSaveDialog::TData FileData;    // Changed
  1340.  
  1341. private:
  1342.  
  1343.     int SaveFile();         // Changed
  1344.     int SaveFileAs();       // Changed
  1345.     void ReadObjects();     // Changed
  1346.     void WriteObjects();    // Changed
  1347.     int CheckAndClear();    // Changed
  1348.     int OkToClear();        // Changed
  1349.     static void WriteObject( GraphicalObject &obj, void * );    // Changed
  1350.  
  1351.     TObjectBuilder *Builder;
  1352.  
  1353.     void FlushObjects();
  1354.     void AddObject( GraphicalObject *obj );
  1355.     static void DrawObject( GraphicalObject &obj, void * );
  1356.     TISetAsVector<GraphicalObject> Objects;
  1357.  
  1358.     int WindowIsDirty;          // Changed
  1359.  
  1360.     class GraphWindowDC
  1361.     {
  1362.     public:
  1363.         GraphWindowDC( TDC& );
  1364.         ~GraphWindowDC();
  1365.         operator TDC&() const;
  1366.     private:
  1367.         TDC& DC;
  1368.         WORD OldFlags;
  1369.         TPen Pen;
  1370.     };
  1371.  
  1372.     DECLARE_RESPONSE_TABLE(TGraphWindow);
  1373.  
  1374. };
  1375.  
  1376. DEFINE_RESPONSE_TABLE1( TGraphWindow, TWindow )
  1377.     EV_COMMAND( CM_FILENEW, CmNew ),
  1378.     EV_COMMAND( CM_FILEOPEN, CmFileOpen ),      // Changed
  1379.     EV_COMMAND( CM_FILESAVE, CmFileSave ),      // Changed
  1380.     EV_COMMAND( CM_FILESAVEAS, CmFileSaveAs ),  // Changed
  1381.     EV_COMMAND( CM_EDITLINE, CmLine ),
  1382.     EV_COMMAND( CM_EDITRECTANGLE, CmRectangle ),
  1383.     EV_COMMAND( CM_EDITCAPTIONEDRECTANGLE, CmCaptionedRectangle ),
  1384.     EV_COMMAND( CM_EDITELLIPSE, CmEllipse ),
  1385.     EV_COMMAND( CM_EDITCAPTIONEDELLIPSE, CmCaptionedEllipse ),
  1386.     EV_COMMAND( CM_HELPABOUT, CmAbout ),
  1387.     EV_WM_LBUTTONDOWN,
  1388.     EV_WM_LBUTTONUP,
  1389.     EV_WM_RBUTTONDOWN,
  1390.     EV_WM_MOUSEMOVE,
  1391. END_RESPONSE_TABLE;
  1392.  
  1393. TGraphWindow::GraphWindowDC::GraphWindowDC( TDC& dc ) :
  1394.     DC(dc),
  1395.     Pen(::GetSysColor(COLOR_WINDOWTEXT))
  1396. {
  1397.     OldFlags = DC.SetTextAlign( TA_CENTER );
  1398.     DC.SelectObject( Pen );
  1399.     DC.SetBkColor( ::GetSysColor( COLOR_WINDOW ) );
  1400. }
  1401.  
  1402. TGraphWindow::GraphWindowDC::~GraphWindowDC()
  1403. {
  1404.     DC.RestorePen();
  1405.     DC.SetTextAlign( OldFlags );
  1406. }
  1407.  
  1408. TGraphWindow::GraphWindowDC::operator TDC&() const
  1409. {
  1410.     return DC;
  1411. }
  1412.  
  1413. // Changed
  1414. TGraphWindow::TGraphWindow() :
  1415.     TWindow( 0, 0, 0 ),
  1416.     Builder(0),
  1417.     FileData(OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST,
  1418.              "Stream Files (*.stm)|*.stm|All Files (*.*)|*.*|",
  1419.              0, "", "*"),
  1420.     WindowIsDirty(0)
  1421. {
  1422. }
  1423.  
  1424. void TGraphWindow::DrawObject( GraphicalObject &obj, void *ptr )
  1425. {
  1426.     obj.Draw( *(GraphWindowDC *)ptr );
  1427. }
  1428.  
  1429. void TGraphWindow::Paint( TDC& dc, BOOL, TRect& )
  1430. {
  1431.     GraphWindowDC gdc(dc);
  1432.     Objects.ForEach( DrawObject, &gdc );
  1433. }
  1434.  
  1435. void TGraphWindow::CmNew()
  1436. {
  1437.     if( CheckAndClear() )
  1438.         Invalidate();
  1439. }
  1440.  
  1441. // Changed
  1442. void TGraphWindow::CmFileOpen()
  1443. {
  1444.     if( CheckAndClear() )
  1445.         {
  1446.         *FileData.FileName = 0;
  1447.         TFileOpenDialog dlg( this, FileData );
  1448.         if( dlg.Execute() == IDOK )
  1449.             {
  1450.             ReadObjects();
  1451.             Invalidate();
  1452.             }
  1453.         }
  1454. }
  1455.  
  1456. // Changed
  1457. void TGraphWindow::CmFileSave()
  1458. {
  1459.     SaveFile();
  1460. }
  1461.  
  1462. // Changed
  1463. int TGraphWindow::SaveFile()
  1464. {
  1465.     if( *FileData.FileName == '\0' )
  1466.         return SaveFileAs();
  1467.     else
  1468.         {
  1469.         WriteObjects();
  1470.         return 1;
  1471.         }
  1472. }
  1473.  
  1474. // Changed
  1475. void TGraphWindow::CmFileSaveAs()
  1476. {
  1477.     SaveFileAs();
  1478. }
  1479.  
  1480. // Changed
  1481. int TGraphWindow::SaveFileAs()
  1482. {
  1483.     *FileData.FileName = '\0';
  1484.     TFileSaveDialog dlg( this, FileData );
  1485.     if( dlg.Execute() == IDOK )
  1486.         {
  1487.         WriteObjects();
  1488.         return 1;
  1489.         }
  1490.     else
  1491.         return 0;
  1492. }
  1493.  
  1494. // Changed
  1495. void TGraphWindow::ReadObjects()
  1496. {
  1497.     ifpstream in( FileData.FileName );
  1498.     int count;
  1499.     in >> count;
  1500.     while( count-- != 0 )
  1501.         {
  1502.         GraphicalObject *object;
  1503.         in >> object;
  1504.         AddObject( object );
  1505.         }
  1506.     WindowIsDirty = 0;
  1507. }
  1508.  
  1509. // Changed
  1510. void TGraphWindow::WriteObject( GraphicalObject& obj, void *data )
  1511. {
  1512.     *(ofpstream *)data << &obj;
  1513. }
  1514.  
  1515. // Changed
  1516. void TGraphWindow::WriteObjects()
  1517. {
  1518.     ofpstream out( FileData.FileName );
  1519.     out << Objects.GetItemsInContainer();
  1520.     Objects.ForEach( WriteObject, &out );
  1521.     WindowIsDirty = 0;
  1522. }
  1523.  
  1524. // Changed
  1525. int TGraphWindow::CheckAndClear()
  1526. {
  1527.     if( OkToClear() )
  1528.         {
  1529.         FlushObjects();
  1530.         return 1;
  1531.         }
  1532.     else
  1533.         return 0;
  1534. }
  1535.  
  1536. // Changed
  1537. int TGraphWindow::OkToClear()
  1538. {
  1539.     if( !WindowIsDirty )
  1540.         return 1;
  1541.     else
  1542.         {
  1543.         string msg;
  1544.         if( *FileData.FileName == 0 )
  1545.             msg = "<untitled>";
  1546.         else
  1547.             msg = FileData.FileName;
  1548.         msg += " has not been saved. Save before closing?";
  1549.         int res = MessageBox( msg.c_str(), GetApplication()->GetName(),
  1550.                               MB_ICONEXCLAMATION | MB_YESNOCANCEL );
  1551.         switch( res )
  1552.             {
  1553.             case IDYES:
  1554.                 return SaveFile();
  1555.             case IDNO:
  1556.                 return 1;
  1557.             case IDCANCEL:
  1558.                 return 0;
  1559.             }
  1560.         return 0;
  1561.         }
  1562. }
  1563.  
  1564. void TGraphWindow::CmLine()
  1565. {
  1566.     Builder = new LineBuilder( *this );
  1567. }
  1568.  
  1569. void TGraphWindow::CmRectangle()
  1570. {
  1571.     Builder = new RectangleBuilder( *this );
  1572. }
  1573.  
  1574. void TGraphWindow::CmCaptionedRectangle()
  1575. {
  1576.     Builder = new CaptionedRectangleBuilder( *this );
  1577. }
  1578.  
  1579. void TGraphWindow::CmEllipse()
  1580. {
  1581.     Builder = new EllipseBuilder( *this );
  1582. }
  1583.  
  1584. void TGraphWindow::CmCaptionedEllipse()
  1585. {
  1586.     Builder = new CaptionedEllipseBuilder( *this );
  1587. }
  1588.  
  1589. void TGraphWindow::CmAbout()
  1590. {
  1591.     TDialog dlg( this, "About" );
  1592.     dlg.Execute();
  1593. }
  1594.  
  1595. // Changed
  1596. BOOL TGraphWindow::CanClose()
  1597. {
  1598.     return CheckAndClear();
  1599. }
  1600.  
  1601. void TGraphWindow::AddObject( GraphicalObject *object )
  1602. {
  1603.     Objects.Add( object );
  1604.     WindowIsDirty = 1;      // Changed
  1605. }
  1606.  
  1607. void TGraphWindow::FlushObjects()
  1608. {
  1609.     Objects.Flush();
  1610.     WindowIsDirty = 0;      // Changed
  1611. }
  1612.  
  1613. void TGraphWindow::EvLButtonDown( UINT modKeys, TPoint& point )
  1614. {
  1615.     if( Builder == 0 )
  1616.         TWindow::EvLButtonDown( modKeys, point );
  1617.     else
  1618.         Builder->SetAnchor(point);
  1619. }
  1620.  
  1621. void TGraphWindow::EvLButtonUp( UINT modKeys, TPoint& point )
  1622. {
  1623.     if( Builder == 0 )
  1624.         TWindow::EvLButtonUp( modKeys, point );
  1625.     else
  1626.         {
  1627.         AddObject( Builder->CreateObject() );
  1628.         delete Builder;
  1629.         Builder = 0;
  1630.         Invalidate();
  1631.         }
  1632. }
  1633.  
  1634. void TGraphWindow::EvRButtonDown( UINT modKeys, TPoint& point )
  1635. {
  1636.     if( Builder == 0 )
  1637.         TWindow::EvRButtonDown( modKeys, point );
  1638.     else
  1639.         {
  1640.         Builder->Cancel();
  1641.         delete Builder;
  1642.         Builder = 0;
  1643.         }
  1644. }
  1645.  
  1646. void TGraphWindow::EvMouseMove( UINT modKeys, TPoint& point )
  1647. {
  1648.     if( Builder == 0 )
  1649.         TWindow::EvMouseMove( modKeys, point );
  1650.     else
  1651.         Builder->Drag( point );
  1652. }
  1653.  
  1654. class TStreamApp : public TApplication 
  1655. {
  1656.  
  1657. public:
  1658.  
  1659.     TStreamApp() : TApplication() {}
  1660.  
  1661.     void InitMainWindow();
  1662.  
  1663. };
  1664.  
  1665. void TStreamApp::InitMainWindow()
  1666. {
  1667.     MainWindow = new TFrameWindow( 0, "Streaming Example, version 1",
  1668.                                    new TGraphWindow );
  1669.     MainWindow->AssignMenu("COMMANDS");
  1670. }
  1671.  
  1672. int OwlMain( int, char ** )
  1673. {
  1674.     TStreamApp app;
  1675.     return app.Run();
  1676. }
  1677.  
  1678.  
  1679.