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);
}
}
- 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.