TN043 : Routines RFX
[!REMARQUE]
La note technique suivante n'a pas été modifiée depuis si c'était première inclus dans la documentation en ligne.Par conséquent, certaines procédures et rubriques peuvent être obsolètes ou incorrects.Pour obtenir les informations les plus récentes, il est recommandé que vous trouviez la rubrique d'intérêt dans l'index de la documentation en ligne.
Cette remarque décrit l'architecture RFX (record field exchange).Elle décrit également comment vous écrivez une procédure de RFX_ .
Vue d'ensemble de record field exchange
Toutes les fonctions de champ de recordset sont effectuées avec le code C++.Il n'existe aucune ressource particulière ou macro magique.Le cœur du mécanisme est une fonction virtuelle qui doit être substituée dans chaque classe de recordset dérivée.Il est toujours trouvé dans cette forme :
void CMySet::DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CMySet)
<recordset exchange field type call>
<recordset exchange function call>
//}}AFX_FIELD_MAP
}
Les commentaires spéciaux d'AFX de format permettent à l'assistant classe pour rechercher et modifier le code de cette fonction.Le code qui n'est pas compatible avec l'assistant classe doit être placé en dehors de les commentaires spéciaux de format.
Dans l'exemple ci-dessus, <recordset_exchange_field_type_call> est comme suit :
pFX->SetFieldType(CFieldExchange::outputColumn);
et <recordset_exchange_function_call> est comme suit :
RFX_Custom(pFX, "Col2", m_Col2);
La plupart des fonctions de RFX_ en ont trois arguments comme indiqué ci-dessus, mais (par exemple.RFX_Text et RFX_Binary) ont des arguments facultatifs supplémentaires.
Plusieurs RFX_ peut être inclus dans chaque fonction d' DoDataExchange .
Consultez « afxdb.h » pour obtenir la liste complète des routines d'échange de champ de recordset fournies avec MFC.
Les appels de champ de recordset permettent d'enregistrer des emplacements de mémoire (généralement données membres) pour enregistrer des données du champ d'une classe de CMySet .
Remarques
Les fonctions de champ de recordset sont conçues pour être utilisées uniquement avec les classes d' CRecordset .Elles ne sont généralement pas utilisables par une autre classe MFC.
Les valeurs initiales des données sont définies dans le constructeur C++ standard, habituellement dans un bloc avec //{{AFX_FIELD_INIT(CMylSet) et les commentaires d' //}}AFX_FIELD_INIT .
Chaque fonction de RFX_ doit prendre en charge plusieurs opérations, allant de retourner l'état modifié du champ à archiver le champ pendant la de modifier le champ.
Chaque fonction qui appelle DoFieldExchange (par exemple SetFieldNull, IsFieldDirty), effectue sa propre initialisation autour de l'appel à DoFieldExchange.
Comment fonctionne-t-cela ?
Vous n'avez pas besoin d'inclure les éléments suivants afin d'utiliser l'record field exchange.Toutefois, la maîtrise cela fonctionne en arrière-plan vous aidera à écrire votre propre procédure d'échange.
La fonction membre d' DoFieldExchange est très comparable à la fonction membre d' Serialize — elle est chargée d'obtenir ou de définir des données à/d ' un formulaire externe (dans ce cas colonnes du résultat d'une requête ODBC) de/à des données membres dans la classe.Le paramètre d' pFX est le contexte pour effectuer l'échange de données et est similaire au paramètre d' CArchive à CObject::Serialize.pFX (un objet d' CFieldExchange ) a un indicateur d'opération, qui est semblable, mais une généralisation de la balise de direction d' CArchive .Une fonction RFX peut peut-être prendre en charge les opérations suivantes :
BindParam — indiquer où ODBC doit extraire des données de paramètre
BindFieldToColumn — indiquer où ODBC doit récupérer/des données outputColumn de dépôt
Fixup — longueurs définies de CString/CByteArray , bit NULL d'état d'ensemble
MarkForAddNew — marque modifiée si la valeur a changé comme appel d'AddNew
MarkForUpdate — marque modifiée si la valeur a changé comme appel de modification
Nom — Ajoutez les noms de champs pour les champs a marqué comme étant modifié
NameValue — ajoutez<nom de colonne>= « ? » pour modifié marqué par champs
Value — Ajoutez « ? » suivi du séparateur, comme « , » ou ''
SetFieldDirty — bit défini d'état modifié (c. autrement dit.) champ modifié
SetFieldNull — bit défini d'état qui indique la valeur NULL pour le champ
IsFieldDirty — valeur de retour de bits modifié d'état
IsFieldNull — valeur de retour de bits null d'état
IsFieldNullable — retourne TRUE si le champ peut contenir des valeurs NULL
StoreField — valeur de champ d'archivage
LoadField — valeur de champ archivée par rechargement
GetFieldInfoValue — informations générales de retour sur un champ
GetFieldInfoOrdinal — informations générales de retour sur un champ
Extensions d'utilisateur
Il existe plusieurs manières d'étendre le mécanisme de la valeur par défaut RFX.Vous pouvez :
Ajoutez de nouveaux types de données.Par exemple :
CBookmark
Ajoutez les nouvelles procédures d'échange (RFX_ ? ? ?).
void AFXAPI RFX_Bigint(CFieldExchange* pFX, const char *szName, BIGINT& value);
Intégrez la fonction membre d' DoFieldExchange de manière conditionnelle des appels supplémentaires RFX ou toutes les autres instructions valides C++.
while (posExtraFields != NULL) { RFX_Text(pFX, m_listName.GetNext(posExtraFields), m_listValue.GetNext(posExtraValues)); }
[!REMARQUE]
Un tel code ne peut pas être modifié par l'assistant classe et doit être utilisé uniquement en dehors de les commentaires spéciaux de format.
Écrire un personnalisé RFX
Pour écrire votre propre fonction de le personnalisé RFX, on suggère que vous avez copié une fonction existante RFX et la modifier à vos objectifs.Sélectionner la droite RFX de copier peut faciliter votre travail beaucoup.Certaines fonctions RFX ont des propriétés uniques que vous devez prendre en considération lors vous aurez parfois pour copier.
RFX_Long and RFX_Int:
Ce sont les fonctions RFX les plus simples.La valeur de données n'a besoin d'aucune traduction spéciale, et la taille des données est résolue.RFX_Single and RFX_Double:
Comme RFX_Long et RFX_Int ci-dessus, ces fonctions sont simples et peuvent utiliser l'implémentation par défaut largement.Ils sont stockés dans dbflt.cpp au lieu de dbrfx.cpp, toutefois, pour activer charger la bibliothèque d'exécution de virgule flottante uniquement lorsqu'ils sont explicitement référence.RFX_Text and RFX_Binary:
Ces deux fonctions préaffectent un tampon statique pour contenir la chaîne/informations binaires, et doivent relever ces mémoires tampon avec ODBC SQLBindCol au lieu de stocker le &value.De ce fait, ces deux fonctions ont beaucoup de code de cas particulier.RFX_Date:
ODBC retourne les informations d'horodatage dans leur propre structure de données de TIMESTAMP_STRUCT.Cette fonction alloue dynamiquement un TIMESTAMP_STRUCT comme « proxy » pour envoyer et recevoir des données datetime.Les différentes opérations doivent transférer des informations d'horodatage entre l'objet C++ CTime et le proxy de TIMESTAMP_STRUCT.Cela complique cette fonction considérablement, il constitue un bon exemple d'utilisation d'un proxy pour le transfert de données.RFX_LongBinary:
C'est la seule fonction de la bibliothèque de classes RFX qui n'utilise pas la liaison des colonnes pour recevoir et envoyer des données.Cette fonctionnalité ignore l'opération de BindFieldToColumn et à la place, pendant l'opération de corrections, alloue le stockage pour contenir les données entrantes de SQL_LONGVARCHAR ou de SQL_LONGVARBINARY, puis effectue un appel de SQLGetData pour récupérer la valeur dans le stockage alloué.Lors de la préparation de pour envoyer des valeurs de données à la source de données (comme NameValue et évaluer les opérations), cette fonction utilise les fonctionnalités du DATA_AT_EXEC ODBC.Consultez note technique 45 pour plus d'informations sur l'utilisation SQL_LONGVARBINARY et SQL_LONGVARCHARs.
Lorsque vous écrivez votre propre fonction de RFX_ , vous pouvez souvent utiliser CFieldExchange::Default pour implémenter une opération donnée.Regardez l'implémentation de la valeur par défaut pour l'opération en question.S'il n'exécute l'opération vous écrirez dans la fonction de RFX_ que vous pouvez déléguer à CFieldExchange::Default. Vous pouvez consulter des exemples d'appeler CFieldExchange::Default dans dbrfx.cpp
Il est important d'appeler IsFieldType au début de votre fonction RFX, et retourne immédiatement s'il retourne FALSE.Ce mécanisme conserve les opérations de paramètre à exécuter sur outputColumns, et inversement (comme appeler BindParam sur outputColumn).En outre, IsFieldType gère automatiquement le nombre d' outputColumns (m_nFields) et params (m_nParams).