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

More by Author

Must Read