Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Using the CEdit control

0.00/5 (No votes)
23 Mar 2001 1  
An entry level tutorial on using the CEdit control.

Introduction

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 CEdit
  • Setting the Maximum Text Length
  • Handling CEdit notification messages
  • Adding, Deleting and Selecting text
  • Scrolling text in the CEdit control
  • 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.

Password (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 SetPasswordChar function.

Lowercase (ES_LOWERCASE) converts all characters to lowercase as they are typed into the Edit Control.

Uppercase (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.)

Number (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.

Auto HScroll 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.

Multi Line ES_MULTILINE. Designates a multiple-line Edit Control. (The default is single line.)

If the ES_AUTOVSCROLL style is specified, the Edit Control shows as many lines as possible and scrolls vertically when the user presses the ENTER key.

If 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.

If the 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.

Want Return 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.

OEM Convert 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.

Extended Styles

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 ModifyStyle() or 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 new and 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.

    m_pFlyEdit->CreateEx(WS_EX_CLIENTEDGE, _T("EDIT"), 
        "", 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.

//    m_pFlyEdit->Create( dwStyle, rc, this, IDC_EDIT6 );

//    m_pFlyEdit->ModifyStyleEx( 0, WS_EX_CLIENTEDGE );

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) 
{
    UpdateData();
    TRACE("CEditCtrlTutorialDlg::OnAlignmentChange( %d )\n", 
                                                 m_nAlignment);
    DWORD dwStyle = 
      WS_CHILD|WS_VISIBLE|WS_TABSTOP/*|WS_BORDER*/|ES_AUTOHSCROLL;

    switch( m_nAlignment )
    {
    case 1:
        dwStyle |= ES_CENTER;
        m_Edit3.ModifyStyle(ES_RIGHT|ES_LEFT,ES_CENTER);
        break;
    case 2:
        dwStyle |= ES_RIGHT;
        m_Edit3.ModifyStyle(ES_CENTER|ES_LEFT,ES_RIGHT);
        break;
    default:
        dwStyle |= ES_LEFT;
        m_Edit3.ModifyStyle(ES_CENTER|ES_RIGHT,ES_LEFT);
        break;
    }
    m_Edit3.Invalidate();

    CString str = _T("");
    if( m_pFlyEdit )
    {
        m_pFlyEdit->GetWindowText( str );
        delete m_pFlyEdit;
    }

    CRect rc;
    m_Template.GetWindowRect( &rc );
    ScreenToClient( &rc );
    m_pFlyEdit = new CEdit;
//    m_pFlyEdit->Create( dwStyle, rc, this, IDC_EDIT6 );

//    m_pFlyEdit->ModifyStyleEx( 0, WS_EX_CLIENTEDGE );

    m_pFlyEdit->CreateEx(WS_EX_CLIENTEDGE, _T("EDIT"), 
                           "", dwStyle, rc, this, IDC_EDIT6);
    // set font same as dialog to be sure they are the same

    m_pFlyEdit->SetFont( GetFont() );
    m_pFlyEdit->SetWindowText( str );

    UpdateData(FALSE);
}

ES_UPPERCASE and 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.

void CEditCtrlTutorialDlg::OnReadOnly() 
{
    UpdateData();
    m_Edit2.SetReadOnly( m_bReadOnly );
}

The 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:

void CEditCtrlTutorialDlg::OnNumbersOnly() 
{
    UpdateData();
    m_Edit7.SetSel(0,-1);        // select all the text

    m_Edit7.Clear();            // delete selection

    m_Edit7.ModifyStyle(ES_NUMBER*(m_bNumbersOnly==FALSE),
                             ES_NUMBER*(m_bNumbersOnly==TRUE));
}

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 UpdateData(FALSE).

void CEditCtrlTutorialDlg::OnFill() 
{
    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");
    UpdateData(FALSE);
}

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.

void CEditCtrlTutorialDlg::OnIn() 
{
    UpdateData();
    m_Edit8.SetSel(0,-1);        // Select all the text

    m_Edit8.Copy();             // copy text to clipboard

    m_Edit5.Paste();           // paste text from clipboard at caret pos

}

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.

void CEditCtrlTutorialDlg::OnSelect() 
{
    m_Edit5.SetSel(10,20);
    UpdateData(FALSE);
}

The caret (cursor) can be placed in the Edit Control by calling the SetSel() with the start and end position being the same.

    // Place caret at end of text

    UpdateData();
    int len = m_strEdit5.GetLength();
    m_Edit5.SetFocus();            // or you won't see it

    m_Edit5.SetSel(len,len);

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.

void CEditCtrlTutorialDlg::OnScrollDown() 
{
    m_Edit5.LineScroll(1);
}

void CEditCtrlTutorialDlg::OnScrollLeft() 
{
    m_Edit5.LineScroll(0,1);
}

void CEditCtrlTutorialDlg::OnScrollRight() 
{
    m_Edit5.LineScroll(0,-1);
}

void CEditCtrlTutorialDlg::OnScrollUp() 
{
    m_Edit5.LineScroll(-1);
}

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 SetWindowText().

    void CEditCtrlTutorialDlg::OnVScroll(UINT nSBCode, 
                          UINT nPos, CScrollBar* pScrollBar) 
    {
        if( pScrollBar->GetDlgCtrlID() == IDC_SPIN2 )
        {
            TRACE("CEditCtrlTutorialDlg::OnDeltaPosSpin2( %d )\n", nPos);
            CString str;
            str.Format("%d",nPos);
            m_Edit11.SetWindowText( str );
        }
        else
            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.

In the 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.SetBuddy( &m_Edit4 );        // attach to Edit Control

    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 UDS_AUTOBUDDY style.

Conclusion

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.

Happy programming!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here