Click here to Skip to main content
Licence CPOL
First Posted 12 Apr 2002
Views 70,433
Bookmarked 26 times

Validating Tree/List Control In-Place Edit

By | 14 Apr 2002 | Article
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)

About the Author

Kyudos

Software Developer

New Zealand New Zealand

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralVirtual key codes PinsussAnonymous7:09 24 Apr '04  
GeneralRe: Virtual key codes PinmemberJudd22:10 25 Apr '04  

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.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 15 Apr 2002
Article Copyright 2002 by Kyudos
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid