wxTextCtrl and c++ streams

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
gsus
Earned a small fee
Earned a small fee
Posts: 10
Joined: Tue Feb 01, 2005 2:15 am

wxTextCtrl and c++ streams

Post by gsus »

Hi have some troubles using wxTextCtrl with streams. i want to redirect cout to a textcontrol.
im using 2.6.2 with with visual studio 7.1 and complile as dll realese.
my setup.h says #define wxUSE_STD_IOSTREAM 1

Code: Select all

wxTextCtrl *control = new wxTextCtrl(...);
  *control << 123.456 << " some text\n";
...works fine.

Code: Select all

#include <iostream>
wxTextCtrl *control = new wxTextCtrl(...);
std::cout.rdbuf(*control); //error c2664
... gives some barely readable error message:
"... unable to convert from'wxTextCtr' to'std::basic_ios..."

if im trying to use wxStreamToTextRedirector redirect(control);
the compiler says wxStreamToTextRedirector not defined.

The documentation to for wxStreamToTextRedirector says "Some compilers and/or build configurations don't support multiply inheriting wxTextCtrl from std::streambuf in which case this class is not compiled in."

Do i have build combination which doesnt support wxStreamToText.?
how could i still redirect std::cout. cos im using a thir part library which is using cout for error messages and i want them to show in the textconsole.

regards, Tobi
micros
Super wx Problem Solver
Super wx Problem Solver
Posts: 317
Joined: Sat Mar 18, 2006 10:41 am
Location: Ustek, Bohemia

Post by micros »

This is from "wx/textctrl.h"

Code: Select all

// Open Watcom 1.3 does allow only ios::rdbuf() while
// we want something with streambuf parameter
// Also, can't use streambuf if making or using a DLL :-(

#if defined(__WATCOMC__) || defined(__MWERKS__) || \
    (defined(__WINDOWS__) && (defined(WXUSINGDLL) || defined(WXMAKINGDLL)))
    #define wxHAS_TEXT_WINDOW_STREAM 0
#elif wxUSE_STD_IOSTREAM
    #include "wx/ioswrap.h"
    #define wxHAS_TEXT_WINDOW_STREAM 1
#else
    #define wxHAS_TEXT_WINDOW_STREAM 0
#endif
So one simple way would be to use static wx libs.
gsus
Earned a small fee
Earned a small fee
Posts: 10
Joined: Tue Feb 01, 2005 2:15 am

Post by gsus »

oh tnx... seems the execelent documentation is missing here something.

unfortunally this doesnt help me much.. im stick with dll's because im having a plugin system.

and getting cout would be really helpull. up to now they go nowhere. maybe i could keep up the console, but that looks ugly.. having a nice wxwidgets framework and displaying text in the console..zzz

regards, Tobi
micros
Super wx Problem Solver
Super wx Problem Solver
Posts: 317
Joined: Sat Mar 18, 2006 10:41 am
Location: Ustek, Bohemia

Post by micros »

Here's what I devised ('tis the whole header):

Code: Select all

#ifndef TEXTCTRLBUF_H
#define TEXTCTRLBUF_H 1

#include <streambuf>
#include "wx/textctrl.h"

class textctrlbuf : public std::basic_streambuf<wxChar>
  {
  public:

    textctrlbuf(wxTextCtrl* text)
      : m_text(text) { }

  protected:

    typedef std::streamsize streamsize;

    virtual int_type overflow(int_type _Meta)
      {
        if (!m_text) {
          return traits_type::eof();
        }

        if (!traits_type::eq_int_type(traits_type::eof(), _Meta)) {
          wxString s(traits_type::to_char_type(_Meta));
          m_text->AppendText(s);
        }

        return traits_type::not_eof(_Meta);
      }

    virtual streamsize xsputn(const wxChar *_Ptr, streamsize _Count)
      {
        if (!m_text) {
          return 0;
        }

        wxString s(_Ptr, _Ptr + _Count);
        m_text->AppendText(s);
        return _Count;
      }

  private:

    wxTextCtrl* m_text;

  }; // textctrlbuf

#endif // ndef TEXTCTRLBUF_H
Here's how to use it (I put this code inside a button click handler in my frame):

Code: Select all

    #if wxUSE_UNICODE
    std::wostream& wxcout = std::wcout;
    #else
    std::ostream& wxcout = std::cout;
    #endif
    // wxTextCtrl* m_log; // I have it defined in the frame
    textctrlbuf buf(m_log); // attach the streambuf to my textctrl
    std::basic_streambuf<wxChar> *p_oldbuf;
    p_oldbuf = wxcout.rdbuf(&buf); // replace cout streambuf with my own
    try {
      wxcout << wxT("this was written to std::cout") << std::endl;
    }
    catch (...) {
      wxcout.rdbuf(p_oldbuf); // restore the original streambuf
      throw;
    }
    wxcout.rdbuf(p_oldbuf); // restore the original streambuf
I didn't test it with wxUSE_UNICODE=1, the above is only a suggestion of how it might work.
Viktor
In need of some credit
In need of some credit
Posts: 7
Joined: Fri Mar 24, 2006 9:37 pm
Location: Hamburg, Germany
Contact:

Post by Viktor »

I tried to use a wxTextCtrl as a wostream, but

Code: Select all

wostream outputOStream(output); // output is my wxTextCtrl*
doesn't work (with only ostream it works, of course). I think it's because wxTextCtrl inherits of streambuf, not of wstreambuf. However, I'd be glad to be corrected! :)
ONeill
I live to help wx-kind
I live to help wx-kind
Posts: 152
Joined: Wed Oct 04, 2006 12:51 pm

Post by ONeill »

For this problem:

Code: Select all

#include <iostream>
wxTextCtrl *control = new wxTextCtrl(...);
std::cout.rdbuf(*control); //error c2664 
use:

Code: Select all

#include <iostream>
wxTextCtrl *control = new wxTextCtrl(...);
std::cout.rdbuf((std::streambuf*)control); //error c2664 
hf
dio3
In need of some credit
In need of some credit
Posts: 1
Joined: Fri Jan 29, 2010 1:57 pm

Post by dio3 »

Signed up just to say Thanks :wink:

textctrlbuf works for me.
fanfa
Earned a small fee
Earned a small fee
Posts: 14
Joined: Mon Jul 26, 2010 8:56 am

Post by fanfa »

I've tried this solution, but after some correct output on the textcontrol, the program crash, with this error

Gtk:ERROR:/build/buildd/gtk+2.0-2.20.1/gtk/gtktextlayout.c:1224:get_style: assertion failed: (layout->one_style_cache == NULL)

The GUI is created on the main thread, and the call to std::cout is done in a separated working thread.

How can i solve it? Thanks
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Post by evstevemd »

fanfa wrote:I've tried this solution, but after some correct output on the textcontrol, the program crash, with this error

Gtk:ERROR:/build/buildd/gtk+2.0-2.20.1/gtk/gtktextlayout.c:1224:get_style: assertion failed: (layout->one_style_cache == NULL)

The GUI is created on the main thread, and the call to std::cout is done in a separated working thread.

How can i solve it? Thanks
Start new Thread. This is very old thread :)
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
Post Reply