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