Compartilhar via


TN026: DDX e rotinas DDV

ObservaçãoObservação

Observe a seguir técnica não foi atualizada desde que foi incluído primeiro na documentação online.Como resultado, alguns procedimentos e tópicos estejam incorretos ou expirado.Para obter as informações mais recente, é recomendável que você procurar pelo tópico de interesse no índice de documentação online.

Essa observação descreve a caixa de diálogo arquitetura de (DDV) troca de dados (DDX) e da caixa de diálogo de validação de dados.Também descreve como você escrever um procedimento de DDX_ ou de DDV_ e como você pode estender ClassWizard para usar suas rotinas.

Visão geral da caixa de diálogo troca de dados

Todas as funções de dados da caixa de diálogo são feitas com código C++.Não há nenhum recurso especial ou macro mágico.O coração do mecanismo é uma função virtual que é substituída em cada classe da caixa de diálogo que faz a caixa de diálogo troca de dados e validação.Sempre é encontrado no formulário:

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
}

Os comentários especiais de AFX de formato permitem que ClassWizard localize e edite o código dentro dessa função.O código que não é compatível com ClassWizard deve ser colocado fora de comentários especiais de formato.

No exemplo anterior, <data_exchange_function_call> está no formulário:

    DDX_Custom(pDX, nIDC, field);

e <data_validation_function_call> é opcional e está no formulário:

    DDV_Custom(pDX, field, ...);

Mais de um par de DDX_/DDV_ pode ser incluído em cada função de DoDataExchange .

Consulte “afxdd_.h” para uma lista de todas as rotinas de troca de dados da caixa de diálogo e rotinas de validação de dados da caixa de diálogo fornecidas com o MFC.

Os dados da caixa de diálogo são apenas o: dados do membro na classe de CMyDialog .Não é armazenada em um estrutura ou em qualquer coisa semelhante.

Anotações

Embora tenhamos chamemos esses de dados “caixa de diálogo,” todos os recursos estão disponíveis em qualquer classe derivada de CWnd e não estão limitados apenas caixas de diálogo.

Os valores iniciais de dados são definidos no construtor do C++ padrão, geralmente em um bloco com //{{AFX_DATA_INIT e comentários de //}}AFX_DATA_INIT .

CWnd::UpdateData é a operação que faz a inicialização e manipulação de erro ao redor de chamada a DoDataExchange.

Você pode chamar CWnd::UpdateData a qualquer momento para executar troca de dados e validação.UpdateDataTRUE () é chamado por padrão no manipulador padrão e em UpdateDatade CDialog::OnOK (FALSOS) é chamado em CDialog::OnInitDialogpadrão.

A rotina de DDV_ deve seguir imediatamente a rotina de DDX_ para o campo.

Como funciona?

Você não precisa entender o seguinte para usar dados da caixa de diálogo.No entanto, essa compreender como funciona nos bastidores ajudará a escrever seu próprio procedimento de troca ou de validação.

A função de membro de DoDataExchange é semelhante à função de membro de Serialize - é responsável para obter ou definir/de dados para um formulário externo (neste caso controles em uma caixa de diálogo) de/para dados do membro na classe.O parâmetro de pDX é o contexto para fazer troca de dados e é semelhante para o parâmetro de CArchive a CObject::Serialize.pDX (um objeto de CDataExchange ) tem um sinalizador de direção bem como CArchive tem um sinalizador de direção:

  • Se !m_bSaveAndValidate, carrega o estado de dados de controles.

  • Se m_bSaveAndValidate, defina o estado dos dados dos controles.

A validação ocorre somente quando m_bSaveAndValidate é definido.O valor de m_bSaveAndValidate é determinado pelo parâmetro de BOOL a CWnd::UpdateData.

Há três interessantes outros membros de CDataExchange :

  • m_pDlgWnd: A janela (geralmente uma caixa de diálogo) que contém os controles.Este é impedir que os chamadores das funções globais de DDX_ e de DDV_ tenham que passar “ou” para cada rotina de DDX/DDV.

  • PrepareCtrl, e PrepareEditCtrl: Preparar um controle de caixa de diálogo para troca de dados.Armazena a alça de controle para definir o foco se a validação falhar.PrepareCtrl é usado para controles de nonedit e PrepareEditCtrl é usado para controles de edição.

  • Falha: Chamado após trazer anterior uma caixa de mensagem que alerta o usuário ao erro de entrada.Esta rotina restaurará o foco para o último controle (a última chamada a PrepareCtrl/PrepareEditCtrl) e irá acionar uma exceção.Essa função de membro pode ser chamada de rotinas de DDX_ e de DDV_.

Extensões do usuário

