This tutorial will show how to use the
CEdit class in a very basic dialog based application. It will cover the following points:
- Adding a
CEdit to your dialog
- Different Selection styles of
- Setting the Maximum Text Length
CEdit notification messages
- Adding, Deleting and Selecting text
- Scrolling text in the
- Attaching a Spin Control
This tutorial assumes that you are comfortable with creating a dialog based application using the VC++ 6 Class Wizard. If you require information on this topic, consult the article: A Beginners Guide to Dialog Base Applications - Part 1.
Adding a CEdit to your dialog
When your dialog-based application is generated, go to the Resources in the Workspace window. Select the dialog
IDD_LISTBOXTUTORIAL_DIALOG in the Dialog section. To insert the ListBox control, select it from the Control palette. The cross shaped cursor indicates where the centre of the ListBox will be placed.
Drag the edges of the control out to the desired size.
Different Selection styles of CEdit
There are a number of different styles of Edit Control. To change the style of the Edit Control, right click on it and select Properties. Then select the Styles or Extended Styles tab.
Among these styles, you will find those to do with just the border appearance of the control. You can play with those yourself and here we will concentrate on the functionality of the control.
ES_PASSWORD). Displays all characters as an asterisk (*) as they are typed into the Edit Control. The default character can be changed by using the
ES_LOWERCASE) converts all characters to lowercase as they are typed into the Edit Control.
ES_UPPERCASE). Converts all characters to uppercase as they are typed into the Edit Control.
Read Only (
ES_READONLY). Prevents the user from entering or editing text in the Edit Control.
Left Text (
ES_LEFT). Left-aligns text in a single-line or multi-line Edit Control.
Centre Text (
ES_CENTER). Centers text in a single-line or multi-line Edit Control. (In Win 98 and Win 2000, this will work with all Edit Controls. In earlier versions, with multi-line controls only.)
Right Text (
ES_RIGHT). Right-aligns text in a single-line or multi-line Edit Control. (In Win 98 and Win 2000, this will work with all Edit Controls. In earlier versions, with multi-line controls only.)
ES_NUMBER) allows only digits to be entered into the Edit Control.
No Hide Selection (
ES_NOHIDESEL) normally. An Edit Control hides the selection when the control loses the input focus and inverts the selection when the control receives the input focus. Specifying
ES_NOHIDESEL deletes this default action.
ES_AUTOHSCROLL. Automatically scrolls text to the right by 10 characters when the user types a character at the end of the line. When the user presses the ENTER key, the control scrolls all text back to position 0.
ES_MULTILINE. Designates a multiple-line Edit Control. (The default is single line.)
ES_AUTOVSCROLL style is specified, the Edit Control shows as many lines as possible and scrolls vertically when the user presses the ENTER key.
ES_AUTOVSCROLL is not given, the Edit Control shows as many lines as possible and beeps if ENTER is pressed when no more lines can be displayed.
ES_AUTOHSCROLL style is specified, the multiple-line Edit Control automatically scrolls horizontally when the caret goes past the right edge of the control. To start a new line, the user must press ENTER. If
ES_AUTOHSCROLL is not given, the control automatically wraps words to the beginning of the next line when necessary; a new line is also started if ENTER is pressed. The position of the word-wrap is determined by the window size. If the window size changes, the word-wrap position changes and the text is redisplayed.
Multiple-line Edit Controls can have scroll bars. An Edit Control with scroll bars processes its own scroll-bar messages. Edit Controls without scroll bars scroll as described above and process any scroll messages sent by the parent window.
Auto V Scroll
ES_AUTOVSCROLL. Automatically scrolls text up one page when the user presses ENTER on the last line.
ES_WANTRETURN. Specifies that a carriage return be inserted when the user presses the ENTER key while entering text into a multiple-line Edit Control in a dialog box. Without this style, pressing the ENTER key has the same effect as pressing the dialog box’s default pushbutton. This style has no effect on a single-line Edit Control.
ES_OEMCONVERT. Text entered in the Edit Control is converted from the ANSI character set to the OEM character set and then back to ANSI. This ensures proper character conversion when the application calls the
AnsiToOem Windows function to convert an ANSI string in the Edit Control to OEM characters. This style is most useful for Edit Controls that contain filenames.
Right Aligned Text
WS_EX_RIGHT. Gives a window, generic right-aligned properties. This style has an effect only if the shell language is Hebrew, Arabic, or another language that supports reading order alignment; otherwise, the style is ignored and not treated as an error.
Right-to-Left Reading Order
WS_EX_RTLREADING. Displays the window text using right-to-left reading order properties. This style has an effect only if the shell language is Hebrew, Arabic, or another language that supports reading order alignment; otherwise, the style is ignored and not treated as an error.
Left scroll bar
WS_EX_LEFTSCROLLBAR. If a vertical scroll bar is present, it is placed to the left of the client area.
Setting the Maximum Text Length
The maximum length of the text permitted in an Edit Control can be set in Class Wizard Member Variable tab. When you attach a String variable to the control, an Edit Control will appear at the bottom of the tab, for entering the maximum length of the input string. If this is left blank, the Edit Control will accept up to 64 Kbytes. As the Edit Control is created in the application's heap, the exact amount depends on the total use of the heap.
The alternative is to call
SetLimitText() in the
InitDialog(). There is also a function
LimitText() which is for backward compatibility only and should not be used. This way the maximum number of characters can be altered at anytime during runtime.
Changing Edit Control Styles at Runtime
It is not possible to change all the styles of an Edit Control at runtime using
ModifyStyleEx(). If you have the need to change the text alignment at runtime, for example, it is best to construct the Edit Control by calling
CreateEx, then deleting it and creating a new one when the style is to be changed. Alternatively, you can have 2 Edit Controls superimposed and hide the one with the incorrect style.
In the demo, I use
CreateEx to create the Edit Control, because then the extended style
WS_EX_CLIENTEDGE can be used to give the 3D border for the control.
"", dwStyle, rc, this, IDC_EDIT6);
You will note the two lines that are commented out. If you enable those and comment out the above line, you will get a flat Edit Control (without border, unless you also uncomment the
WS_BORDER style). The control remains flat because
WS_EX_CLIENTEDGE is one of the styles that cannot be changed after creation.
In the demo, the Edit Controls headed 'Text Alignment test' change the alignment style. The code deletes the old Edit Control and creates a new one each time the radio buttons are clicked.
ModifyStyle() is called for
m_Edit3 but as you will note, it has no effect.
void CEditCtrlTutorialDlg::OnAlignmentChange(UINT nID)
TRACE("CEditCtrlTutorialDlg::OnAlignmentChange( %d )\n",
DWORD dwStyle =
switch( m_nAlignment )
dwStyle |= ES_CENTER;
dwStyle |= ES_RIGHT;
dwStyle |= ES_LEFT;
CString str = _T("");
if( m_pFlyEdit )
m_pFlyEdit->GetWindowText( str );
m_Template.GetWindowRect( &rc );
ScreenToClient( &rc );
m_pFlyEdit = new CEdit;
"", dwStyle, rc, this, IDC_EDIT6);
m_pFlyEdit->SetFont( GetFont() );
m_pFlyEdit->SetWindowText( str );
ES_LOWERCASE styles need to be treated in the same way.
ES_READONLY style can be changed by calling the
SetReadOnly() member function as shown in the demo.
m_Edit2.SetReadOnly( m_bReadOnly );
ES_NUMBER style can also be changed at runtime using
ModifyStyle(). It is handy where an Edit Control is used for multiple purposes and also to turn the style in case it was forgotten in the RC script. The code below will actually toggle the style:
In this example, the Edit Control is also cleared while the style is changed. A number-only Edit Control can have non-numeric characters in it. It just won't permit them to be entered from the keyboard.
Handling CEdit messages
The notification messages available for Edit Controls are the following:
ON_EN_CHANGE. The user has taken an action that may have altered text in an Edit Control. Unlike the
EN_UPDATE notification message, this notification message is sent after Windows updates the display.
ON_EN_ERRSPACE. The Edit Control cannot allocate enough memory to meet a specific request.
ON_EN_HSCROLL. The user clicks an Edit Control’s horizontal scroll bar. The parent window is notified before the screen is updated.
ON_EN_KILLFOCUS. The Edit Control loses the input focus.
In many cases, this message is used to handle validation. If you do this, you must take care in displaying the error message. Directly calling
MessageBox() will cause another
Killfocus message to be generated when the message box is closed and, if the invalid input is still there start an endless loop.
ON_EN_MAXTEXT. The current insertion has exceeded the specified number of characters for the Edit Control and has been truncated. Also sent when an Edit Control does not have the
ES_AUTOHSCROLL style and the number of characters to be inserted would exceed the width of the Edit Control. Also sent when an Edit Control does not have the
ES_AUTOVSCROLL style and the total number of lines resulting from a text insertion would exceed the height of the Edit Control.
ON_EN_SETFOCUS. Sent when an Edit Control receives the input focus.
If the project demands that the maximum length change because of other settings, then it is best to check for this and change the setting each time the control gains focus.
ON_EN_UPDATE. The Edit Control is about to display altered text. Sent after the control has formatted the text but before it screens the text so that the window size can be altered, if necessary.
ON_EN_VSCROLL. The user clicks an Edit Control’s vertical scroll bar. The parent window is notified before the screen is updated.
Adding, Deleting and Selecting text
Adding text programmatically is very straight forward. If the existing text is to be replaced, either call
SetWindowText() for the control ..
m_pFlyEdit->SetWindowText( str );
or use Data Exchange and set the control's string variable and call
m_strEdit5 = _T("Soft rays of sunlight illuminate "
"the sky...\r\nIn hues of reds and pinks...\"
"\r\nWondrous in their magnificence..."
"\r\nNatures canvas at it's best...\"
"\r\nA sunrise, a sunset...\r\nVibrant and full
" of colour\r\nToo beautiful to miss");
To insert text or append text, it is of course possible to get the existing text, then make the changes in the
CString and put the modified string back as above. It is also possible to paste the text from the clipboard using the
Paste() member function. The code fragment below copies the text from one Edit Control to the clipboard and then pastes it at the cursor (caret) position in the multi-line control.
When you select the text programmatically, the Edit Control must have the
ES_NOHIDESEL style if the selection is to be visible. The following code selects the characters 10-20 in the multi-line control.
The caret (cursor) can be placed in the Edit Control by calling the
SetSel() with the start and end position being the same.
int len = m_strEdit5.GetLength();
Scrolling text in the CEdit Control
Multi-line controls can also be scrolled programmatically by calling the
LineScroll() member function. The 4 arrow buttons to the right of the multi-line control, each call scrolls the edit window one line/character in the matching direction.
Attaching a Spin Control
Select the Spin Control and place it beside the desired Edit Control, and adjust its size.
Note: sometimes the Spin Control looks larger in the editor than in the final dialog, so it pays the test what it looks like.
Spin Control Styles
UDS_HORZ. Causes the control’s arrows to point left and right instead of up and down.
UDS_WRAP. Causes the position to “wrap” if it is incremented or decremented beyond the ending or beginning of the range.
UDS_ARROWKEYS. Causes the control to increment and decrement the position when the UP ARROW and DOWN ARROW keys are pressed.
UDS_SETBUDDYINT. Causes the control to set the text of the buddy window (using the
WM_SETTEXT message) when the position changes. The text consists of the position formatted as a decimal or hexadecimal string.
More often than not, this is the style used because the framework has the code to do all the work for you. If you choose not to use this style, then you have to provide the function to update the Edit Control yourself. Warning: if you use the Data Exchange, you may find the other Edit Control gets reset to 0, so use
void CEditCtrlTutorialDlg::OnVScroll(UINT nSBCode,
UINT nPos, CScrollBar* pScrollBar)
if( pScrollBar->GetDlgCtrlID() == IDC_SPIN2 )
TRACE("CEditCtrlTutorialDlg::OnDeltaPosSpin2( %d )\n", nPos);
m_Edit11.SetWindowText( str );
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
UDS_NOTHOUSANDS. Does not insert a thousands separator between every three decimal digits.
UDS_AUTOBUDDY. Automatically selects the previous window in the Z-order as the control’s buddy window.
When you have a number of Edit/Spin Control pairs on the screen, getting the tab order (which affects the Z-order) correct is important so the Spin Control buddy's the correct Edit Control. Note also if the control has neither of the next 2 styles, it is unattached and stay where it was placed. With attached controls, the Spin Control is moved to be within the area of the Edit Control.
UDS_ALIGNRIGHT. Positions the spin button control next to the right edge of the buddy window. The width of the buddy window is decreased to accommodate the width of the control.
UDS_ALIGNLEFT. Positions the spin button control next to the left edge of the buddy window. The buddy window is moved to the right and its width decreased to accommodate the width of the control.
InitDialog(), the range and the initial position must be set. The Edit Control's initial text must also be set up there as in this code.
m_Spin.SetRange( -10, 10 );
m_Spin.SetPos( 0 );
m_Edit4.SetWindowText( "0" );
m_ManualSpin.SetRange( 0, 20 );
m_ManualSpin.SetPos( 0 );
m_Edit11.SetWindowText( "0" );
The commented line allows you to set the buddy Edit Control to the Spin Control if you can't have them in the tab order required when you use the
Many member functions have not been covered in this article. This will give you a chance to experiment with the more advanced features of the multi-line controls.
For character by character validation, see other articles such as A Validating Edit Control - Joseph M. Newcomer and others. The Rich Edit Control has the features discussed here and others for which it is mostly used.