Home

Windows Controls: Edit Control

 

Introduction to Edit Controls

 

Description

An edit box is a Windows control used to display text or get it from the user. To provide its functionality, the control displays a box, whose background is white by default, surrounded by a black line. If the box is empty, the user may be expected to enter some letters, numbers, or other characters into it. If the box contains some text, the user should be able to edit it. Another edit box may be used to present text to the user without his or her being able to change it. The text that displays in an edit box is referred to as its value.

Like most other controls, the role of an edit box is not obvious at first glance. That is why it should (always) be accompanied by a label that defines its purpose. From the user's standpoint, an edit box is named after the label closest to it. Such a label is usually positioned to the left or the top side of the edit box. From the programmer's point of view, an edit box is a place holder used for various things. For example, you can show or hide it as you see fit.

Creating an Edit Control

To create an edit box, click the Edit Box button Edit from the Toolbox and click the desired area on a form or a dialog box.

An edit box is a control based on the CEdit class. Therefore, to programmatically create an edit box, declare a variable of CEdit type using its (default) constructor. To initialize the control, call the CEdit::Create() method. Its syntax is:

BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);

Here is an example:

BOOL CExerciseDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Add "About..." menu item to system menu.

	. . . No Change

	// TODO: Add extra initialization here
	CEdit* edtTotal = new CEdit;
	edtTotal-<Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER,
		         CRect(40, 20, 160, 43), this, 2002);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

The content of an edit box, that is, its value, is a string. It could be considered as null-terminated constant (LPCTSTR) or a CString value.

Edit Control Characteristics

 

Introduction

Like every other control added during design, you should give some attention to the identifier of an edit box. The first edit box placed on a form or dialog box receives an identifier of IDC_EDIT1. The second would be identified as IDC_EDIT2, etc. It is highly recommended that you give a meaningful and friendly identifier to each control. For example, if an edit box is used to receive or display an address, you can set its identifier to IDC_ADDRESS. If an edit box is used to enter an email address, you can change its ID to IDC_EMAILADDRESS or IDC_EMAIL_ADDRESS. An identifier should have a maximum of 30 characters. Notice that the ID contains C, which stands for Control.

If you plan to access an edit box in your code, you should create a variable for it. The variable can be a CEdit or a CString object. The difference is that, if you want to access the control as an MFC class, you should create the variable as a CEdit object. If you are more interested with the value (as a string) of the control, you should declare the variable as CString. Fortunately, you can add two variables for the same control.

The Text of an Edit Control

Probably the most important characteristic of an edit control for both the programmer and the user is the text it is displaying or that it can display. When you add an Edit control, it receives default text as Sample edit box. This text is not part of the control and does not show when the control comes up. It is only an indicator.

If the user wants to change the text of an edit box and if the control allows changes, she must first click in the control, which places a caret in the edit box. The caret is a blinking I beam that serves as a reminder that lets the user know what edit control would receive any change made. This means that if the user starts typing, the edit control in which the caret is positioned would display a change in its value. The edit box that has the caret is said to have focus. As mentioned already, the user gives focus to an edit box by clicking it. Remember that if a label that accompanies an edit box has an access key, the user can also give focus to the edit control by pressing the access key.

At any time, you can find out what text is in an edit control and there are various techniques you can use. We saw already how to get a handle to a control by calling the CWnd::GetDlgItem() method. After calling this method, you can use the CWnd::GetWindowText() method to find out what text an edit box holds. Here is an example:

void CExerciseDlg::CreateName()
{
    CEdit *edtFirstName;

    edtFirstName = reinterpret_cast<CEdit *>(GetDlgItem(IDC_FIRST_NAME));

    edtFirstName->GetWindowText(FirstName);
}

Another technique you can use to get the text of an edit control consists of calling the CWnd::GetDlgItemText() method. It is provided in two syntaxes as follows:

int GetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount ) const;
int GetDlgItemText(int nID, CString& rString ) const;

The nID argument is the identifier of the control whose text you want to retrieve. The lpStr or the rString is the returned value of the text in the edit box. It must be provided as a string variable. If you are using a null-terminated variable, pass a third argument as nMaxCount that specifies the maximum length of the string. Here is an example:

void CExerciseDlg::OnButton1()
{
    // TODO: Add your control notification handler code here
    CString Edit1, Edit2, Result;

    GetDlgItemText(IDC_EDIT1, Edit1);
    GetDlgItemText(IDC_EDIT2, Edit2);
    Result = Edit1 + " " + Edit2;

    SetDlgItemText(IDC_EDIT3, Result);
}

As mentioned above, the value of an edit box is of high interest to you and your users. If you want to retrieve the value of an edit box, call the CWnd::GetWindowText() method. If you want to display or change the text of an edit box, call the CWnd::SetWindowText() method. The SetWindowText() method takes a constant pointer to null-terminated string (LPCTSTR) and displays its value in the edit. This method is very convenient if you had add a CEdit variable to your edit control. If you have added the variable as a CString, you can use the CString::Format() method to change or format the value to display in an edit box.

