Click here to Skip to main content
Click here to Skip to main content
Go to top

Validating Tree/List Control In-Place Edit

, 14 Apr 2002
Rate this:
Please Sign up or sign in to vote.
Adding per character input validation to the in-place label edit control in list and tree controls.

Introduction

Ever wanted to edit tree or list control labels, and include text validation as you type? I searched a lot of places for such methods of validating text while typing in the label edit control of a tree or list control on an MFC dialog. I could only find complicated custom classes and the like, most of which had far more functionality than I was after.

Method

I implemented something very simple in the dialog PreTranslateMessage method (use the Class Wizard to add this method to your dialog code). Whether the following code is useful to you depends on the complexity of the validation you require. I was only interested in restricting input, so this works very well.

BOOL CCMyDialog::PreTranslateMessage(MSG* pMsg)
{
    //----------------
    // Local variables
    //----------------

    CString strEditIn = "";
    CString strEditOut = "";
    TCHAR c;

    //------------------------------
    // Get the window with the focus
    //------------------------------

    CWnd *pCont = GetFocus();

    //--------------------------------
    // Get list (or tree) edit control
    //--------------------------------
    
    CEdit *pEdit = m_ListCtrl.GetEditControl();
    //CEdit *pEdit = m_TreeCtrl.GetEditControl();

    //----------------------------------------------------
    // Only proceed if the edit control exists and has 
    // the focus
    //----------------------------------------------------

    if (pCont == pEdit)
    {
        switch(pMsg->message)
        {
            //----------------------------
            // Catch the character message
            //----------------------------

            case WM_CHAR:
            switch(pMsg->wParam)
            {
                //-----------------------------
                // Ignore these basic edit keys
                //-----------------------------

                case VK_RETURN:
                case VK_DELETE:
                case VK_BACK:
                case VK_ESCAPE:
                case VK_LEFT:
                case VK_RIGHT:
                case VK_UP:
                case VK_DOWN:
                case VK_SHIFT:
                case VK_CONTROL:
                ::TranslateMessage(pMsg);
                ::DispatchMessage(pMsg);
                break;

                //------------------
                // Process each CHAR
                //------------------
                
                default:
                c = pMsg->wParam;
                //----------------------------------------
                // This is my very simple per-character
                // validation routine. Invalid chars
                // are not passed on. Any validation 
                // code could be added here.
                //
                strEditIn = c;
                strEditIn.MakeUpper();
                strEditOut = ValidateText(strEditIn, 1,
                                                    FALSE);
                if (strEditIn != strEditOut)
                {
                    pMsg->wParam = 0;
                }
                //----------------------------------------
                ::TranslateMessage(pMsg);
                ::DispatchMessage(pMsg);
                break;
            }
            return (TRUE);
            break;
        }
    }
    return CDialog::PreTranslateMessage(pMsg);
}

However, bear in mind that some of the pre-defined virtual key codes can conflict with other character codes. For instance, VK_DOWN equals (0x28) (40), which is the same code as the open bracket '(' character. Normally, the down character isn't that important in single line Edit controls, but if you do need to include 'down' and the '(' character, you would have to use the WM_KEYDOWN message to record which key has actually been pressed.

For alphanumeric text, you could try the following:

BOOL CCMyDialog::PreTranslateMessage(MSG* pMsg)
{
    //----------------
    // Local variables
    //----------------

    CString strEditIn = "";
    CString strEditOut = "";
    TCHAR c;
    BOOL bPassThru = FALSE;

    //------------------------------
    // Get the window with the focus
    //------------------------------

    CWnd *pCont = GetFocus();

    //--------------------------------
    // Get list (or tree) edit control
    //--------------------------------
    
    CEdit *pEdit = m_ListCtrl.GetEditControl();
    //CEdit *pEdit = m_TreeCtrl.GetEditControl();

    //----------------------------------------------------
    // Only proceed if the edit control exists and has the
    // focus
    //----------------------------------------------------

    if (pCont == pEdit)
    {
        switch(pMsg->message)
        {
            //---------------------------
            // Catch the key down message
            //---------------------------

            case WM_KEYDOWN:

            //--------------------------------------------
            // Alphanumeric characters are between VK_HELP
            // and VK_LWIN
            //--------------------------------------------

            if ((pMsg->wParam <= VK_HELP) ||
                          (pMsg->wParam >= VK_LWIN))
            {
                bPassThru = TRUE;
            }

            //----------------------------
            // Catch the character message
            //----------------------------

            case WM_CHAR:
            switch(pMsg->wParam)
            {
                //--------------------------------
                // The backspace is a special case
                //--------------------------------

                case VK_BACK:
                ::TranslateMessage(pMsg);
                ::DispatchMessage(pMsg);
                break;

                //------------------
                // Process each CHAR
                //------------------
                
                default:
                if (!bPassThru)
                {
                    c = pMsg->wParam;
                    //-------------------------------------
                    // This is my very simple per-character
                    // validation routine. Invalid chars
                    // are not passed on. Any validation 
                    // code could be added here.
                    //
                    strEditIn = c;
                    strEditIn.MakeUpper();
                    strEditOut = ValidateText(strEditIn,
                                                 1, FALSE);
                    if (strEditIn != strEditOut)
                    {
                        pMsg->wParam = 0;
                    }
                    //-------------------------------------
                    ::TranslateMessage(pMsg);
                    ::DispatchMessage(pMsg);
                    return (TRUE);
                }
            }
            break;
        }
    }
    return CDialog::PreTranslateMessage(pMsg);
}

Note this is not meant to be an article on methods of validating text. There are plenty of such methods available on line.

Revision History

12 Aug 2002 - Initial Revision.

License

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

Share

About the Author

Kyudos
Software Developer
New Zealand New Zealand
No Biography provided

Comments and Discussions

 
GeneralVirtual key codes PinsussAnonymous24-Apr-04 7:09 
You say that VK_DOWN is the same as open bracket. Where can I find what { } and \ are? Some say that they're OEM specific, and I should use the VK_OEMX codes, but those don't compile. Why don't they have their own virtual key codes?
GeneralRe: Virtual key codes PinmemberJudd25-Apr-04 22:10 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140926.1 | Last Updated 15 Apr 2002
Article Copyright 2002 by Kyudos
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid