Compartilhar via


TN026: DDX e rotinas DDV

Observação:

A seguinte nota técnica não foi atualizada desde que foi incluída pela primeira vez na documentação online.sistema autônomo resultado, alguns procedimentos e tópicos podem estar desatualizado ou incorreto.Para obter informações mais recentes, é recomendável que você procurar o tópico de interesse no índice de documentação online.

Esta nota descreve a troca de dados de caixa de diálogo (DDX) e a arquitetura de validação (DDV) de dados de caixa de diálogo.Ela também descreve como você gravar um procedimento DDX_ ou DDV_ e como você pode estender ClassWizard usar suas rotinas.

Visão geral dados caixa de diálogo dados Exchange

Todas as funções de dados de caixa de diálogo são feitas com código C++.Não existem recursos especiais ou macros mágica.O coração do mecanismo é uma função virtual é substituída em cada classe de caixa de diálogo que oferece dados da caixa de diálogo trocar e validação.Sempre se encontra neste 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 AFX formato especial que ClassWizard localizar e edição o código nessa função.Código que não é compatível com ClassWizard deve ser colocado fora dos comentários formato especial.

No exemplo acima, <data_exchange_function_call> consta o formulário:

    DDX_Custom(pDX, nIDC, field);

e <data_validation_function_call> é opcional e está no formato:

    DDV_Custom(pDX, field, ...);

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

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

Dados da caixa de diálogo são exatamente isso: dados do membro no CMyDialog classe.Ele não está armazenado em uma struct ou algo semelhante.

Anotações

Embora nós telefonar esse "dados de caixa de diálogo", todos os recursos estão disponível em qualquer classe derivada deCWnd e não se limitando a, apenas as caixas de diálogo.

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

CWnd::UpdateData a operação que faz a inicialização e o erro está manipulando em torno da telefonar para DoDataExchange.

Você pode chamar CWnd::UpdateData a qualquer momento para realizar a troca de dados e validação. Por padrão, UpdateData(Verdadeiro) é chamado no padrão CDialog::OnOK manipulador e UpdateData(FALSE) é chamado no padrão CDialog::OnInitDialog.

A rotina DDV_ deve seguir imediatamente a rotina DDX_ que campo.

Como ele funciona?

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

The DoDataExchange função de membro é muito parecido com o Serialize função de membro - ele é responsável por obter ou configuração dados para/de um formulário externo (neste caso controla em uma caixa de diálogo) de/para dados do membro na classe. The pDX parâmetro é o contexto para fazer o intercâmbio de dados e é semelhante a CArchive parâmetro para CObject::Serialize. The pDX (um CDataExchange objeto) tem uma direção sinalizar como CArchive tem um sinalizador de direção:

  • If ! m_bSaveAndValidate e, em seguida, carregar o estado dos dados em controles.

  • If m_bSaveAndValidate, em seguida, conjunto o estado de dados dos controles.

A validação ocorre somente quando m_bSaveAndValidate está definido. O valor de m_bSaveAndValidate é determinada pelo parâmetro BOOL para CWnd::UpdateData.

Existem três outros interessante CDataExchange membros:

  • m_pDlgWnd: A janela (geralmente uma caixa de diálogo) que contém os controles. Isso é para impedir que os chamadores das funções global DDX_ e DDV_ precisar passar 'this' para cada rotina DDX/DDV.

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

  • Falha: Chamado após colocar uma caixa de mensagem alertando o usuário ao erro de entrada.Esta rotina restaurará o foco para o último controle (a última telefonar para PrepareCtrl/PrepareEditCtrl) e lançar uma exceção. Esta função de membro pode ser chamada por rotinas DDX_ e DDV_.

