/////////////////////////////////////////////////////////////////////////////
-// Program: wxWindows Widgets Sample
+// Program: wxWidgets Widgets Sample
// Name: textctrl.cpp
// Purpose: part of the widgets sample showing wxTextCtrl
// Author: Vadim Zeitlin
#include "wx/log.h"
#include "wx/timer.h"
+ #include "wx/bitmap.h"
#include "wx/button.h"
#include "wx/checkbox.h"
#include "wx/radiobox.h"
#include "wx/statbox.h"
#include "wx/stattext.h"
#include "wx/textctrl.h"
+ #include "wx/msgdlg.h"
#endif
#include "wx/sizer.h"
+#include "wx/ioswrap.h"
#include "widgets.h"
// control ids
enum
{
- TextPage_Reset = 100,
+ TextPage_Reset = wxID_HIGHEST,
TextPage_Set,
TextPage_Add,
TextPage_Clear,
TextPage_Load,
+ TextPage_StreamRedirector,
+
TextPage_Password,
TextPage_WrapLines,
TextPage_Textctrl
enum TextLines
{
TextLines_Single,
- TextLines_Multi
+ TextLines_Multi,
+ TextLines_Max
+};
+
+// wrap style radio box
+enum WrapStyle
+{
+ WrapStyle_None,
+ WrapStyle_Word,
+ WrapStyle_Char,
+ WrapStyle_Best,
+ WrapStyle_Max
+};
+
+#ifdef __WXMSW__
+
+// textctrl kind values
+enum TextKind
+{
+ TextKind_Plain,
+ TextKind_Rich,
+ TextKind_Rich2,
+ TextKind_Max
};
+#endif // __WXMSW__
+
// default values for the controls
static const struct ControlValues
{
TextLines textLines;
+
bool password;
- bool wraplines;
bool readonly;
+ bool filename;
+
+ WrapStyle wrapStyle;
+
+#ifdef __WXMSW__
+ TextKind textKind;
+#endif // __WXMSW__
} DEFAULTS =
{
TextLines_Multi, // multiline
- FALSE, // not password
- TRUE, // do wrap lines
- FALSE // not readonly
+ false, // not password
+ false, // not readonly
+ false, // not filename
+ WrapStyle_Word, // wrap on word boundaries
+#ifdef __WXMSW__
+ TextKind_Plain // plain EDIT control
+#endif // __WXMSW__
};
// ----------------------------------------------------------------------------
{
public:
// ctor(s) and dtor
- TextWidgetsPage(wxNotebook *notebook, wxImageList *imaglist);
- virtual ~TextWidgetsPage();
+ TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
+ virtual ~TextWidgetsPage(){};
+
+ virtual wxControl *GetWidget() const { return m_text; }
+ virtual void RecreateWidget() { CreateText(); }
+
+ // lazy creation of the content
+ virtual void CreateContent();
protected:
// create an info text contorl
void OnButtonClear(wxCommandEvent& event);
void OnButtonLoad(wxCommandEvent& event);
+ void OnStreamRedirector(wxCommandEvent& event);
void OnButtonQuit(wxCommandEvent& event);
void OnText(wxCommandEvent& event);
// the radiobox to choose between single and multi line
wxRadioBox *m_radioTextLines;
+ // and another one to choose the wrapping style
+ wxRadioBox *m_radioWrap;
+
// the checkboxes controlling text ctrl styles
wxCheckBox *m_chkPassword,
- *m_chkWrapLines,
- *m_chkReadonly;
+ *m_chkReadonly,
+ *m_chkFilename;
+
+ // under MSW we test rich edit controls as well here
+#ifdef __WXMSW__
+ wxRadioBox *m_radioKind;
+#endif // __WXMSW__
// the textctrl itself and the sizer it is in
wxTextCtrl *m_text;
*m_textPosLast,
*m_textLineLast,
*m_textSelFrom,
- *m_textSelTo;
+ *m_textSelTo,
+ *m_textRange;
// and the data to show in them
long m_posCur,
m_selFrom,
m_selTo;
+ wxString m_range10_20;
+
private:
- // any class wishing to process wxWindows events must use this macro
- DECLARE_EVENT_TABLE();
+ // any class wishing to process wxWidgets events must use this macro
+ DECLARE_EVENT_TABLE()
+ DECLARE_WIDGETS_PAGE(TextWidgetsPage)
+};
+
+// ----------------------------------------------------------------------------
+// WidgetsTextCtrl
+// ----------------------------------------------------------------------------
+
+class WidgetsTextCtrl : public wxTextCtrl
+{
+public:
+ WidgetsTextCtrl(wxWindow *parent,
+ wxWindowID id,
+ const wxString& value,
+ int flags)
+ : wxTextCtrl(parent, id, value, wxDefaultPosition, wxDefaultSize, flags)
+ {
+ }
- DECLARE_WIDGETS_PAGE(TextWidgetsPage);
+protected:
+ void OnRightClick(wxMouseEvent& event)
+ {
+ wxString where;
+ wxTextCoord x, y;
+ switch ( HitTest(event.GetPosition(), &x, &y) )
+ {
+ default:
+ wxFAIL_MSG( _T("unexpected HitTest() result") );
+ // fall through
+
+ case wxTE_HT_UNKNOWN:
+ x = y = -1;
+ where = _T("nowhere near");
+ break;
+
+ case wxTE_HT_BEFORE:
+ where = _T("before");
+ break;
+
+ case wxTE_HT_BELOW:
+ where = _T("below");
+ break;
+
+ case wxTE_HT_BEYOND:
+ where = _T("beyond");
+ break;
+
+ case wxTE_HT_ON_TEXT:
+ where = _T("at");
+ break;
+ }
+
+ wxLogMessage(_T("Mouse is %s (%ld, %ld)"), where.c_str(), x, y);
+
+ event.Skip();
+ }
+
+private:
+ DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
EVT_BUTTON(TextPage_Reset, TextWidgetsPage::OnButtonReset)
+ EVT_BUTTON(TextPage_StreamRedirector, TextWidgetsPage::OnStreamRedirector)
+
EVT_BUTTON(TextPage_Clear, TextWidgetsPage::OnButtonClear)
EVT_BUTTON(TextPage_Set, TextWidgetsPage::OnButtonSet)
EVT_BUTTON(TextPage_Add, TextWidgetsPage::OnButtonAdd)
EVT_TEXT(TextPage_Textctrl, TextWidgetsPage::OnText)
EVT_TEXT_ENTER(TextPage_Textctrl, TextWidgetsPage::OnTextEnter)
- EVT_CHECKBOX(-1, TextWidgetsPage::OnCheckOrRadioBox)
- EVT_RADIOBOX(-1, TextWidgetsPage::OnCheckOrRadioBox)
+ EVT_CHECKBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
+ EVT_RADIOBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(WidgetsTextCtrl, wxTextCtrl)
+ EVT_RIGHT_UP(WidgetsTextCtrl::OnRightClick)
END_EVENT_TABLE()
// ============================================================================
// implementation
// ============================================================================
-IMPLEMENT_WIDGETS_PAGE(TextWidgetsPage, _T("Text"));
+#if defined(__WXX11__)
+ #define FAMILY_CTRLS NATIVE_CTRLS
+#elif defined(__WXUNIVERSAL__)
+ #define FAMILY_CTRLS UNIVERSAL_CTRLS
+#else
+ #define FAMILY_CTRLS NATIVE_CTRLS
+#endif
+
+IMPLEMENT_WIDGETS_PAGE(TextWidgetsPage, _T("Text"),
+ FAMILY_CTRLS | EDITABLE_CTRLS
+ );
// ----------------------------------------------------------------------------
// TextWidgetsPage creation
// ----------------------------------------------------------------------------
-TextWidgetsPage::TextWidgetsPage(wxNotebook *notebook, wxImageList *imaglist)
- : WidgetsPage(notebook)
+TextWidgetsPage::TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist)
+ : WidgetsPage(book, imaglist, text_xpm)
{
- imaglist->Add(wxBitmap(text_xpm));
-
// init everything
+#ifdef __WXMSW__
+ m_radioKind =
+#endif // __WXMSW__
+ m_radioWrap =
m_radioTextLines = (wxRadioBox *)NULL;
m_chkPassword =
- m_chkWrapLines =
- m_chkReadonly = (wxCheckBox *)NULL;
+ m_chkReadonly =
+ m_chkFilename = (wxCheckBox *)NULL;
m_text =
m_textPosCur =
m_textPosLast =
m_textLineLast =
m_textSelFrom =
- m_textSelTo = (wxTextCtrl *)NULL;
+ m_textSelTo =
+ m_textRange = (wxTextCtrl *)NULL;
+
m_sizerText = (wxSizer *)NULL;
m_posCur =
m_posLast =
m_selFrom =
m_selTo = -2; // not -1 which means "no selection"
+}
+void TextWidgetsPage::CreateContent()
+{
// left pane
static const wxString modes[] =
{
_T("multi line"),
};
- wxStaticBox *box = new wxStaticBox(this, -1, _T("&Set textctrl parameters"));
- m_radioTextLines = new wxRadioBox(this, -1, _T("&Number of lines:"),
+ wxStaticBox *box = new wxStaticBox(this, wxID_ANY, _T("&Set textctrl parameters"));
+ m_radioTextLines = new wxRadioBox(this, wxID_ANY, _T("&Number of lines:"),
wxDefaultPosition, wxDefaultSize,
WXSIZEOF(modes), modes,
1, wxRA_SPECIFY_COLS);
wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
sizerLeft->Add(m_radioTextLines, 0, wxGROW | wxALL, 5);
- sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
+ sizerLeft->AddSpacer(5);
m_chkPassword = CreateCheckBoxAndAddToSizer(
sizerLeft, _T("&Password control"), TextPage_Password
);
- m_chkWrapLines = CreateCheckBoxAndAddToSizer(
- sizerLeft, _T("Line &wrap"), TextPage_WrapLines
- );
m_chkReadonly = CreateCheckBoxAndAddToSizer(
sizerLeft, _T("&Read-only mode")
);
+ m_chkFilename = CreateCheckBoxAndAddToSizer(
+ sizerLeft, _T("&Filename control")
+ );
+ m_chkFilename->Disable(); // not implemented yet
+ sizerLeft->AddSpacer(5);
+
+ static const wxString wrap[] =
+ {
+ _T("no wrap"),
+ _T("word wrap"),
+ _T("char wrap"),
+ _T("best wrap"),
+ };
+
+ m_radioWrap = new wxRadioBox(this, wxID_ANY, _T("&Wrap style:"),
+ wxDefaultPosition, wxDefaultSize,
+ WXSIZEOF(wrap), wrap,
+ 1, wxRA_SPECIFY_COLS);
+ sizerLeft->Add(m_radioWrap, 0, wxGROW | wxALL, 5);
+
+#ifdef __WXMSW__
+ static const wxString kinds[] =
+ {
+ _T("plain edit"),
+ _T("rich edit"),
+ _T("rich edit 2.0"),
+ };
+
+ m_radioKind = new wxRadioBox(this, wxID_ANY, _T("Control &kind"),
+ wxDefaultPosition, wxDefaultSize,
+ WXSIZEOF(kinds), kinds,
+ 1, wxRA_SPECIFY_COLS);
+
+ sizerLeft->AddSpacer(5);
+ sizerLeft->Add(m_radioKind, 0, wxGROW | wxALL, 5);
+#endif // __WXMSW__
wxButton *btn = new wxButton(this, TextPage_Reset, _T("&Reset"));
+ sizerLeft->Add(2, 2, 0, wxGROW | wxALL, 1); // spacer
sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
// middle pane
- wxStaticBox *box2 = new wxStaticBox(this, -1, _T("&Change contents:"));
+ wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, _T("&Change contents:"));
wxSizer *sizerMiddleUp = new wxStaticBoxSizer(box2, wxVERTICAL);
btn = new wxButton(this, TextPage_Set, _T("&Set text value"));
- sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
+ sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
btn = new wxButton(this, TextPage_Add, _T("&Append text"));
- sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
+ sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
btn = new wxButton(this, TextPage_Insert, _T("&Insert text"));
- sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
+ sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
btn = new wxButton(this, TextPage_Load, _T("&Load file"));
- sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
+ sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
btn = new wxButton(this, TextPage_Clear, _T("&Clear"));
- sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
+ sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
+
+ btn = new wxButton(this, TextPage_StreamRedirector, _T("St&ream redirection"));
+ sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
- wxStaticBox *box4 = new wxStaticBox(this, -1, _T("&Info:"));
+ wxStaticBox *box4 = new wxStaticBox(this, wxID_ANY, _T("&Info:"));
wxSizer *sizerMiddleDown = new wxStaticBoxSizer(box4, wxVERTICAL);
m_textPosCur = CreateInfoText();
),
0, wxALL, 5
);
+
+ m_textRange = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
+ wxDefaultPosition, wxDefaultSize,
+ wxTE_READONLY);
+ sizerMiddleDown->Add
+ (
+ CreateTextWithLabelSizer
+ (
+ _T("Range 10..20:"),
+ m_textRange
+ ),
+ 0, wxALL, 5
+ );
+
wxSizer *sizerMiddle = new wxBoxSizer(wxVERTICAL);
sizerMiddle->Add(sizerMiddleUp, 0, wxGROW);
sizerMiddle->Add(sizerMiddleDown, 1, wxGROW | wxTOP, 5);
// right pane
- wxStaticBox *box3 = new wxStaticBox(this, -1, _T("&Text:"));
+ wxStaticBox *box3 = new wxStaticBox(this, wxID_ANY, _T("&Text:"));
m_sizerText = new wxStaticBoxSizer(box3, wxHORIZONTAL);
Reset();
CreateText();
- m_sizerText->SetMinSize(250, 0);
+ m_sizerText->SetMinSize(150, 0);
// the 3 panes panes compose the upper part of the window
wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
sizerTop->Add(sizerMiddle, 0, wxGROW | wxALL, 10);
sizerTop->Add(m_sizerText, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
- SetAutoLayout(TRUE);
SetSizer(sizerTop);
-
- sizerTop->Fit(this);
-}
-
-TextWidgetsPage::~TextWidgetsPage()
-{
}
// ----------------------------------------------------------------------------
GetTextExtent(_T("9999999"), &s_maxWidth, NULL);
}
- wxTextCtrl *text = new wxTextCtrl(this, -1, _T(""),
+ wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
wxDefaultPosition,
- wxSize(s_maxWidth, -1),
+ wxSize(s_maxWidth, wxDefaultCoord),
wxTE_READONLY);
return text;
}
wxTextCtrl *text2)
{
wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
- sizerRow->Add(new wxStaticText(this, -1, label), 0,
+ sizerRow->Add(new wxStaticText(this, wxID_ANY, label), 0,
wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5);
sizerRow->Add(text, 0, wxALIGN_CENTRE_VERTICAL);
if ( text2 )
{
- sizerRow->Add(new wxStaticText(this, -1, label2), 0,
+ sizerRow->Add(new wxStaticText(this, wxID_ANY, label2), 0,
wxALIGN_CENTRE_VERTICAL | wxLEFT | wxRIGHT, 5);
sizerRow->Add(text2, 0, wxALIGN_CENTRE_VERTICAL);
}
void TextWidgetsPage::Reset()
{
m_radioTextLines->SetSelection(DEFAULTS.textLines);
+
m_chkPassword->SetValue(DEFAULTS.password);
- m_chkWrapLines->SetValue(DEFAULTS.wraplines);
m_chkReadonly->SetValue(DEFAULTS.readonly);
+ m_chkFilename->SetValue(DEFAULTS.filename);
+
+ m_radioWrap->SetSelection(DEFAULTS.wrapStyle);
+
+#ifdef __WXMSW__
+ m_radioKind->SetSelection(DEFAULTS.textKind);
+#endif // __WXMSW__
}
void TextWidgetsPage::CreateText()
{
- int flags = 0;
+ int flags = ms_defaultFlags;
switch ( m_radioTextLines->GetSelection() )
{
default:
- wxFAIL_MSG( _T("unexpected radio box selection") );
+ wxFAIL_MSG( _T("unexpected lines radio box selection") );
case TextLines_Single:
break;
case TextLines_Multi:
flags |= wxTE_MULTILINE;
- m_chkPassword->SetValue(FALSE);
+ m_chkPassword->SetValue(false);
break;
}
flags |= wxTE_PASSWORD;
if ( m_chkReadonly->GetValue() )
flags |= wxTE_READONLY;
- if ( !m_chkWrapLines->GetValue() )
- flags |= wxHSCROLL;
+
+ switch ( m_radioWrap->GetSelection() )
+ {
+ default:
+ wxFAIL_MSG( _T("unexpected wrap style radio box selection") );
+
+ case WrapStyle_None:
+ flags |= wxTE_DONTWRAP; // same as wxHSCROLL
+ break;
+
+ case WrapStyle_Word:
+ flags |= wxTE_WORDWRAP;
+ break;
+
+ case WrapStyle_Char:
+ flags |= wxTE_CHARWRAP;
+ break;
+
+ case WrapStyle_Best:
+ // this is default but use symbolic file name for consistency
+ flags |= wxTE_BESTWRAP;
+ break;
+ }
+
+#ifdef __WXMSW__
+ switch ( m_radioKind->GetSelection() )
+ {
+ default:
+ wxFAIL_MSG( _T("unexpected kind radio box selection") );
+
+ case TextKind_Plain:
+ break;
+
+ case TextKind_Rich:
+ flags |= wxTE_RICH;
+ break;
+
+ case TextKind_Rich2:
+ flags |= wxTE_RICH2;
+ break;
+ }
+#endif // __WXMSW__
wxString valueOld;
if ( m_text )
{
valueOld = m_text->GetValue();
- m_sizerText->Remove(m_text);
+ m_sizerText->Detach( m_text );
delete m_text;
}
else
valueOld = _T("Hello, Universe!");
}
- m_text = new wxTextCtrl(this, TextPage_Textctrl,
- valueOld,
- wxDefaultPosition, wxDefaultSize,
- flags);
+ m_text = new WidgetsTextCtrl(this, TextPage_Textctrl, valueOld, flags);
+
+#if 0
+ if ( m_chkFilename->GetValue() )
+ ;
+#endif // TODO
+
+ // cast to int needed to silence gcc warning about different enums
m_sizerText->Add(m_text, 1, wxALL |
- (flags & wxTE_MULTILINE ? wxGROW
+ (flags & wxTE_MULTILINE ? (int)wxGROW
: wxALIGN_TOP), 5);
m_sizerText->Layout();
}
if ( m_textLineLast )
{
m_textLineLast->SetValue(
- wxString::Format(_T("%ld"), m_text->GetNumberOfLines()));
+ wxString::Format(_T("%d"), m_text->GetNumberOfLines()) );
}
if ( m_textSelFrom && m_textSelTo )
m_selTo = selTo;
}
}
+
+ if ( m_textRange )
+ {
+ wxString range = m_text->GetRange(10, 20);
+ if ( range != m_range10_20 )
+ {
+ m_range10_20 = range;
+ m_textRange->SetValue(range);
+ }
+ }
}
void TextWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
void TextWidgetsPage::OnButtonSet(wxCommandEvent& WXUNUSED(event))
{
- m_text->SetValue(_T("Yellow submarine"));
+ m_text->SetValue(m_text->GetWindowStyle() & wxTE_MULTILINE
+ ? _T("Here,\nthere and\neverywhere")
+ : _T("Yellow submarine"));
+
m_text->SetFocus();
}
void TextWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
{
- m_text->AppendText(_T("here, there and everywhere"));
- m_text->SetFocus();
+ if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
+ {
+ m_text->AppendText(_T("We all live in a\n"));
+ }
+
+ m_text->AppendText(_T("Yellow submarine"));
}
void TextWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
{
- m_text->WriteText(_T("is there anybody going to listen to my story"));
- m_text->SetFocus();
+ m_text->WriteText(_T("Is there anybody going to listen to my story"));
+ if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
+ {
+ m_text->WriteText(_T("\nall about the girl who came to stay"));
+ }
}
void TextWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
else
{
long elapsed = sw.Time();
- wxLogMessage(_T("Loaded file '%s' in %u.%us"),
- filename.c_str(), elapsed / 1000, elapsed % 1000);
+ wxLogMessage(_T("Loaded file '%s' in %lu.%us"),
+ filename.c_str(), elapsed / 1000,
+ (unsigned int) elapsed % 1000);
}
}
}
void TextWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
{
event.Enable( (m_radioTextLines->GetSelection() != DEFAULTS.textLines) ||
- (m_chkReadonly->GetValue() != DEFAULTS.readonly) ||
+#ifdef __WXMSW__
+ (m_radioKind->GetSelection() != DEFAULTS.textKind) ||
+#endif // __WXMSW__
(m_chkPassword->GetValue() != DEFAULTS.password) ||
- (m_chkWrapLines->GetValue() != DEFAULTS.wraplines) );
+ (m_chkReadonly->GetValue() != DEFAULTS.readonly) ||
+ (m_chkFilename->GetValue() != DEFAULTS.filename) ||
+ (m_radioWrap->GetSelection() != DEFAULTS.wrapStyle) );
}
-void TextWidgetsPage::OnText(wxCommandEvent& event)
+void TextWidgetsPage::OnText(wxCommandEvent& WXUNUSED(event))
{
// small hack to suppress the very first message: by then the logging is
// not yet redirected and so initial setting of the text value results in
// an annoying message box
- static bool s_firstTime = TRUE;
+ static bool s_firstTime = true;
if ( s_firstTime )
{
- s_firstTime = FALSE;
+ s_firstTime = false;
return;
}
void TextWidgetsPage::OnTextEnter(wxCommandEvent& event)
{
wxLogMessage(_T("Text entered: '%s'"), event.GetString().c_str());
+ event.Skip();
}
-void TextWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event)
+void TextWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
{
CreateText();
}
+void TextWidgetsPage::OnStreamRedirector(wxCommandEvent& WXUNUSED(event))
+{
+#if wxHAS_TEXT_WINDOW_STREAM
+ wxStreamToTextRedirector redirect(m_text);
+ wxString str( _T("Outputed to cout, appears in wxTextCtrl!") );
+ wxSTD cout << str << wxSTD endl;
+#else
+ wxMessageBox(_T("This wxWidgets build does not support wxStreamToTextRedirector"));
+#endif
+}