Utiliser la touche entrée pour les contrôles d’édition dans une boîte de dialogue


Résumé


Les applications Windows affichent souvent des boîtes de dialogue d’entrée de données pour demander des informations aux utilisateurs. Ces boîtes de dialogue contiennent plusieurs contrôles d’édition et deux boutons de commande (de type pousser), nommés OK et annuler. Voici un exemple de boîte de dialogue d’entrée de données, qui demande des informations personnelles, telles que le numéro de sécurité sociale, l’adresse, le numéro d’identification (ID), la date/heure et ainsi de suite. Chacun de ces éléments est entré dans un contrôle d’édition. Par défaut, la touche TAB est utilisée dans une boîte de dialogue pour déplacer le focus entre les contrôles d’édition. En tant qu’interface utilisateur commune, il est toutefois possible d’utiliser la touche entrée (retour) pour basculer entre les contrôles d’édition (par exemple, une fois que l’utilisateur a entré une information, le fait d’appuyer sur entrée positionne le focus sur le champ suivant). Il existe plusieurs façons d’activer l’utilisation de la touche entrée pour basculer entre les contrôles d’édition. L’une des méthodes consiste à utiliser WM_COMMAND et les messages de notification qui s’y trouvent dans la boîte de dialogue des boutons et contrôles d’édition. Une autre méthode consiste à sous-déclasser les contrôles d’édition. Le troisième consiste à utiliser app Studio et l’Assistant classe et à créer une nouvelle fonction membre de boîte de dialogue.

Informations supplémentaires


Méthode I : (WM_COMMAND)

Cette méthode est basée sur le comportement suivant des boîtes de dialogue (gestionnaire de boîte de dialogue) et sur la gestion du focus dans Windows. Si une boîte de dialogue ou l’un de ses contrôles possède actuellement le focus d’entrée, il est alors appuyé sur la touche entrée pour que Windows envoie un message WM_COMMAND avec le paramètre idItem (wParam) défini sur l’ID du bouton de commande par défaut. Si la boîte de dialogue ne possède pas de bouton de commande par défaut, le paramètre idItem est défini sur IDOK par défaut. Lorsqu’une application reçoit le message WM_COMMAND avec idItem défini sur l’ID du bouton de commande par défaut, le focus reste associé au contrôle sur lequel le focus a été appuyé. L’appel de GetFocus () à ce point retourne le handle du contrôle qui avait le focus avant que la touche entrée ne soit enfoncée. L’application peut vérifier cette poignée de contrôle et déterminer s’il appartient à n’importe lequel des contrôles d’édition dans la boîte de dialogue. Si tel est le cas, l’utilisateur a entré des données dans l’un des contrôles d’édition et, après avoir effectué cette opération, a appuyé sur entrée. À ce stade, l’application peut envoyer le message de WM_NEXTDLGCTL à la boîte de dialogue pour déplacer le focus sur le contrôle suivant. Toutefois, si le focus s’est associé à l’un des boutons de commande (CANCEL ou OK), la fonction GetFocus () renvoie une poignée de contrôle de bouton, le premier peut faire disparaître la boîte de dialogue. Le pseudo-code de cette logique ressemble à ce qui suit dans la procédure de la boîte de dialogue de l’application :
     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 ;

Méthode II

Cette méthode implique de sous-classer/surclasser le contrôle d’édition dans la boîte de dialogue. Une fois les contrôles d’édition sous-classés ou superclassés, toutes les entrées au clavier sont envoyées à la procédure de sous-classe/surclasse du contrôle d’édition qui dispose actuellement du focus d’entrée, que la boîte de dialogue dispose d’un bouton de commande par défaut ou non. L’application peut intercepter les messages de la touche (ou la fonction car), chercher la touche entrée et procéder au traitement en conséquence. Voici une procédure d’exemple de sous-classe qui recherche la clé 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 */ 

Méthode 3

Cette méthode implique l’utilisation de App Studio et de ClassWizard et la création d’une nouvelle fonction membre de boîte de dialogue. Cette méthode permet à un utilisateur d’appuyer sur la touche entrée et de placer le focus sur le prochain contrôle d’édition. Si le focus est actuellement sur le dernier contrôle d’édition dans la boîte de dialogue, le focus passe au premier contrôle d’édition. Tout d’abord, utilisez App Studio pour modifier l’ID du bouton OK dans la boîte de dialogue. Le comportement par défaut de l’application Studio est d’attribuer au bouton OK l’ID IDOK. L’ID du bouton OK doit être modifié en une autre valeur, par exemple, IDC_OK. Modifiez également les propriétés du bouton OK de sorte qu’il ne s’agit pas d’un PUSHBUTTON par défaut. Ensuite, utilisez ClassWizard pour créer une nouvelle boîte de dialogue membres funciton. Nommez la nouvelle fonction membre telle que OnClickedOK. Cette fonction doit être liée au BN_CLICKED message du contrôle IDC_OK. Une fois cette opération terminée, écrivez le corps de la fonction OnClickedOK. Le code doit être placé normalement dans la fonction OnOK dans la nouvelle fonction OnClickedOK, y compris la fonction OnOK d’une classe. Ajoutez le prototype suivant au fichier d’en-tête pour la boîte de dialogue :
   protected:      virtual void OnOK();
Ajoutez une fonction OnOK à la boîte de dialogue et au code, comme illustré ci-dessous :
   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();   }