home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / PSTREAMS.PAK / STREAM0.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  59KB  |  1,421 lines

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