Eigene Streams



  • Hi,

    ich möchte für ein Ausgabefenster ( Win32 Editwindow ) ein eigenes ostream Objekt wie z.B. cout programmieren, also das ich nur schreibe
    winout << "Hallo Welt" und auf dem Fenster erscheint die jeweilige Ausgabe.
    Das ganze wenn möglich mit den gängigsten Manipulatoren.
    Wie stelle ich das an ?
    Also meine Überlegungen waren einfach ein Objekt von std::ostream abzuleiten und ein paar entsprechende Methoden zu überschreiben.
    Nur irgendwie klappt das nicht, ich weiss gar nicht welche Methoden ich denn da jetzt überschreiben muss, sind ja nun wirklich eine ganze Menge, und mit welcher Funktionalität.
    Ich habe mich auch weiter erkundigt und erfahren das std::ostream gepuffert ist, ich möchte aber gar keine gepufferte Ausgabe für mein Fenster.
    Ich habe mir auch mal in meiner STL die Implementierung von ostringstream amgeguckt, aber irgendwie wurde ich da nicht besonders schlau, zumal der Code echt unleserlich ist. Ich habe auch im Internet nichts passendes dazu gefunden.

    Wie schreibe ich eigene (STL konforme) Ausgabeströme in C++ ?

    Thx



  • Im Prinzip implementiert man neue streams indem man einen neuen streambuf erstellt.

    Noch n bisschen buggy, aber von der Idee her kannst du ja mal mein cppgi::basic_bufferedStream ansehen.





  • Ich hab so eine Klasse für X11 geschrieben. Vielleicht hilft dir der Code

    template<class charT, class traits=std::char_traits<charT> >
    class windowstreambuf : public std::basic_streambuf<charT,traits>, 
    			private window
    {
      static const size_t BUFFER_SIZE=100;
      char buffer[BUFFER_SIZE];
      size_t pos;
      int x_, y_;
      int init_x, init_y;
      XFontStruct *font;
    public:
      windowstreambuf(window *win, const char *font_p, const XColor &text)
        : window(*win), pos(0), x_(0), y_(15), init_x(0), init_y(15),
          font(XLoadQueryFont(getDisplay(),font_p))
      {
        XSetFont(getDisplay(),getGC(),font->fid);
        XSetForeground(getDisplay(),getGC(),text.pixel);
      }
      windowstreambuf(window *win, const char *font_p, const XColor &text,
    		  int x, int y)
        : window(*win), pos(0), x_(x), y_(y), init_x(x), init_y(y), 
          font(XLoadQueryFont(getDisplay(),font_p))
      {
        XSetFont(getDisplay(),getGC(),font->fid);
        XSetForeground(getDisplay(),getGC(),text.pixel);
      }
      ~windowstreambuf()
      { XUnloadFont(getDisplay(),font->fid); }
    
      void setx(int x) { x_=x; }
      void sety(int y) { y_=y; }
      void rewind(void) { x_=init_x; y_=init_y; }
      void clear(void) { rewind(); winclear(); }
    protected:
      int_type overflow(int_type c=traits::eof())
      {
        if(pos>=BUFFER_SIZE-1)
          sync();
        if(c=='\n')
        {
          sync();
          y_+=15; //replace 15 with font height
          x_=init_x;
          return c;
        }
        buffer[pos++]=c;
        return c;
      }
      int sync(void)
      {
        if(pos==0)
          return true;
        XDrawString(getDisplay(),getWindow(),getGC(),x_,y_,buffer,pos);
        XFlush(getDisplay());
        x_+=XTextWidth(font,buffer,pos);
        pos=0;
        return true;
      }
    };
    


  • Danke!


Anmelden zum Antworten