Partager via


TN026 : routines DDX et DDV

Remarque

La note technique suivante n'a pas été mise à jour depuis son inclusion initiale dans la documentation en ligne. Par conséquent, certaines procédures et rubriques peuvent être obsolètes ou incorrectes. Pour obtenir les informations les plus récentes, il est recommandé de rechercher l'objet qui vous intéresse dans l'index de la documentation en ligne.

Cette note décrit l’architecture d’échange de données de dialogue (DDX) et de validation des données de dialogue (VDD). Il décrit également comment écrire une procédure DDX_ ou VDD_ et comment étendre ClassWizard pour utiliser vos routines.

Vue d’ensemble de l’échange de données de boîte de dialogue

Toutes les fonctions de données de boîte de dialogue sont effectuées avec du code C++. Il n’y a pas de ressources spéciales ni de macros magiques. Le cœur du mécanisme est une fonction virtuelle qui est substituée dans chaque classe de dialogue qui effectue l’échange et la validation de données de dialogue. Elle est toujours trouvée sous cette forme :

void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);   // call base class

    //{{AFX_DATA_MAP(CMyDialog)
        <data_exchange_function_call>
        <data_validation_function_call>
    //}}AFX_DATA_MAP
}

Le format spécial des commentaires AFX permet à ClassWizard de localiser et de modifier le code dans cette fonction. Le code qui n’est pas compatible avec ClassWizard doit être placé en dehors des commentaires de format spéciaux.

Dans l’exemple ci-dessus, <data_exchange_function_call> se présente sous la forme suivante :

DDX_Custom(pDX, nIDC, field);

et <data_validation_function_call> est facultatif et se présente sous la forme suivante :

DDV_Custom(pDX, field, ...);

Plusieurs paires DDX_/VDD_ peuvent être incluses dans chaque DoDataExchange fonction.

Consultez « afxdd_.h » pour obtenir la liste de toutes les routines d’échange de données de dialogue et les routines de validation des données de dialogue fournies avec MFC.

Les données de boîte de dialogue sont simplement les suivantes : données membres dans la CMyDialog classe. Il n’est pas stocké dans un struct ou quelque chose de similaire.

Notes

Bien que nous appelons cette « données de dialogue », toutes les fonctionnalités sont disponibles dans n’importe quelle classe dérivée CWnd et ne sont pas limitées aux dialogues uniquement.

Les valeurs initiales des données sont définies dans le constructeur C++ standard, généralement dans un bloc avec //{{AFX_DATA_INIT et //}}AFX_DATA_INIT des commentaires.

CWnd::UpdateData est l’opération qui effectue l’initialisation et la gestion des erreurs autour de l’appel à DoDataExchange.

Vous pouvez appeler CWnd::UpdateData à tout moment pour effectuer l’échange et la validation des données. Par défaut (TRUE) est appelé dans le gestionnaire par CDialog::OnOK défaut UpdateDataet UpdateData(FALSE) est appelé dans la valeur par défautCDialog::OnInitDialog.

La routine VDD_ doit immédiatement suivre la routine de DDX_ pour ce champ.

Fonctionnement

Vous n’avez pas besoin de comprendre ce qui suit pour utiliser les données de boîte de dialogue. Toutefois, comprendre comment cela fonctionne en arrière-plan vous aidera à écrire votre propre procédure d’échange ou de validation.

La DoDataExchange fonction membre est similaire à la Serialize fonction membre : elle est chargée d’obtenir ou de définir des données vers/à partir d’un formulaire externe (dans ce cas, les contrôles d’une boîte de dialogue) de/vers les données membres de la classe. Le paramètre pDX est le contexte d’échange de données et est similaire au CArchive paramètre .CObject::Serialize Le pDX (un CDataExchange objet) a un indicateur de direction semblable CArchive à celui d’un indicateur de direction :

  • Si !m_bSaveAndValidate, chargez l’état des données dans les contrôles.

  • Si m_bSaveAndValidate, définissez l’état des données à partir des contrôles.

La validation se produit uniquement quand m_bSaveAndValidate elle est définie. La valeur de m_bSaveAndValidate est déterminée par le paramètre BOOL sur CWnd::UpdateData.

Il existe trois autres membres intéressants CDataExchange :

  • m_pDlgWnd: fenêtre (généralement une boîte de dialogue) qui contient les contrôles. Cela permet d’empêcher les appelants des fonctions globales DDX_ et VDD_ de devoir passer « ceci » à chaque routine DDX/VDD.

  • PrepareCtrl, et PrepareEditCtrl: prépare un contrôle de dialogue pour l’échange de données. Stocke le handle de ce contrôle pour définir le focus en cas d’échec d’une validation. PrepareCtrl est utilisé pour les contrôles non modifiés et PrepareEditCtrl est utilisé pour les contrôles d’édition.

  • Fail: appelé après avoir affiché une boîte de message indiquant à l’utilisateur l’erreur d’entrée. Cette routine restaure le focus sur le dernier contrôle (le dernier appel vers PrepareCtrl ou PrepareEditCtrl) et lève une exception. Cette fonction membre peut être appelée à partir des routines DDX_ et VDD_.

Extensions utilisateur

Il existe plusieurs façons d’étendre le mécanisme DDX/VDD par défaut. Vous pouvez :

  • Ajoutez de nouveaux types de données.

    CTime
    
  • Ajouter de nouvelles procédures d’échange (DDX_).

    void PASCAL DDX_Time(CDataExchange* pDX, int nIDC, CTime& tm);
    
  • Ajouter de nouvelles procédures de validation (VDD_).

    void PASCAL DDV_TimeFuture(CDataExchange* pDX, CTime tm, BOOL bFuture);
    // make sure time is in the future or past
    
  • Passez des expressions arbitraires aux procédures de validation.

    DDV_MinMax(pDX, age, 0, m_maxAge);
    

    Remarque

    Ces expressions arbitraires ne peuvent pas être modifiées par ClassWizard et doivent donc être déplacées en dehors des commentaires de format spécial (//{AFX_DATA_MAP(CMyClass)).

DoDataExchange La fonction membre inclut des conditions ou d’autres instructions C++ valides avec des appels de fonction d’échange et de validation mélangés.

//{{AFX_DATA_MAP(CMyClass)
DDX_Check(pDX, IDC_SEX, m_bFemale);
DDX_Text(pDX, IDC_EDIT1, m_age);
//}}AFX_DATA_MAP
if (m_bFemale)
    DDV_MinMax(pDX, age, 0, m_maxFemaleAge);
else
    DDV_MinMax(pDX, age, 0, m_maxMaleAge);

Remarque

Comme indiqué ci-dessus, ce code ne peut pas être modifié par ClassWizard et ne doit être utilisé qu’en dehors des commentaires de format spécial.

Prise en charge de ClassWizard

ClassWizard prend en charge un sous-ensemble de personnalisations DDX/VDD en vous permettant d’intégrer vos propres routines DDX_ et VDD_ dans l’interface utilisateur ClassWizard. Cela n’est avantageux que si vous envisagez de réutiliser des routines DDX et VDD particulières dans un projet ou dans de nombreux projets.

Pour ce faire, des entrées spéciales sont effectuées dans DDX.CLW (versions antérieures de Visual C++ stockées ces informations dans APSTUDIO. INI) ou dans le projet . Fichier CLW. Les entrées spéciales peuvent être entrées dans la section [Informations générales] de votre projet . Fichier CLW ou dans la section [ExtraDDDX] du fichier DDX.CLW dans le répertoire \Program Files\Microsoft Visual Studio\Visual C++\bin. Vous devrez peut-être créer le fichier DDX.CLW s’il n’existe pas déjà. Si vous envisagez d’utiliser les routines DDX_/VDD_ personnalisées uniquement dans un certain projet, ajoutez les entrées à la section [Informations générales] de votre projet. Fichier CLW à la place. Si vous envisagez d’utiliser les routines sur de nombreux projets, ajoutez les entrées à la section [ExtraDDDX] de DDX.CLW.

Le format général de ces entrées spéciales est le suivant :

ExtraDDDXCount=n

n est le nombre de lignes ExtraDDX à suivre, du formulaire

ExtraDDDX ?=keys ; vb-keys ; invite ; type ; initValue ; DDX_Proc [ ; VDD_Proc ; prompt1 ; arg1 [ ; invite2 ; fmt2]]

Où? est un nombre 1 - n indiquant le type DDX dans la liste en cours de définition.

Chaque champ est délimité par un caractère « ; ». Les champs et leur objectif sont décrits ci-dessous.

  • keys

    Liste de caractères uniques indiquant pour quelle boîte de dialogue contrôle ce type de variable est autorisée.

    Caractère Contrôle autorisé
    E edit
    C boîte de case activée à deux états
    c zone de case activée tri-état
    R première case d’option dans un groupe
    L Zone de liste non triée
    l Zone de liste triée
    M zone de liste modifiable (avec élément d’édition)
    N Liste déroulante non triée
    n Liste déroulante triée
    1 si l’insertion DDX doit être ajoutée à la tête de liste (la valeur par défaut est ajoutée à la fin) Elle est généralement utilisée pour les routines DDX qui transfèrent la propriété « Control ».
  • vb-keys

    Ce champ est utilisé uniquement dans le produit 16 bits pour les contrôles VBX (les contrôles VBX ne sont pas pris en charge dans le produit 32 bits)

  • prompt

    Chaîne à placer dans la zone de liste déroulante Propriété (sans guillemets)

  • type

    Identificateur unique pour le type à émettre dans le fichier d’en-tête. Dans notre exemple ci-dessus avec DDX_Time, cette valeur est définie sur CTime.

  • vb-keys

    Non utilisé dans cette version et doit toujours être vide

  • initValue

    Valeur initiale : 0 ou vide. S’il est vide, aucune ligne d’initialisation n’est écrite dans la section //{AFX_DATA_INIT du fichier d’implémentation. Une entrée vide doit être utilisée pour les objets C++ (tels que CString, CTimeetc.) qui ont des constructeurs qui garantissent une initialisation correcte.

  • DDX_Proc

    Identificateur unique de la procédure DDX_. Le nom de la fonction C++ doit commencer par « DDX_ », mais n’incluez pas « DDX_ » dans l’identificateur <DDX_Proc> . Dans l’exemple ci-dessus, l’identificateur <DDX_Proc> serait Time. Lorsque ClassWizard écrit l’appel de fonction dans le fichier d’implémentation dans la section {{AFX_DATA_MAP, il ajoute ce nom à DDX_, ce qui arrive à DDX_Time.

  • commentaire

    Commentaire à afficher dans la boîte de dialogue pour la variable avec ce DDX. Placez le texte souhaité ici et fournissez généralement quelque chose qui décrit l’opération effectuée par la paire DDX/VDD.

  • VDD_Proc

    La partie VDD de l’entrée est facultative. Toutes les routines DDX n’ont pas toutes des routines de VDD correspondantes. Souvent, il est plus pratique d’inclure la phase de validation dans le cadre du transfert. Cela est souvent le cas lorsque votre routine de VDD ne nécessite aucun paramètre, car ClassWizard ne prend pas en charge VDD routines sans aucun paramètre.

  • arg

    Identificateur unique de la procédure VDD_. Le nom de la fonction C++ doit commencer par « VDD_ », mais n’incluez pas « DDX_ » dans l’identificateur <DDX_Proc>.

    arg est suivi de 1 ou 2 VDD arguments :

    • promptN

      Chaîne à placer au-dessus de l’élément de modification (avec & pour l’accélérateur).

    • fmtN

      Caractère de format pour le type d’argument, l’un des suivants :

      Caractère Type
      j int
      u nombre entier non signé
      D long int (c’est-à-dire long)
      U long non signé (autrement dit, DWORD)
      f virgule flottante
      F double
      s string

Voir aussi

Notes techniques par numéro
Notes techniques par catégorie