Há várias maneiras para estender o mecanismo de opção DDX/DDV.Você pode:

  • Adicionar novos tipos de dados.

    CTime
    
  • Adicionar novos procedimentos de troca (DDX_???).

    void PASCAL DDX_Time(CDataExchange* pDX, int nIDC, CTime& tm);
    
  • Adicionar novos procedimentos de validação (DDV_???).

    void PASCAL DDV_TimeFuture(CDataExchange* pDX, CTime tm, BOOL bFuture);
    // make sure time is in the future or past
    
  • Passar expressões arbitrárias para procedimentos de validação.

    DDV_MinMax(pDX, age, 0, m_maxAge);
    
    ObservaçãoObservação

    Essas expressões arbitrárias não podem ser editadas por ClassWizard e não devem ser movidas como consequência fora de comentários especiais de formato/({{AFX_DATA_MAP CMyClass) ().

Com a função de membro de DoDialogExchange incluir as condições ou quaisquer outras declarações válidos C++ com chamadas de função misturadas de troca e validação.

//{{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);
ObservaçãoObservação

Como mostrado acima, esse código não pode ser editado por ClassWizard e deve ser usado somente para fora de comentários especiais de formato.

Suporte de ClassWizard

ClassWizard suporta um subconjunto de personalizações de DDX/DDV permitindo que você integre suas próprias rotinas de DDX_ e de DDV_ a interface do usuário de ClassWizard.Isso é útil para somente se você planejar reutilizar o detalhe DDX e rotinas de DDV em um projeto ou em vários projetos.

Para fazer isso, as entradas especiais são feitas em DDX.CLW (as versões anteriores do Visual C++ têm essas informações em APSTUDIO.INI) ou no arquivo de .CLW do seu projeto.Entradas especiais podem ser inscritas [na seção de informações gerais] do arquivo de .CLW do seu projeto ou na seção de ExtraDDX [] do arquivo de DDX.CLW \ program files \ Microsoft Visual Studio \ Visual C++ diretório \ bin.Você pode precisar criar o arquivo de DDX.CLW se ainda não existir.Se você planejar usar rotinas personalizadas DDX_/DDV_ somente em um determinado projeto, adicione as entradas [à seção de informações gerais] do arquivo de projeto .CLW em vez disso.Se você planejar usar rotinas em vários projetos, adicione as entradas à seção de ExtraDDX [] de DDX.CLW.

O formato geral sobre essas entradas especiais é:

ExtraDDXCount=n

em onde é o número de ExtraDDX?então linhas

ExtraDDX?=<keys>;<vb-keys>; <prompt>; <type>; <initValue>; <DDX_Proc>
[;<DDV_Proc>; <prompt1>; <arg1>; [<prompt2>; <fmt2>]]

onde?é um número 1 – valor indicando que DDX em na lista que está sendo definida.

Cada campo é limitado por “; ” caractere.Campos e sua finalidade são descritos em.

  • <keys>
    = a lista de caracteres únicos que indicam que a caixa de diálogo controla esse tipo de variável é permitida.

    = E edição

    C = caixa de seleção de dois estados

    c = caixa de seleção de três estados

    R = primeiro botão de opção em um grupo

    L = caixa de listagem nonsorted

    l = classificado a caixa de listagem

    M (= caixa de combinação com item de edição)

    Na lista nonsorted soltar =

    = classificado na lista de soltar

    1 = se a inserção de DDX é adicionada ao início da lista (opção é adiciona à parte final) que isso é geralmente usado para rotinas de DDX que transferem a propriedade “controle”.

  • <vb-keys>
    Este campo é usado somente no produto de 16 bits para controles de VBX (controles de VBX não são suportados no produto de 32 bits)

  • <prompt>
    Cadeia de caracteres para colocar na caixa de combinação de propriedade (nenhuma citação)

  • <type>
    Escolha o identificador para o tipo emitir no arquivo de cabeçalho.Em nosso exemplo anterior com DDX_Time, isso deve ser definido como CTime.

  • <vb-keys>
    Não usado nesta versão e deve estar sempre vazio

  • <initValue>
    Valor inicial — 0 ou em branco.Se estiver vazia, então nenhuma linha de inicialização será gravada em //{{seção de AFX_DATA_INIT do arquivo de implementação.Uma entrada em branco deve ser usada para os objetos C++ (como CString, CTime, e assim por diante) que têm construtores que garantem a inicialização correta.

  • <DDX_Proc>
    Identificador único para o procedimento de DDX_.O nome da função C++ deve começar com “DDX_”, mas não inclui “DDX_” no identificador de <DDX_Proc> .No exemplo anterior, o identificador de <DDX_Proc> seria tempo.Quando ClassWizard grava a chamada de função para o arquivo da implementação no {{seção de AFX_DATA_MAP, acrescenta esse nome a DDX_, bem chegando em DDX_Time.

  • <comment>
    Comente mostrar na caixa de diálogo para a variável com esse DDX.Colocar qualquer texto que você deseja aqui, e fornecer geralmente algo que descreve a operação executada por pares de DDX/DDV.

  • <DDV_Proc>
    A parte de DDV de entrada é opcional.Nem todas rotinas de DDX têm correspondentes rotinas de DDV.Geralmente, é mais conveniente colocar a fase de validação como uma parte integral de transferência.Isso geralmente é o caso em sua rotina de DDV não requer nenhum parâmetro, porque ClassWizard não suporta rotinas de DDV sem nenhum parâmetro.

  • <arg>
    Identificador único para o procedimento de DDV_.O nome da função C++ deve começar com “DDV_”, mas não inclui “DDX_” no identificador de <DDX_Proc> .

seguido por 1 ou 2 args de DDV:

  • <promptX>
    cadeia de caracteres para colocar acima do item de edição com (&) para o acelerador

  • <fmtX>
    caractere de formato para o tipo de arg, de um

    int de =

    EUA = sem-sinal

    = De tempo int (isto é, long)

    EUA = unsigned long (isto é, dword)

    f = float

    F = double

    s = cadeia de caracteres

Consulte também

Outros recursos

Notas técnicas por número

Notas técnicas por categoria