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