Record Field Exchange: Working with the Wizard Code
The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.
The latest version of this topic can be found at Record Field Exchange: Working with the Wizard Code.
This topic explains the code that the MFC Application Wizard and Add Class (as described in Adding an MFC ODBC Consumer) write to support RFX and how you might want to alter that code.
This topic applies to classes derived from |
When you create a recordset class with the MFC Application Wizard or Add Class, the wizard writes the following RFX-related elements for you, based on the data source, table, and column choices you make in the wizard:
Declarations of the recordset field data members in the recordset class
An override of
CRecordset::DoFieldExchangeInitialization of recordset field data members in the recordset class constructor
The wizards write a recordset class declaration in an .h file that resembles the following for class CSections:
class CSections : public CRecordset
{
public:
CSections(CDatabase* pDatabase = NULL);
DECLARE_DYNAMIC(CSections)
// Field/Param Data
CString m_strCourseID;
CString m_strInstructorID;
CString m_strRoomNo;
CString m_strSchedule;
CString m_strSectionNo;
// Overrides
// Wizard generated virtual function overrides
protected:
virtual CString GetDefaultConnect(); // Default connection string
virtual CString GetDefaultSQL(); // Default SQL for Recordset
virtual void DoFieldExchange(CFieldExchange* pFX); // RFX support
// Implementation
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
};
If you add parameter data members or new field data members that you bind yourself, add them after the wizard-generated ones.
Also, notice that the wizard overrides the DoFieldExchange member function of class CRecordset.
DoFieldExchange is the heart of RFX. The framework calls DoFieldExchange any time it needs to move data either from data source to recordset or from recordset to data source. DoFieldExchange also supports obtaining information about field data members through the IsFieldDirty and IsFieldNull member functions.
The following DoFieldExchange override is for the CSections class. The wizard writes the function in the .cpp file for your recordset class.
void CSections::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, "CourseID", m_strCourseID);
RFX_Text(pFX, "InstructorID", m_strInstructorID);
RFX_Text(pFX, "RoomNo", m_strRoomNo);
RFX_Text(pFX, "Schedule", m_strSchedule);
RFX_Text(pFX, "SectionNo", m_strSectionNo);
}
Notice the following key features of the function:
This section of the function is called the field map.
A call to
CFieldExchange::SetFieldType, through thepFXpointer. This call specifies that all RFX function calls up to the end ofDoFieldExchangeor the next call toSetFieldTypeare output columns. For more information, see CFieldExchange::SetFieldType.Several calls to the
RFX_Textglobal function — one per field data member (all of which areCStringvariables in the example). These calls specify the relationship between a column name on the data source and a field data member. The RFX functions do the actual data transfer. The class library supplies RFX functions for all the common data types. For more information about RFX functions, see Record Field Exchange: Using the RFX Functions.
Note The order of the columns in your result set must match the order of the RFX function calls in
DoFieldExchange.The
pFXpointer to a CFieldExchange object that the framework passes when it callsDoFieldExchange. TheCFieldExchangeobject specifies the operation thatDoFieldExchangeis to perform, the direction of transfer, and other context information.
The recordset constructor that the wizards write contains two things related to RFX:
An initialization for each field data member
An initialization for the m_nFields data member, which contains the number of field data members
The constructor for the CSections recordset example looks like this:
CSections::CSections(CDatabase* pdb)
: CRecordset(pdb)
{
m_strCourseID = "";
m_strInstructorID = "";
m_strRoomNo = "";
m_strSchedule = "";
m_strSectionNo = "";
m_nFields = 5;
}
If you add any field data members manually, as you might if you bind new columns dynamically, you must increment |
m_nFields += 3;
This is the code for adding three new fields. If you add any parameter data members, you must initialize the m_nParams data member, which contains the number of parameter data members. Put the m_nParams initialization outside the brackets.