Borland Online And The Cobb Group Present:


September, 1995 - Vol. 2 No. 9


Listing A: DCSTREAM.H
#ifndef _DCSTREAM_H
#define _DCSTREAM_H
#include <stdarg.h>
#include <iostream.h>
#include <iomanip.h>
#include <gdiobjec.h>

class odcstream;

class dcstreambuf: public streambuf
{
  public:
    dcstreambuf( unsigned int = 512 );
    ~dcstreambuf( void );

  protected:
    enum { TAB_ANSI = 1, TAB_HARD };

    HDC hDC;
    char *buf;

    TEXTMETRIC tm;

    int x0, x, y, ydir, *tabs;

    unsigned int bufsiz, tabType, itab, ntabs;

    virtual int overflow( int );
    virtual int sync( void );

    int gettab( int );
    void settabs( unsigned int, int* );
    int hardtab( void );
    int ansitab( void );

   friend class odcstream;
};

class odcstream: public TDC, public ostream
{ public:
    odcstream( HDC hdc, dcstreambuf *buf ):
       TDC( hdc ), ostream( buf )
    { init(); };

    odcstream( HDC hdc, dcstreambuf &buf ):
       TDC( hdc ), ostream( &buf )
    { init(); };

    int x( int );
    int y( int );
    int x( void )
    { return ((dcstreambuf*)rdbuf())->x; }
    int y( void )
    { return ((dcstreambuf*)rdbuf())->y; }
    const TPoint& xy( const TPoint &p )
    { xy( p.x, p.y );
      return p; }

      void xy( int xnew, int ynew )
      { dcstreambuf &sb = *(dcstreambuf*)rdbuf();
        flush();
        sb.itab = 0;
        sb.x0 = sb.x = xnew;
        sb.y = ynew; }

      void hardtab( void )
      { ((dcstreambuf*)rdbuf())->tabType = 
             dcstreambuf::TAB_HARD; }

      void ansitab( void )
      { ((dcstreambuf*)rdbuf())->tabType = 
             dcstreambuf::TAB_ANSI; }

      void tab( int i)
      { ((dcstreambuf*)rdbuf())->settabs(1, &i); }

      void tabs( unsigned int n, int* i)
      { ((dcstreambuf*)rdbuf())->settabs( n, i ); }

      void tabs( unsigned int, ... );

   private:
      void init( void );
};

inline void odcstream::init( void )
{ TSize wp, vp;
  dcstreambuf &sb = *(dcstreambuf*)rdbuf();

  sb.hDC = *this;
  wp = GetWindowExt();
  vp = GetViewportExt();
  sb.ydir = ( (long)wp.cy * (long)vp.cy > 0 )? 1: -1;
  xy( 0, 0 ); };

/*
 * odcstream manipulators
 *
 * the manipulators can be used as:
 *    odc << gotox( int )
 *    odc << gotoy( int )
 *    odc << gotoxy( int, int )
 *    odc << tab( 4 )
 *
 * these are inline because they don't export
 * from a DLL correctly
 */

template<class typ, class typ2>
class omanip2
{
      ostream& (*_fn)(ostream&, typ, typ2);
      typ _ag;
      typ2 _ag2;

   public:
      omanip2( ostream& (*_f)(ostream&, typ, typ2), 
               typ _z, typ2 _z2 ):
         	       _fn(_f), _ag(_z), _ag2(_z2) { }

      friend ostream& operator << ( ostream& _s, 
                  omanip2<typ, typ2>& _f )
      { return(*_f._fn)(_s, _f._ag, _f._ag2); }
};

inline ostream& odc_x_( ostream& os, int x )
{ ((odcstream&)os).x( x );
  return os; }

inline ostream& odc_y_( ostream& os, int y )
{ ((odcstream&)os).y( y );
  return os; }

inline ostream& odc_xy_( ostream& os, int x, int y )
{ ((odcstream&)os).xy( x, y );
  return os; }

inline ostream& odc_tab_( ostream& os, int t )
{ ((odcstream&)os).tab( t );
  return os; }

inline omanip<int> gotox( int x )
{ return omanip<int>( odc_x_, x ); }

inline omanip<int> gotoy( int y )
{ return omanip<int>( odc_y_, y ); }

inline omanip2<int,int> gotoxy( int x, int y )
{ return omanip2<int,int>( odc_xy_, x, y ); }

inline omanip<int> tab( int t )
{ return omanip<int>( odc_tab_, t ); }

#endif

Return to "Streaming text to a device context"


Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.