Sammendrag
Windows-baserte programmer vise ofte dialogbokser for dataregistrering forespørre informasjon fra brukere. Disse dialogboksene kan inneholde flere redigeringskontroller og to (push) kommandoknapper, OK og Avbryt. Et eksempel på en dialogboks for registrering av data er en som ber om personlig informasjon som personnummer, adresse, identifikasjonsnummer (ID), dato/klokkeslett, og så videre fra brukere. Hvert av disse elementene er lagt inn i redigeringskontrollen.
Som standard brukes TAB-tasten i en dialogboks for å fokusere på Skift mellom redigeringskontroller. Som en felles brukergrensesnitt, men kan en også bruke nøkkelen angir (retur) til å flytte mellom redigeringskontrollene (for eksempel når brukeren skriver inn informasjonen, trykker ENTER, flyttes fokus til neste felt). Det finnes noen måter å aktivere bruken av ENTER-tasten til å flytte mellom redigeringskontroller. Én metode er å bruke WM_COMMAND og redigere meldingene som følger med den i dialogboksen for kontrollene og knappene. En annen metode innebærer delklassifisere redigeringskontrollene. En tredje innebærer å bruke App Studio og veiviseren klassen og opprette en ny dialogboks for medlemsfunksjon.Hvis du vil ha mer informasjon
Metode I: (WM_COMMAND)
Denne metoden er basert på følgende virkemåte for dialogbokser (dialogboksen Manager) og fokus-håndtering i Windows.
Hvis en dialogboks eller en av de tilhørende kontrollene har inndata fokus, får trykke ENTER-tasten Windows til å sende en WM_COMMAND-melding med idItem (wParam)-parameteren angitt til IDen til standard kommandoknapp. Hvis dialogboksen ikke har en standard kommandoknapp, er og idItem-parameteren satt til IDOK som standard. Når et program mottar meldingen WM_COMMAND med idItem satt til IDen til standard kommandoknapp, forblir fokuset som hadde fokus før trykket ENTER-tasten. Kaller GetFocus() nå returnerer håndtaket for kontrollen som hadde fokus før trykket ENTER-tasten. Programmet kan kontrollere dette kontrollhåndtaket og finne ut om den tilhører noen av redigeringskontrollene i dialogboksen. Hvis den gjør det, er brukeren registrerer data i én av redigeringskontrollene, og etter å gjøre dette, trykker ENTER. Programmet kan nå sende WM_NEXTDLGCTL-melding til å flytte fokus til neste kontroll i dialogboksen. Men hvis fokuset var med ett av kommandoen knapper (Avbryt eller OK), og deretter GetFocus() returnerer et kontrollhåndtak knappen, og deretter en kan lukke dialogboksen. Pseudo-kode for denne logikken ligner på følgende i programmets dialogboks for prosedyren: 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 ;
Metoden II
Denne metoden innebærer underklasse/superclassing edit-kontrollen i dialogboksen. Når redigeringskontrollene er en underklasse eller superclassed, alle tastatur input sendes underklasse/superklasse fremgangsmåten i redigeringskontrollen som for øyeblikket har inn fokus, uavhengig av om dialogboksen har en standard kommandoknapp. Programmet kan overtrykke pil ned (eller char) meldinger, se etter ENTER-tasten, og gjør behandling i henhold til dette. Det følgende er et eksempel underklasse prosedyre som leter etter ENTER-tasten:
//*-------------------------------------------------------------------
//| 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 */
Metode 3
Denne metoden innebærer å bruke App Studio og ClassWizard og opprette en ny dialogboks for medlemsfunksjon.
Denne metoden, kan en bruker trykker ENTER og har fokus gå videre til neste redigeringskontrollen. Hvis fokus er på siste redigeringskontroll i dialogboksen, fokus vil gå videre til den første kontrollen. Først bruke App Studio til å endre IDen til knappen OK i dialogboksen. Standard virkemåte for App Studio er å gi OK-knappen-ID-IDOK. -ID på OK-knappen skal endres til en annen verdi, for eksempel IDC_OK. Endre egenskapene for OK-knappen også, slik at det ikke er en standard trykknapp. Deretter bruker du ClassWizard til å opprette en ny dialogboks for medlem funksjon. Gi navn til den nye medlem funksjonen noe sånt som OnClickedOK. Denne funksjonen skal være knyttet til meldingen BN_CLICKED fra IDC_OK-kontrollen. Når dette er gjort, kan du skrive hoveddelen av funksjonen OnClickedOK. Du må plassere koden som du normalt ville ta med i OnOK-funksjonen i den nye OnClickedOK-funksjonen, inkludert en klasse OnOK funksjon. Legg til følgende prototypen hovedpostfil for dialogboksen: protected:
virtual void OnOK();
Legge til en funksjon for OnOK i dialogboksen, og koden er som vist nedenfor:
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(); }