TN043: RFX rotinas
Observação |
---|
A seguinte nota técnica não foi atualizada desde que foi incluída pela primeira vez na documentação online.Como resultado, alguns procedimentos e tópicos podem estar desatualizado ou incorreto.As informações mais recentes, é recomendável que você procure o tópico de interesse no índice de documentação on-line. |
Esta anotação descreve a arquitetura do exchange (RFX) de campo de registro.Ele também descreve como escrever um RFX_ procedimento.
Visão geral do Exchange de campo do registro
Todas as funções de campo de conjunto de registros 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 que deve ser substituída em cada classe derivada de conjunto de registros.Ele sempre é encontrado neste formulário:
void CMySet::DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CMySet)
<recordset exchange field type call>
<recordset exchange function call>
//}}AFX_FIELD_MAP
}
Comentários AFX formato especial permitem ClassWizard localizar e editar o código nessa função.Código que não é compatível com ClassWizard deve ser colocado fora dos comentários de formato especial.
No exemplo acima, <recordset_exchange_field_type_call> é no formulário:
pFX->SetFieldType(CFieldExchange::outputColumn);
e <recordset_exchange_function_call> é no formulário:
RFX_Custom(pFX, "Col2", m_Col2);
A maioria dos RFX_ funções têm três argumentos como mostrado acima, mas alguns (por exemplo,RFX_Texte RFX_Binary) tem argumentos opcionais adicionais.
Mais de um RFX_ podem ser incluídos em cada DoDataExchange função.
Consulte afxdb.h para obter uma lista de todas as recordset campo exchange rotinas fornecidas com MFC.
Chamadas de campo de conjunto de registros são uma maneira de registrar locais da memória (geralmente membros de dados) para armazenar dados de campo para um CMySet classe.
Anotações
Funções de campo de conjunto de registros são projetadas para trabalhar somente com o CRecordset classes.Eles não são geralmente usados por outras classes do MFC.
Valores iniciais de dados são definidos no construtor de C++ padrão, normalmente em um bloco com //{{AFX_FIELD_INIT(CMylSet) e //}}AFX_FIELD_INIT comentários.
Cada RFX_ função deve oferecer suporte a várias operações, variando de retornar o status incorreto do campo para o campo em preparação para o campo de edição de arquivamento.
Cada função que chama DoFieldExchange (por exemplo SetFieldNull, IsFieldDirty), oferece sua própria inicialização em torno da chamada para DoFieldExchange.
Como funciona?
Você não precisa entender o seguinte para usar a troca de campo de registro.No entanto, entender como isso funciona nos bastidores ajudará você a escrever seu próprio procedimento de exchange.
O DoFieldExchange função de membro é muito parecido com o Serialize função de membro — é responsável por obter ou definir dados para/de/para dados de membro na classe de um formulário externo (em colunas esta ocorrência do resultado de uma consulta ODBC).O pFX parâmetro é o contexto para fazer a troca de dados e é semelhante a CArchive parâmetro para CObject::Serialize.O pFX (um CFieldExchange objeto) tem um indicador de operação, que é semelhante, mas uma generalização de CArchive sinalizador de direção.Uma função RFX pode ter que oferecer suporte as seguintes operações:
BindParam — indicar onde ODBC deve recuperar dados de parâmetro
BindFieldToColumn — indicar onde ODBC deve recuperar/depósito outputColumn dados
Correção — definir CString/CByteArray comprimentos, definir status NULL bit
MarkForAddNew — Mark dirty se valor foi alterado desde que chamar AddNew
MarkForUpdate — Mark dirty se valor foi alterado desde Editar chamar
Nome — acrescentar nomes de campo para os campos marcados com problemas
NomeValor — acrescentar "< nome de coluna > =?" para os campos marcados com problemas
Valor — acrescentar "?" seguido de separador, como ',' ou ' '
SetFieldDirty— Definir status bit sujo (ou sejacampo alterado)
SetFieldNull— Defina o bit de status indicando um valor nulo para campo
IsFieldDirty— Retornar valor de bits de status dirty
IsFieldNull— Retornar valor de bit nulo status
IsFieldNullable— Retornar TRUE se o campo pode conter valores nulos
StoreField — arquivar valor do campo
LoadField — recarregar arquivados valor do campo
GetFieldInfoValue — retornar gerais informações em um campo
GetFieldInfoOrdinal — retornar gerais informações em um campo
Extensões de usuário
Há várias maneiras de estender o mecanismo RFX padrão.Você pode
Adicione novos tipos de dados.Por exemplo:
CBookmark
Adicione novos procedimentos de exchange (RFX_???).
void AFXAPI RFX_Bigint(CFieldExchange* pFX, const char *szName, BIGINT& value);
Tem o DoFieldExchange função de membro condicionalmente incluir chamadas RFX adicionais ou quaisquer outras instruções C++ válidas.
while (posExtraFields != NULL) { RFX_Text(pFX, m_listName.GetNext(posExtraFields), m_listValue.GetNext(posExtraValues)); }
Observação |
---|
Esse código não pode ser editado por ClassWizard e deve ser usado somente fora dos comentários de formato especial. |
Gravando RFX
Para escrever sua própria função RFX personalizada, é recomendável copiar uma função RFX existente e modificá-lo para seus propósitos.Selecionar o RFX direito para copiar pode tornar seu trabalho mais fácil.Algumas funções RFX têm algumas propriedades exclusivas que você deve levar em conta ao decidir qual copiar.
RFX_Long e RFX_Int:
Essas são as funções RFX mais simples.O valor de dados não precisa qualquer interpretação especial e o tamanho dos dados é fixo.RFX_Single e RFX_Double:
Como RFX_Long e RFX_Int acima, essas funções são simples e pode fazer usar a implementação padrão amplamente.Eles são armazenados em dbflt.cpp em vez de dbrfx.cpp, no entanto, para habilitar carregando o runtime flutuante ponto biblioteca somente quando elas são explicitamente referência.RFX_Text e RFX_Binary:
Essas duas funções pré-alocar um buffer estático para armazenar informações de seqüência de caracteres/binário e devem registrar esses buffers com ODBC SQLBindCol em vez de registrar e valor.Assim, essas duas funções possuem muita código de caso especial.RFX_Date:
ODBC retorna informações de data e hora em sua própria estrutura de dados TIMESTAMP_STRUCT.Esta função aloca dinamicamente um TIMESTAMP_STRUCT como "proxy" para enviar e receber dados de hora de data.Várias operações devem transferir as informações de data e hora entre C++ CTime objeto e o proxy TIMESTAMP_STRUCT.Esta função isso complica consideravelmente, mas é um bom exemplo de como usar um proxy para transferência de dados.RFX_LongBinary:
Essa é a única biblioteca de classe função RFX que não usa ligação de coluna para receber e enviar dados.Essa função ignora a operação de BindFieldToColumn em vez disso, durante a operação de correção, aloca armazenamento para manter os dados SQL_LONGVARCHAR ou SQL_LONGVARBINARY de entrada e realiza uma chamada SQLGetData para recuperar o valor para o armazenamento alocado.Ao se preparar para enviar valores de dados de volta para a fonte de dados (como operações NomeValor e valor), essa função usa a funcionalidade do ODBC DATA_AT_EXEC.Consulte técnico anotação 45 para obter mais informações sobre como trabalhar com SQL_LONGVARBINARY e SQL_LONGVARCHARs.
Ao escrever seu próprio RFX_ função, você sempre poderá usar CFieldExchange::Default para implementar uma determinada operação.Examinar a implementação do padrão para a operação em questão.Se realiza a operação seria escrever em seu RFX_ função pode delegar para o CFieldExchange::Default. Você pode ver exemplos de chamada CFieldExchange::Default em dbrfx.cpp
É importante chamar IsFieldType no início de sua função RFX e retornar imediatamente se retornará falso.Esse mecanismo mantém operações de parâmetro de sendo executada no outputColumnse vice-versa (como chamada BindParam em um outputColumn).Além disso, IsFieldType automaticamente mantém o controle de contagem de outputColumns (m_nFields) e params (m_nParams).