Extensões de usuário

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

  • Adicione novos tipos de dados.

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

    void PASCAL DDX_Time(CDataExchange* pDX, int nIDC, CTime& tm);
    
  • Adicione 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
    
  • Passe expressões arbitrários para os procedimentos de validação.

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

    Tais expressões arbitrários não podem ser editados por ClassWizard e portanto deve ser movidos de fora dos comentários formato especial (/ / {{AFX_DATA_MAP(CMyClass)).

Ter o DoDialogExchangefunção de membro incluem condicionais ou quaisquer outras declarações C++ válidas com troca sobreposta e chamadas de função de 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ção:

sistema autônomo mostrado acima, esse código não pode ser editado pelo ClassWizard e deve ser usado somente fora dos comentários formato especial.

Suporte ClassWizard

ClassWizard suporta um subconjunto das personalizações DDX/DDV, permitindo que você integrar suas próprias rotinas DDX_ e DDV_ a interface do usuário ClassWizard.Isso é apenas custo vantajoso se você pretende reutilizar determinadas rotinas DDX e DDV em um projeto ou em vários projetos.

Para fazer isso, as entradas especiais são feitas no DDX.CLW (versões anteriores do Visual C++ armazenado essas informações em APSTUDIO.INI) ou no arquivo .CLW do seu projeto.Entradas especiais podem ser inseridas na seção [Geral Info] .CLW arquivo do seu projeto ou na seção [ExtraDDX] do arquivo DDX.CLW em \Arquivos de programas\Microsoft Studio\Visual Visual C ++ diretório \bin.Talvez seja necessário criar o arquivo DDX.CLW se ainda não existir.Se você plano para usar as rotinas DDX_/DDV_ personalizadas somente em um determinado projeto, adicione as entradas na seção [Geral Info] do arquivo de projeto .CLW em vez disso.Se você planeja usar as rotinas em vários projetos, adicione as entradas para a seção [ExtraDDX] DDX.CLW.

O formato geral dessas entradas especiais é:

ExtraDDXCount=n

onde n é o número de ExtraDDX?linhas a seguir

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

onde?é um número de 1 – n que indica qual tipo DDX na lista que está sendo definida.

Cada campo é delimitado por um caractere ';'.Os campos e sua finalidade são descritas abaixo.

  • <keys>
    = lista de caracteres única que indica para quais controles de caixa de diálogo esse tipo de variável é permitido.

    E = edição

    C = caixa de seleção de dois estados

    c = caixa de seleção estado tri

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

    L = nonsorted lista caixa

    l = caixa de listagem classificada

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

    N = lista de soltar nonsorted

    n = lista de soltar classificada

    1 = se inserir DDX deve ser adicionado ao topo da lista (o padrão é adicionar a cauda) isto geralmente é usado para rotinas DDX que transferência a propriedade 'Controle'.

  • <vb-keys>
    Este campo é usado apenas no produto 16 bit para controles VBX (VBX não há suporte para controles no produto de 32 bit)

  • <aviso>
    Seqüência de caracteres para a caixa de combinação de propriedade (sem aspas)

  • <type>
    Identificador único para tipo emitir no arquivo de cabeçalho.Em nosso exemplo acima DDX_Time, isso seria conjunto a CTime.

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

  • <initvalue>
    Valor inicial — 0 ou em branco.Se estiver em branco, nenhuma linha de inicialização será gravada na seção //{{AFX_DATA_INIT do arquivo de implementação.Uma entrada em branco deve ser usada para objetos C++ (tal sistema autônomo CString, CTimee assim por diante) que possuem construtores que garantem a inicialização correta.

  • <DDX_Proc>
    Identificador único para o procedimento DDX_.O nome da função C++ deve começar com "DDX_", mas não inclua "DDX_" no identificador de <DDX_Proc>.No exemplo acima, o identificador <DDX_Proc> seria time.Quando ClassWizard grava a telefonar de função no arquivo de implementação do {{AFX_DATA_MAP seção, ele anexa esse nome ao DDX_, assim, chegando ao DDX_Time.

  • <comentário>
    Comentário para mostrar na caixa de diálogo variável com este DDX.Insira qualquer texto você deseja que aqui e geralmente fornecem algo que descreve a operação executada pelo emparelhar DDX/DDV.

  • <DDV_Proc>
    A parte DDV de entrada é opcional.Nem todas as rotinas DDX têm rotinas DDV correspondentes.Em geral, é mais conveniente incluir a fase de validação sistema autônomo parte integrante da transferência.Geralmente isso é o caso quando sua rotina DDV não exige qualquer parâmetro, porque ClassWizard não oferece suporte a rotinas DDV sem parâmetros.

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

seguido por args DDV 1 ou 2:

  • <promptx>
    seqüência de caracteres para inserir acima do item de edição (com & para acelerador)

  • <fmtx>
    caractere de formato para o tipo de arg, uma das

    d = int

    u = não assinado

    D = int longo (ou seja, longo)

    U = longo não assinado (isto é, DWORD)

    f = float

    F = duplo

    s = seqüência

Consulte também

Outros recursos

Notas técnicas por número

Notas técnicas por categoria