WxTextCtrl
From WxWiki
[edit] Allowing Only Certain Kinds of Input
To create a textctrl that only allows a certain kind of input, use wxMaskedEditCtrl or wxFormatValidator. wxMaskedEditCtrl works with a mask, that is, each char in its place. wxFormatValidator is useful for writing localized numbers (to deal with a decimal separator for example). You can find them at contributed classes.
[edit] In-place Input Capitalization
Until there is no other solution available, do it like this:
BEGIN_EVENT_TABLE(MyDialog, wxDialog)
...
EVT_TEXT(MyDialog::IdOfTxtCtrl, MyDialog::OnText)
END_EVENT_TABLE()
void MyDialog::OnText(wxCommandEvent& event)
{
if(!m_ctrlPtr->IsModified())
return;
else if(m_busy)
{
// don't know why I need this
// IsModified doesn't work the way I thought
// it should (according to the reference)
return;
}
long insertionPoint = m_ctrlPtr->GetInsertionPoint();
m_busy = true;
m_ctrlPtr->SetValue(m_ctrlPtr->GetValue().Upper());
m_busy = false;
m_ctrlPtr->SetInsertionPoint(insertionPoint);
}
[edit] Different Characters with Different Colours
- use wxTextCtrl::SetStyle(). Note that to do some of this, you'll need to have created the wxTextCtrl with the wxTE_RICH2 style for your wxMSW port.
or:
- you need to use wxTextAttr. See the manual and the text sample.
[edit] Scrolling
Is there a way to reliably scroll so that the bottom line of text is at the bottom of the wxTextCtrl?
If you always use AppendText() it will scroll automatically (if it doesn't, it's a bug). You can always ensure that the last line is visible using ShowPosition(GetLastPosition()) too, of course.
Note: If you rely on this mechanism, the text will scroll a whole page down at a time. If you want the control to show the last line of text at the bottom, you can add "ScrollLines(1)" right after the AppendText call. AppendText will ensure the new line is visible, and ScrollLines will ensure the scroll bar is at the real end of the range, not further.
Under (at least) wxWidgets 2.6.3 under Windows the above seems to work as long as the string you pass to AppendText() only contains a single '\n'. If there are several lines it seems you have to modify the argument to ScrollLines accordingly. Example MSW code:
function AddSomeText( wxTextCtrl *aChatWindow, wxString s )
{
// HACK: Under Windows (using wxTE_RICH2) we have trouble ensuring that the last
// entered line is really at the bottom of the screen. We jump through some
// hoops to get this working.
// Count number of newlines (i.e lines)
int lines = 0;
const char* cstr = s.c_str();
for( ; *cstr ; ++cstr )
if( *cstr == '\n' )
++lines;
// Dance...
aChatWindow->Freeze(); // Freeze the window to prevent scrollbar jumping
aChatWindow->AppendText( s ); // Add the text
aChatWindow->ScrollLines( lines + 1 ); // Scroll down correct number of lines + one (the extra line is important for some cases!)
aChatWindow->ShowPosition( aChatWindow->GetLastPosition() ); // Ensure the last line is shown at the very bottom of the window
aChatWindow->Thaw(); // Allow the window to redraw
}
The Freeze() / Thaw() calls might not be necessary, but I added them for good measure.
[edit] Disabling Auto-scroll
You cannot disable auto-scroll with AppendText() in a cross-platform manner. Under Windows:
long pos = ::SendMessage( ctrl->GetHwnd(), EM_GETFIRSTVISIBLELINE, 0, 0 ); ctrl->AppendText(text); int newpos = ::SendMessage( ctrl->GetHwnd(), EM_GETFIRSTVISIBLELINE, 0, 0 ); ::SendMessage( ctrl->GetHwnd(), EM_LINESCROLL, 0, pos-newpos );
[edit] Background Color
You can change the background color of the entire wxTextCtrl by using the SetBackgroundColour (note the British spelling) method of wxWindow.
TextOutput->SetBackgroundColour (wxColour("#000000"));
[edit] wxTE_PROCESS_ENTER and Multiline wxTextCtrls
Multiline wxTextCtrls do not support wxTE_PROCESS_ENTER, and should never get EVT_TEXT_ENTER events. The fact that this sometimes works on MSW is actually a (minor) bug.
[edit] Right Justifying Text in a wxTextCtrl Textbox
With wxTE_RIGHT. (Didn't work in some pre-2.6 versions).
[edit] SetDefaultStyle
It seems that SetDefaultStyle() does not work if you have the wxTE_RICH2 flag set.
[edit] Pitfalls
PositionToXY() always returns FALSE on wxMac at least in 2.4.2. This function is not implemented on that platform.
- PositionToXY()/XYToPosition() also is not implemented on wxMac 2.6.3 and 2.8.0
[edit] See Also
Official documentation: wxTextCtrl Class Reference
