Podsumowanie
W aplikacjach opartych na systemie Windows często są wyświetlane okna dialogowe wprowadzania danych w celu żądania informacji od użytkowników. Te okna dialogowe mogą zawierać kilka kontrolek edycji i dwa przyciski polecenia (push), oznaczone etykietą OK i Anuluj. Przykładem okna dialogowego Wprowadzanie danych jest to, że żąda informacji osobistych, takich jak numer ubezpieczenia społecznego, adres, numer identyfikacyjny (ID), Data/godzina i tak dalej, od użytkowników. Każdy z tych elementów jest wprowadzany do kontrolki edycji. Domyślnie klawisz TAB jest stosowany w oknie dialogowym, aby przenieść fokus między kontrolkami edycji. Jako typowy interfejs użytkownika może jednak również przełączać się między kontrolkami edycji za pomocą klawisza ENTER (RETURN) (na przykład po wprowadzeniu przez użytkownika fragmentów informacji naciśnięcie klawisza ENTER powoduje przeniesienie fokusu do następnego pola). Istnieje kilka sposobów umożliwiania przechodzenia między kontrolkami edycji za pomocą klawisza ENTER. Jedna metoda polega na użyciu WM_COMMAND i wiadomości z powiadomieniami, które są z nimi związane w oknie dialogowym Edytowanie kontrolek i przycisków. Inna metoda obejmuje podklasy kontrolek edycji. Trzecia pociąga za sobą używanie programu App Studio i kreatora klas oraz tworzenie nowej funkcji składowej okna dialogowego.
Więcej informacji
Metoda I: (WM_COMMAND)
Ta metoda jest oparta na poniższym zachowaniu okien dialogowych (Menedżer okien dialogowych) i zajmowaniu fokusu w systemie Windows. Jeśli okno dialogowe lub jedna z jego kontrolek ma obecnie fokus wprowadzania, naciśnięcie klawisza ENTER powoduje, że system Windows wysyła wiadomość WM_COMMAND przy użyciu parametru idItem (wParam) ustawionego na identyfikator domyślnego przycisku polecenia. Jeśli okno dialogowe nie zawiera domyślnego przycisku polecenia, jako parametr idItem jest domyślnie ustawiona wartość IDOK. Gdy aplikacja otrzyma wiadomość WM_COMMANDą z idItemą na identyfikator przycisku polecenia domyślnego, fokus pozostanie z kontrolką, w której fokus się przed naciśnięciem klawisza ENTER. Wywołanie funkcji GetFocus () w tym punkcie powoduje zwrócenie uchwytu kontrolki, w którym fokus był fokusem przed naciśnięciem klawisza ENTER. Aplikacja może sprawdzić ten uchwyt sterujący i sprawdzić, czy należy on do jakichkolwiek kontrolek edycyjnych w oknie dialogowym. Jeśli tak, użytkownik wprowadził dane do jednej z kontrolek edycji i po wykonaniu tej czynności naciśnięcie klawisza ENTER. W tym momencie aplikacja może wysłać wiadomość WM_NEXTDLGCTLą do okna dialogowego, aby przenieść fokus do następnej kontrolki. Jeśli jednak fokus był jednym z przycisków poleceń (anulowanie lub OK), funkcja GetFocus () zwróci uchwyt sterujący przyciskiem, a w tym momencie, gdy to pole może odrzucać okno dialogowe. Pseudo kod tej logiki jest podobny do następującego w procedurze okna dialogowego aplikacji:
case WM_COMMAND: if(wParam=IDOFDEFBUTTON || IDOK) { // User has hit the ENTER key. hwndTest = GetFocus() ; retVal = TesthWnd(hWndTest) ; //Where retVal is a boolean variable that indicates whether //the hwndTest is the handle of one of the edit controls. if(hwndTest) { //Focus is with an edit control, so do not close the dialog. //Move focus to the next control in the dialog. PostMessage(hDlg, WM_NEXTDLGCTL, 0, 0L) ; return TRUE ; } else { //Focus is with the default button, so close the dialog. EndDialog(hDlg, TRUE) ; return FALSE ; } } break ;
Metoda II
Ta metoda obejmuje podklasy lub nadklasy kontrolki edycji w oknie dialogowym. Po podklasie lub superklasie kontrolek edycyjnych wszystkie dane wprowadzane za pomocą klawiatury są wysyłane z podklasą/procedurą superklasy kontrolki edycji, która aktualnie ma fokus wprowadzania, niezależnie od tego, czy okno dialogowe ma domyślny przycisk polecenia. Aplikacja może zalewkować tekst w dół (lub znak), poszukać klawisza ENTER i odpowiednio przeprowadzić przetwarzanie. Poniżej przedstawiono procedurę z przykładową podklasą, która wyszukuje klucz ENTER:
//*------------------------------------------------------------------- //| Title: //| SubClassProc //| //| Parameters: //| hWnd - Handle to the message's destination window //| wMessage - Message number of the current message //| wParam - Additional info associated with the message //| lParam - Additional info associated with the message //| //| Purpose: //| This is the window procedure used to subclass the edit control. //*--------------------------------------------------------------------- long FAR PASCAL SubProc(HWND hWnd, WORD wMessage,WORD wParam,LONG lParam) { switch (wMessage) { case WM_GETDLGCODE: return (DLGC_WANTALLKEYS | CallWindowProc(lpOldProc, hWnd, wMessage, wParam, lParam)); case WM_CHAR: //Process this message to avoid message beeps. if ((wParam == VK_RETURN) || (wParam == VK_TAB)) return 0; else return (CallWindowProc(lpOldProc, hWnd, wMessage, wParam, lParam)); case WM_KEYDOWN: if ((wParam == VK_RETURN) || (wParam == VK_TAB)) { PostMessage (ghDlg, WM_NEXTDLGCTL, 0, 0L); return FALSE; } return (CallWindowProc(lpOldProc, hWnd, wMessage, wParam, lParam)); break ; default: break; } /* end switch */
Metoda 3
Ta metoda obejmuje używanie funkcji App Studio i ClassWizard oraz tworzenie nowego elementu członkowskiego okna dialogowego. Ta metoda umożliwi użytkownikowi naciśnięcie klawisza ENTER i przejście fokusu do następnej kontrolki edycji. Jeśli fokus znajduje się obecnie w ostatnim formancie edycyjnym w oknie dialogowym, fokus zostanie przeniesiony do pierwszej kontrolki edycji. Najpierw użyj narzędzia App Studio, aby zmienić identyfikator przycisku OK w oknie dialogowym. Domyślnym zachowaniem aplikacji App Studio jest ustawienie przycisku OK na identyfikator IDOK. Identyfikator przycisku OK należy zmienić na inną wartość, taką jak IDC_OK. Ponadto Zmień właściwości przycisku OK, aby nie był to przycisk domyślny. Następnie użyj ClassWizard, aby utworzyć nowe okno dialogowe funciton. Nadaj nazwę nowej funkcji składowej, takiej jak OnClickedOK. Ta funkcja powinna być powiązana z wiadomością BN_CLICKEDą od kontrolki IDC_OK. Po wykonaniu tej czynności Napisz treść funkcji OnClickedOK. Kod, który normalnie należy umieścić w funkcji OnOK, należy umieścić w nowej funkcji OnClickedOK, w tym w OnOK funkcji Class. Dodaj następujący prototyp do pliku nagłówka w oknie dialogowym:
protected: virtual void OnOK();
Dodaj do okna dialogowego OnOK, jak przedstawiono poniżej:
void CMyDialog::OnOK() { CWnd* pwndCtrl = GetFocus(); CWnd* pwndCtrlNext = pwndCtrl; int ctrl_ID = pwndCtrl->GetDlgCtrlID(); switch (ctrl_ID) { case IDC_EDIT1: pwndCtrlNext = GetDlgItem(IDC_EDIT2); break; case IDC_EDIT2: pwndCtrlNext = GetDlgItem(IDC_EDIT3); break; case IDC_EDIT3: pwndCtrlNext = GetDlgItem(IDC_EDIT4); break; case IDC_EDIT4: pwndCtrlNext = GetDlgItem(IDC_EDIT1); break; case IDOK: CDialog::OnOK(); break; default: break; } pwndCtrlNext->SetFocus(); }