Allowing the TAB key in Edit Controls


I was quite frustrated in with my application. I have a dialog with a simple multi-line edit (MLE) control. When I attempted to press the TAB key, the entire contents of my edit control would be highlighted! Evidently, this is the default action of an edit control when the Tab key is pressed. Anyway, I wanted the Tab key to work as I would expect it to in a control that is supposedly mimicing an editor so I set out to find a solution.


Basically, it came down to control's the tried and true, PreTranslateMessage member function. It works like this. PreTranslateMessage is a virtual member function that is called in order to give your control a chance to do something before (or instead of) the default behavior of the control. Therefore, in this function, I check to see if the message being sent is a WM_KEYDOWN message (indicating that the user has pressed some key). I then determine if the key being pressed is the Tab key (whose id is VK_TAB). If these two cases are true, I simply deselect any selected text and insert a tab character into the control (\t).

Implementing this Solution

Here are the steps necessary to implement my work-around.
  1. To your override of CDialog class, add the following method:
  2. virtual BOOL PreTranslateMessage(MSG *);
  3. Implement this function, for example:
  4. BOOL CEditExDlg::PreTranslateMessage(MSG* pMsg) 
     if ((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_TAB)) 
      // get the char index of the caret position
      int nPos = LOWORD(m_MyEditCtl.CharFromPos(m_MyEditCtl.GetCaretPos()));
      // select zero chars
      m_MyEditCtl.SetSel(nPos, nPos);
      // then replace that selection with a TAB
      m_MyEditCtl.ReplaceSel("\t", TRUE);
      // no need to do a msg translation, so quit. 
      // that way no further processing gets done
      return TRUE;
     //just let other massages to work normally
     return CDialog::PreTranslateMessage(pMsg);


Download demo project - 10 Kb


  • Goal

    Posted by snareenactina on 12/09/2012 09:36am

    ararmenian You may not be able to find this page because of: Data from over 100 sources as well as proprietary data on key industries. All organized, translated and updated weekly covering city and provincial economies and 10 of China's leading industries. Over the past few years, Vietnam has begun to rise up in the rankings of world countries. Here is a quick rundown of how it compares to other countries: exact Gut instinct and human nature still rule the day. hlavního G. Recent Revival goalc Schools are supposed to be sanctuaries of education, and the threat of being sent to prison for a minor infraction likely discourages attendance for some at-risk youth. restrooms These data show the tax burden (personal and corporate) and national debt as a percentage of GDP. Samples are taken at 10 year intervals (snapshots, but the rolling averages are very close). compound Just so you know whom your readership comprises of, I live in Ireland and have a keen interest in eschatology. I chanced upon the two sites and have now followed your posts now for a number of weeks. Hugely informative and well composed. Thank you. merida One dimension of growth rebalancing on which there has in fact been progress is related to China’s external balances. The trade surplus fell from its peak level of over 7 percent of GDP in 2007 to 3 percent in 2010 (Figure 8). Export and import growth took a tumble during the financial crisis but have since recovered sharply (Figure 9). The investment boom has driven import growth sharply higher while export growth has been strong but lower than import growth due to weaknesses in advanced country markets that absorb a large fraction of China’s imports. strictly Macroeconomics is a broad topic, which scholars and students find complex to analyze. This is because this topic focuses on how economic forces affects political, social, economic, and labor institutions

  • Can you control the width of the Tab space?

    Posted by mtb2440 on 10/28/2005 05:14pm

    I would like to set it to 4 spaces. Thanks - great technique. MB


    Posted by Legacy on 10/28/2003 12:00am

    Originally posted by: Andy Walker


    There is an MFC defined way of doing this which means you don't have to check for the correct controls in a muti-control dialog etc.

    All you need to do to get the Tab to work in an edit control of a dialog is override the WM_GETDLGCODE message which is sent to all controls in a dialog box. The solution isn't available via ClassWizard.

    Create your control in the Resource Editor.

    Derive a class from CEdit, and add the handler to the header...

    class CTabEdit : public CEdit
    // Construction

    afx_msg UINT OnGetDlgCode();


    ...and the function body to the .cpp...

    // NOTE - the ClassWizard will add and remove mapping macros here.

    // CTabEdit message handlers
    UINT CTabEdit::OnGetDlgCode()
    return DLGC_WANTTAB;

    ...In the function return DLGC_WANTTAB as above.

    In your dialog with the control in it, include the Header for the above class in the .h file.

    #include "TabEdit.h"

    class CBuildManagerDlg : public CDialog

    Now add a variable for the control in the dialog using the Class wizard.

    Then alter the Classwizard code to use your new CTabEdit...

    // Dialog Data
    CTabEdit m_cTabEdit;
    CButton m_cOKBtn;
    CListbox m_cStopStartList;


    No need to use Pre-Translate.


  • Thanks for the post

    Posted by Legacy on 04/22/2003 12:00am

    Originally posted by: Newbie

    Thanks for the post. I don't due alot of windows programming but ran into this same problem and because of your post I made this change in under 5 minutes. So thanks for taking the time to post.

  • How do I catch any key without using MFC?

    Posted by Legacy on 03/08/2003 12:00am

    Originally posted by: Witek

    If keybord focus is in some edit control and I want to catch arrow keys without using MFC. Can anybody helps?

  • Greate Thank you..

    Posted by Legacy on 02/19/2003 12:00am

    Originally posted by: Kim Su-Jung

    i am in agony this problem. 

    thank you

  • Can we display new line chracter as well

    Posted by Legacy on 08/06/2002 12:00am

    Originally posted by: Ramesh

    I have an Edit Control in VC++, and I basically use it for logging. So I assign the member variable to the log info I want and then I use the UpdateData(FALSE).
    Now the problem I have is I want the new line character to function as new line, but instead it displays some special character there. How do I send a new line character to my Edit Control.

  • We can also use CEdit::PreTranslateMessage

    Posted by Legacy on 01/02/2002 12:00am

    Originally posted by: Franz Wong

    If we use CEdit::PreTranslateMessage, then the program will only do the job when the focus is on the edit box.

  • a simple question???

    Posted by Legacy on 12/07/2001 12:00am

    Originally posted by: John Miller

    This question may look stupid or simple for you folks here,
    but I am still puzzled with this:

    is a control (such as a Edit box or Static control) area
    still the client area of the main dialog window?

    When the mouse move occurs within any control box area,
    it looks that the neither the WM_MOUSEMOVE nor the WM_NCMOUSEMOVE message does not get sent!

    When you put a control on top of the dialog client area,
    how do you capture the mouse move event WITHIN the control

    Hope some one would kindly point it out, thanks!

  • if this isn't the only control in the window ...

    Posted by Legacy on 08/15/2001 12:00am

    Originally posted by: Rick Phillips

    I found this solution to be quite helpful, as in my application I needed a simple way to enter script-language syntax.  However I ran into a slight problem. Because this solution captures all of the <TAB> key events, if there are other controls on the window then it is no longer possible to <TAB> from one to the other.

    The solution to this is quite simple. In pre-translate message, just check to see if your edit control has the input focus:

    CEdit* pMyEditControl = (CEdit*)GetDlgItem(IDC_MY_EDIT);

    // see if the multiline edit control has the input focus
    if ((CEdit*)this->GetFocus() == pMyEditControl)
    // implement Hilmi Jauffer's solution here




  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Entire organizations suffer when their networks can't keep up and new opportunities are put on hold. Waiting on service providers isn't good business. In these examples, learn how to simplify network management so that your organization can better manage costs, adapt quickly to business demands, and seize market opportunities when they arise.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date