Click here to Skip to main content
15,881,559 members
Articles / Desktop Programming / MFC
Article

The Ultimate Toolbox Masked Edit

Rate me:
Please Sign up or sign in to vote.
4.25/5 (3 votes)
25 Aug 2007CPOL4 min read 38.9K   462   16   3
The Ultimate Toolbox provides a generic masked edit control for validated input.

Visit the Ultimate Toolbox main page for an overview and configuration guide to the Ultimate Toolbox library.

Source code and project files for this sample can be found in the samples\gui\maskededit directory of the sample projects download.

Contents

Overview

Image 1

The COXMaskedEdit control is an easy-to-use edit control that allows you to specify the format in which text entries will be made.

Features

The COXMaskedEdit control provides restricted data input as well as formatted data output. This control supplies visual cues about the type of data being entered or displayed.

COXMaskedEdit generally behaves as a standard text box control with enhancements for optional masked input and formatted output. If you don't use an input mask, it behaves much like a standard text box.

If you define an input mask, each character position in the COXMaskedEdit control maps to either a placeholder of a specified type or a literal character. Literal characters, or literals, can give visual cues about the type of data being used. For example, the parentheses surrounding the area code of a telephone number are literals: (206).

If you attempt to enter a character that conflicts with the input mask, the control generates a "ValidationError" beep. The input mask prevents you from entering invalid characters into the control. When you define an input mask, the Masked Edit control behaves differently from the standard text box. The insertion point automatically skips over literals as you enter data or moves the insertion point.

When you insert or delete a character, all non-literal characters to the right of the insertion point are shifted, as necessary. If shifting these characters leads to a validation error, the insertion or deletion is prevented, and a "ValidationError" beep is triggered. For example, suppose the Mask property is defined as "?###", and the current value of the Text property is "A12." If you attempt to insert the letter "B" to the left of the letter "A", the "A" would shift to the right. Since the second value of the input mask requires a number, the letter "A" would cause the control to generate a "ValidationError" beep.

COXMaskedEdit also validates the parameter value of the SetInputText function the user passes at run time. If you use the SetInputText function so that it conflicts with the input mask, the function will return an error code.

You may select text in the same way as for a standard text box control. When selected text is deleted, the control attempts to shift the remaining characters to the right of the selection. However, any remaining character that might cause a validation error during this shift is deleted, and no "ValidationError" beep is generated.

Normally, when a selection in the COXMaskedEdit control is copied onto the Clipboard, the entire selection, including literals, is transferred onto the Clipboard. You can use the SetClipMode function to define the behavior so that only the user-entered data is transferred onto the Clipboard - the literal characters that are part of the input mask are not copied.

Usage

You can attach a COXMaskedEdit to an existing CEdit control by subclassing the latter.

This is remarkably simple to do in the DevStudio IDE when working with an MFC dialog. Place a standard edit control on the dialog using the dialog editor. Invoke the Class Wizard and select the Member Variables page. Add a member variable for the ID of the edit control, selecting a CEdit control as the type.

Next, open the header file for the dialog. Include OXMaskedEdit.h. In the AFX_DATA section for the dialog you will see the declaration for the edit control as a CEdit. Change this to COXMaskedEdit (or a class derived from COXMaskedEdit) and viola - you can now initialize the mask etc. You won't need to call Create. (Don't forget to include the OXMaskedEdit.cpp file in your project!)

The samples\gui\maskededit sample demonstrates setting different masks.

C++
#include "OXMaskedEdit.h"    // COXMaskedEdit

/////////////////////////////////////////////////////////////////////////////

// CMaskedEditTestDlg dialog

class CMaskedEditTestDlg : public CDialog
    {
    // Construction

    public:
        CMaskedEditTestDlg(CWnd* pParent = NULL) ;
        
        // Dialog Data

    protected:
        //{{AFX_DATA(CMaskedEditTestDlg)

    enum { IDD = IDD_MASKEDEDITTEST_DIALOG };
        COXMaskedEdit m_editMasked   ;
        CComboBox     m_comboMasks   ;
        CString       m_csPromptChar ;

If you want to be notified on validation of the data entered, you can add an ON_NOTIFY handler to the parent of the COXMaskedEdit - in this case the sample dialog:

C++
BEGIN_MESSAGE_MAP(CMaskedEditTestDlg, CDialog)
    //{{AFX_MSG_MAP(CMaskedEditTestDlg)

    ...
    //}}AFX_MSG_MAP

    ON_NOTIFY(OXMEN_VALIDATE,IDC_EDIT_TEST,OnValidateEditTest)
END_MESSAGE_MAP()

And code a handler - this code from the sample just looks for "345" and will not allow the user to leave the control if found:

C++
void CMaskedEditTestDlg::OnValidateEditTest(NMHDR * pNotifyStruct, 
    LRESULT * result)
{
    LPMENMHDR pMENotifyStruct = (LPMENMHDR)pNotifyStruct;

    UpdateData();

    CString sText=m_editMasked.GetInputData();

    // just as an example: if user typed "345" then typed 

    // information is invalid,

    // cursor will be set before first found "345" symbol

    int nPos=sText.Find(_T("345"));
    if(nPos!=-1)
    {
        pMENotifyStruct->bValid=FALSE;
        pMENotifyStruct->nPosition=m_editMasked.LPtoRP(nPos);
    }
    else
    {
        pMENotifyStruct->bValid=TRUE;
        pMENotifyStruct->bDefaultValidation=TRUE;
    }
    *result=0;
}

The OnInitDialog method in the sample adds some masks to the mask selection combo, then calls the OnSelendokMasks handler explicitly to set the first one as the mask for the COXMaskedEdit:

C++
    m_comboMasks.AddString ( _T("Digit Test: ###-####") ) ;
    m_comboMasks.AddString ( _T("Decimal Test: ###.###.###.###") ) ;
    m_comboMasks.AddString ( _T("Thousands Test: ##,###.##") ) ;
    m_comboMasks.AddString ( _T("Time Test: ##:##") ) ;
    m_comboMasks.AddString ( _T("Date Test: ##/##/####") ) ;
    // Since the "C" programming language also uses the '\' as an 

    // escape character, you must use two in sequence to equal one 

    // switch for masking purposes. 

    m_comboMasks.AddString ( _T(
        "\\Alphanumeric Test: AAAAAAAAAA\\, AAAAAAAA") ) ;
    m_comboMasks.AddString ( _T(
        "\\Alphabetic Test: ????????????????") ) ;
    m_comboMasks.AddString ( _T(
        "Uppercase Test: >>>>>>> ????????") ) ;
    m_comboMasks.AddString ( _T(
        "Lowercase Test: <<<<<<< ????????") ) ;
    m_comboMasks.AddString ( _T("Phone:(###)###-#### Ext:####") ) ;
    m_comboMasks.AddString ( _T("AAA-#######")                  ) ;
    m_comboMasks.AddString ( _T(
        "&####-##-## ##\\:##\\:##")     ) ;
    m_comboMasks.SetCurSel ( 0 ) ;
    OnSelendokMasks() ;
void CMaskedEditTestDlg::OnSelendokMasks()
    {
    TRACE(_T("CMaskedEditTestDlg::OnSelendokMasks()\n"));

    int nSelected = m_comboMasks.GetCurSel() ;
    if ( nSelected >= 0 )
    {
        CString csNewMask ;
        m_comboMasks.GetLBText ( nSelected, csNewMask ) ;
        m_editMasked.SetMask   ( csNewMask ) ;
    }
}

Depending on the order of compilation you may also find if helpful to include OXMaskedEdit.h in the dialog and/or main application .cpp file of your project.

A full class reference for COXMaskedEdit is available in the compiled HTML help documentation.

History

Initial CodeProject release August 2007.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Canada Canada
In January 2005, David Cunningham and Chris Maunder created TheUltimateToolbox.com, a new group dedicated to the continued development, support and growth of Dundas Software’s award winning line of MFC, C++ and ActiveX control products.

Ultimate Grid for MFC, Ultimate Toolbox for MFC, and Ultimate TCP/IP have been stalwarts of C++/MFC development for a decade. Thousands of developers have used these products to speed their time to market, improve the quality of their finished products, and enhance the reliability and flexibility of their software.
This is a Organisation

476 members

Comments and Discussions

 
GeneralEN_KILLFOCUS not working Pin
weirdog24-Aug-10 11:44
weirdog24-Aug-10 11:44 
GeneralBUG: content is not updated in overwrite mode Pin
Bela Babik30-Jun-08 17:31
Bela Babik30-Jun-08 17:31 
GeneralRe: BUG: content is not updated in overwrite mode [modified] Pin
Graham Shanks19-Sep-08 4:43
Graham Shanks19-Sep-08 4:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.