home *** CD-ROM | disk | FTP | other *** search
/ Troubleshooting Netware Systems / CSTRIAL0196.BIN / attach / msj / v10n08 / sketchsc.exe / MYWIN.H < prev    next >
C/C++ Source or Header  |  1995-08-01  |  6KB  |  180 lines

  1. //-----------------------------------------------------------------------
  2. // MYWIN.H:            Various Windows support classes
  3. //-----------------------------------------------------------------------
  4. #ifndef MYWIN_H__
  5. #define MYWIN_H__
  6.  
  7. #ifdef DEBUG
  8. #define D(x) x
  9. #else
  10. #define D(x) /*empty*/
  11. #endif
  12.  
  13. //----------------------------------------------------------------------- 
  14. // The mapping_mode is a convenience. It is intended for use ONLY by the
  15. // device class. You set the mapping mode anywhere in your program
  16. // either by creating an object like this:
  17. //
  18. //        mapping_mode m( MM_TEXT );
  19. //
  20. // or executing a cast instruction somewhere in your program:
  21. //
  22. //        mapping_mode( MM_TEXT );
  23. //
  24. // You can do this only once. So it's best to do it as a global variable
  25. // or with a call in your applications InitInstance() function.
  26. //
  27. // I've encapsulated the mapping mode into a class (as compared to using
  28. // a global variable) to guarantee that it won't be used without having
  29. // been set and that it won't change after being set. Keeps everbody
  30. // honest. For example, the following code appears in the device
  31. // implemenation:
  32. //
  33. //        SetMapMode( mapping_mode() );
  34. //
  35. // The "mapping_mode()" is a cast that creates a mapping-mode object
  36. // (which is actually of zero size since it's only field is static).
  37. // The compiler then converts that object into an int, using
  38. // mapping_mode::operator int(), which returns the actual mapping mode.
  39. // It does some data validition first, though, and throws a
  40. // mapping_mode::error object if the mode hasn't been set yet. 
  41. // All this is done inline, with the error checking removed when not
  42. // debugging, so is no less efficient than a direct access of a global
  43. // variable.
  44.  
  45. class mapping_mode    
  46. {
  47.     static int mode;
  48.     enum { MM_NONE = MM_MAX+1 };    // MM_MAX defined by Windows
  49.  
  50.     void check_valid( void );
  51.  
  52. public:
  53.     class error{};
  54.     mapping_mode( UINT init_mode );
  55.  
  56. private:
  57.     friend class device;
  58.     friend class rect_update;
  59.  
  60.     mapping_mode( void ){}
  61.     operator int( void );
  62. };
  63. //----------------------------------------------------------------------- 
  64. inline mapping_mode::mapping_mode( UINT init_mode )
  65. {
  66.     D( if( mode != MM_NONE )    )// Can be set only once.
  67.     D(        throw error();        )
  68.  
  69.     mode = init_mode ;
  70. }
  71. //----------------------------------------------------------------------- 
  72. inline mapping_mode::operator int( )
  73. {
  74.     D( if( mode == MM_NONE )    )
  75.     D(     throw error();        )
  76.  
  77.     return mode;
  78. }
  79.  
  80. //======================================================================= 
  81. // My variant on a device context. Automatically maps into and out
  82. // of the current mapping modes. Create from a window to get the
  83. // equivalent of a CClientDC and from a CDC to get a auto-mapping
  84. // device context. The original device context is not released in
  85. // this last case (ie, I'm assuming that you got it from an existing
  86. // CDC).
  87. //
  88. // the device also adds to the windows DC by supporting
  89. // the notion of a puts() function. It keeps a document-relative
  90. // text cursor and puts at that location. The line height is
  91. // contolled by the current font.
  92. //
  93. //    dc->puts( const CString &str );
  94. //    dc-set_text_cursor( const CPoint &location );
  95.  
  96. // Use puts like this to get printf-style functionality:
  97. //
  98. //    CString s;
  99. //    dc->puts( s.Format("fmt",args) );
  100. //
  101. // The function returns the current cursor location after the print.
  102. // TabbedTextOut() is used to print the buffer, so use SetTextAlign,
  103. // etc to control placement. The position is controled by an
  104. // internal cursor and is advanced to the next line automatically
  105. // after every puts() call. Use set_text_cursor() to set a text
  106. // position (in logical units) to be used by the next puts() call.
  107. // The 'y' coordinate sticks on, so all subsequent lines will be
  108. // offset if set_text_cursor presents a nonzero y coordinate.
  109. // Tabs are 8-space tabs, starting at the far left of the line,
  110. // where a "space" is the average character width.
  111.  
  112. class device : public CDC
  113. {
  114.     const CWnd    *owner;
  115.     CPoint        cursor;        // puts() cursor
  116.     CRect        bounding;    // bounding rectangle if this is a CPaintDC
  117.  
  118. protected:
  119.     virtual void prepare( void );
  120.  
  121. public:
  122.     virtual
  123.     ~device( void             );
  124.      device( const CWnd *win );
  125.      device( const CDC  *dc  ); 
  126.  
  127.     void set_up_scrolling( CSize document_size );
  128.  
  129.     const CPoint &puts    ( const CString &str             );
  130.     void set_text_cursor( const CPoint  &location         );
  131.     void invalidate_rect( CRect invalid_region,
  132.                           int    erase_background = TRUE    );
  133.  
  134. private: friend class rect_client;
  135.     CRect *get_client_rect( CRect *r ) const;
  136. };
  137. //-----------------------------------------------------------------------
  138. inline void device::set_text_cursor( const CPoint &location )
  139. {
  140.     cursor = location;
  141. }
  142. //======================================================================= 
  143. class rect_client: public CRect
  144. {
  145. public:
  146.     rect_client( const device &dc )
  147.     {
  148.         dc.get_client_rect( this );
  149.     }
  150. };
  151. //======================================================================= 
  152. class rect_clip: public CRect
  153. {
  154. public:
  155.     rect_clip( const device &dc )
  156.     {
  157.         dc.GetClipBox( this );
  158.     }
  159. };
  160. //======================================================================= 
  161. class rect_update: public CRect
  162. {
  163. public:
  164.     rect_update( CWnd *win )
  165.     {                                        
  166.         win->GetUpdateRect( this, FALSE );
  167.         if( !IsRectEmpty() )
  168.         {
  169.             DWORD winstyle = GetClassLong(win->m_hWnd, GWL_STYLE);
  170.             if( !((winstyle & CS_OWNDC) && (mapping_mode()==MM_TEXT)) ) 
  171.             {
  172.                 device dc( win );
  173.                 dc.DPtoLP( this );
  174.             }
  175.         }
  176.     }
  177. };
  178.  
  179. #endif // MYWIN_H__
  180.