Giving Focus

To manage its role on a form or dialog box, an edit control is equipped with some messages known as notifications. To give focus to an edit control, you can call the SetFocus() method. When this happens, the control fires an event named OnSetFocus. It is sent when an edit box receives focus. This happens when the user clicks the edit box or after previously pressing Tab, to give focus to the control:

BEGIN_MESSAGE_MAP(CExerciseDlg, CDialog)
//{{AFX_MSG_MAP(CDialog3aDlg)
    ON_EN_SETFOCUS(IDC_LAST_NAME, OnSetFocusLastName)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

...

void CExerciseDlg::OnSetFocusLastName()
{
    // TODO: Add your control notification handler code here
    m_Message.SetWindowText("The First Name has focus");
}

The OnExit() event occurs when the control loses focus. This is the result of an ON_EN_KILLFOCUS message. In the case of an edit box, this could happen if the control has focus and the user presses Tab; the edit box would lose focus.

Changing Text

One way the user can use an edit control consists of typing in it or editing its existing text. When this happens, the control fires an ON_EN_CHANGE event that results in the OnChange method. This event sends a message that the content of the edit box has changed. You can use this event to check, live, what the user is doing in the edit box. For example, if you create a dialog box or a form with a first and last names edit boxes, you can use another edit box to display the full name. You can implement the OnChange events of the edit boxes as follows:

BEGIN_MESSAGE_MAP(CExerciseDlg, CDialog)
//{{AFX_MSG_MAP(CDialog3aDlg)
    ON_EN_SETFOCUS(IDC_LAST_NAME, OnSetFocusLastName)
    ON_EN_CHANGE(IDC_FIRST_NAME, OnChangeFirstName)
    ON_EN_CHANGE(IDC_LAST_NAME, OnChangeLastName)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

...

void CExerciseDlg::OnChangeFirstName()
{
    // TODO: Add your control notification handler code here
    m_FirstName.GetWindowText(m_strFirstName);
    m_LastName.GetWindowText(m_strLastName);
    CString FullName = m_strFirstName + " " + m_strLastName;

    m_FullName.SetWindowText(FullName);
}

void CExerciseDlg::OnChangeLastName()
{
    // TODO: Add your control notification handler code here
    m_FirstName.GetWindowText(m_strFirstName);
    m_LastName.GetWindowText(m_strLastName);
    CString FullName = m_strFirstName + " " + m_strLastName;

    m_FullName.SetWindowText(FullName);
}

ON_EN_UPDATE: The OnUpdate() event is sent after the content of an edit box has changed but before the text is formally displayed.

 
 
 

The Maximum Text Length

When adding a variable for the edit control, you can specify the maximum allowable number of characters the user can enter. If the user attempts exceeding this maximum, an ON_EN_MAXTTEXT event is sent. This event is implemented through the OnMaxtext() method. You can catch this event to let the user know about the problem. If you set up the Maximum Characters fine, you do not need to perform any "if" or "while" checking. The edit control would do it itself.

The OnErrSpace() event is event is sent if the compiler encountered a problem when attempting to allocate memory space to the control. This event is generated from the ON_EN_ERRSPACE message.

A Read-Only Edit Control

An edit box can be used to request information from the user. If you want to prevent the user from changing the value of an edit box, you can make it read-only. This is taken care of by setting the Read-Only property to True or checking its check box. To do this programmatically, call the CEdit::SetReadOnly() method.

The Caret

If an edit box is not read-only, that is, if it allows the user to change its value, the user must first give it focus. When an edit box has focus, it displays a blinking caret. By default, the caret is an I beam. If you want to use a different caret, you have various options. You can change the caret from an I beam to a wider or taller gray caret by calling the CWnd::CreateGrayCaret() method. Its syntax is:

void CreateGrayCaret(int nWidth, int nHeight);

This method allows you to specify a width and a height for a gray blinking caret. After creating the caret, to display it, call the CWnd::ShowCaret() method. Its syntax is:

void ShowCaret( );

Here is an example:

BOOL CExerciseDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // TODO: Add extra initialization here
    m_Username.ShowCaret();

    return TRUE; // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

The above caret appears gray. If you want the caret to be completely black, you can call the CWnd::CreateSolidCaret() method. Its syntax is:

void CreateSolidCaret( int nWidth, int nHeight );

This method creates a rectangular caret of nWidth x nHeight dimensions. Here is an example:

BOOL CExerciseDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // TODO: Add extra initialization here
    m_Username.CreateSolidCaret(5, 15);
    m_Username.ShowCaret();

    return TRUE; // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

To provide a better designed caret, you can call the CWnd::CreateCaret() method. Its syntax is:

void CreateCaret(CBitmap* pBitmap);

Before calling this method, you can first design a bitmap, load it, and then pass it as the pBitmap argument. After initializing and loading the bitmap, to display it in the edit box, call the CWnd::ShowCaret() method. Here is an example:

BOOL CExerciseDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // TODO: Add extra initialization here
    CEdit *edtBookTitle;
    CBitmap *pBitmap = new CBitmap;

    edtBookTitle = reinterpret_cast<CEdit *>(GetDlgItem(IDC_BOOK_TITLE));

    pBitmap->LoadBitmap(IDB_BMP_CARET);
    edtBookTitle->CreateCaret(pBitmap);
    edtBookTitle->ShowCaret();

    return TRUE; // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

If an edit box is editable and the user starts typing in it, the new characters would display. As the user is typing, the caret moves from left to right (for US English). The user can also move the caret back and forth using the Backspace, Delete, Home, End, or the arrow keys. At any time you can find out the current position of the caret by calling the CWnd::GetCaretPos() method. Its syntax is:

static CPoint PASCAL GetCaretPos();

This method retrieves the left (x) and bottom (y) coordinates of the caret in the control that called it. These coordinates represent the member variables of a CPoint that this method returns. The measures are relative to the control and not the control's parent.

Here is an example:

void CExerciseDlg::CaretPosition(void)
{
    CEdit *edtBookTitle;
    CStatic *stcCaretPos;
    CPoint CrtPos;
    char Msg[40];

    edtBookTitle = reinterpret_cast<CEdit *>(GetDlgItem(IDC_BOOK_TITLE));
    stcCaretPos = reinterpret_cast<CStatic *>(GetDlgItem(IDC_CARET_POS));

    CrtPos = edtBookTitle->GetCaretPos();
    sprintf(Msg, "Caret Position: (%d, %d)", CrtPos.x, CrtPos.y);

    stcCaretPos->SetWindowText(Msg);
}

An Edit Control for a Password

If want to hide the characters that display in an edit box, you can set the Password property to True. To do this programmatically, add the ES_PASSWORD style to the edit control. This style makes the edit control displays each character, or changes each one of its characters into an asterisk. If you prefer another symbol for the password style, call the CEdit::SetPassword() method. Its syntax is:

void SetPasswordChar(TCHAR ch);

This method takes as argument the character that you want to use.

If an edit box is configured to display an asterisk character and you want to find out what that character is, call the CEdit::GetPasswordChar(). Its syntax is:

TCHAR GetPasswordChar() const;

This method takes no argument but returns the symbol used to mask the characters of a password-configured edit box.

The Character Case

By default, an edit box is configure to display or receive text of any alphabetic and non-alphabetic character. The alphabetical letters are received by their case and kept like that, uppercase and lowercase. If you want to convert an edit box' characters to uppercase, set the Uppercase property to True or programmatically add the ES_UPPERCASE style. In the same way, to convert the characters to lowercase, either at design time set the Lowercase property to True or programmatically add the ES_LOWERCASE style. The non-alphabetical characters are not treated by their case.

An Edit Control for Integers

If you want, you can configure the edit box to allow only numeric characters. This is done by setting the Number property to True.

The Text Alignment

By default, the characters entered in an edit box start their positioning to the left, which is the default for regular text. You can align its value to the center or the right by selecting the desired value from the Align Text combo box. Any of these three alignment modes can also be set programmatically by adding either the ES_LEFT, the ES_CENTER, or the ES_RIGHT style.

Multiline Edit Controls

 

Introduction

By default, an edit box is used to display a single line of text. An edit box is referred to as multiline when it can display its text on more than one line.

To create a multiline edit box, use the same Edit control as the above single line Edit box. To make this a multiline edit box, set its Multiline property to True. At design time, to make it obvious that the control can display more than one line of text, heighten it:

Multiple Line Edit Control

To programmatically create a multi-line edit control, declare a variable of type CEdit. When initializing it, add the ES_MULTILINE style. Here is an example:

BOOL CExerciseDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Add "About..." menu item to system menu.

	. . . No Change

	// TODO: Add extra initialization here
	CEdit* edtMemo = new CEdit;
	edtMemo->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_MULTILINE,
		        CRect(10, 10, 300, 200), this, 2002);

	return TRUE;  // return TRUE  unless you set the focus to a control
} 

Supporting Carriage Return

If the user is typing text in an edit control and press Enter, the control, usually a button, that is the default would be activated. This feature is valuable for a single line edit box. If you are creating a multiline edit box, you should allow the user to press Enter while entering text into the control. This would prevent the default button from being activated and would transfer the caret to the next line. To provide this functionality, add the ES_WANTRETURN style or, at design time, set the Want Return property to True.

Supporting Scroll Bars

If the text of the edit control is longer than the edit control can display at one time, you should equip it with scroll bars. To do this, at design time, set the Horizontal and/or the Vertical Scroll properties to True. At run time, add the WS_HSCROLL and/or the WS_VSCROLL properties.

 
 
   
 

Home Copyright © 2010-2011 FunctionX, Inc.