[MFC] Cum prind 'Tab' si 'Enter' intr-un control edit?

Despre MFC, ATL si alte biblioteci C++ de la Microsoft (forum moderat)
Post Reply
User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

[MFC] Cum prind 'Tab' si 'Enter' intr-un control edit?

Post by Ovidiu Cucu » 07 Aug 2011, 09:19

Problema
Intr-un dialog, am un control edit (edit box) pentru care am derivat o clasa din CEdit. Programul nu intra in handlerele de mesaje pentru tastarura (WM_KEYDOWN, WM_KEYUP si WM_CHAR) atunci cand apas tasta 'Tab' sau 'Enter'.

Cauza
Intr-un dialog anumite taste au rol de navigare. Pentru a decide care taste sunt tratate in control si care in procedura dialogului, pentu navigare, sistemul trimite mai intai mesajul WM_GETDLGCODE procedurii fereasta a controlului.
Procedura fereastra default a unui control 'Edit' intoarce o valoare care spune ca vrea sa trateze mesajele de la tastatura inclusiv cele pentru sageti (DLGC_WANTARROWS), dar nu si pentru 'Tab' si 'Enter'.

Rezolvare
Pentru a adauga 'Tab' la lista se poate seta flag-ul DLGC_WANTTAB in valoarea returnata din WM_GETDLGCODE.
Pentru a aduga si 'Enter', flagul coresunzator este DLGC_WANTALLKEYS. Asta inseamna ca se vrea orice mesaj de la tastatura, inclusiv cel pentru tasta 'Enter'.

Exemplu

Code: Select all

// CustomEdit.h

class CCustomEdit : public CEdit
{
   // ...
   afx_msg UINT OnGetDlgCode();
   afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
   //...
};

Code: Select all

// CustomEdit.cpp
   // ...
   ON_WM_GETDLGCODE()
   ON_WM_CHAR()
   //}}AFX_MSG_MAP
END_MESSAGE_MAP()

Code: Select all

UINT CCustomEdit::OnGetDlgCode() 
{
   TRACE0("\n CCustomEdit::OnGetDlgCode");
   UINT nDefDlgCode = CEdit::OnGetDlgCode();             // default value
   UINT nCustomDlgCode = nDefDlgCode | DLGC_WANTALLKEYS; // wants all keys 

   return nCustomDlgCode;
}

Code: Select all

void CCustomEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
   switch(nChar)
   {
   case VK_RETURN:
      TRACE0("\n 'Enter' key has been pressed");
      // do stuff
      break;
   case VK_TAB:
      TRACE0("\n 'Tab' key has been pressed");
      // do something else
      break;
   // ...
   default:
      // call default implementation
      CEdit::OnChar(nChar, nRepCnt, nFlags);
   }
}
Note
  • O alta metoda destul de des folosita este de a prinde mesajele in functia PreTranslateMessage suprascrisa in clasa dialogului parinte.
    Personal, in cazul de fata nu recomand aceasta. In primul rand este o abordare mai putin obiectuala (face parintele tot ce ar trebui sa faca de fapt copiii) si in general, in MFC nu e o idee prea buna de a suprascrie functii virtuale generice, bune la de toate, asa cum este si PreTranslateMessage decat in cazurl in care nu exista si o alta cale. Pot deveni la un momentdat "aglomerate", greu de intretinut si pline de bug-uri.
Vezi si << Back to MFC index



Post Reply