TN043:RFX 常式
注意
下列技術提示自其納入線上文件以來,未曾更新。 因此,有些程序和主題可能已過期或不正確。 如需最新資訊,建議您在線上文件索引中搜尋相關的主題。
此附註描述記錄欄位交換 (RFX) 架構。 它也會描述如何撰寫 RFX_ 程式。
記錄欄位交換概觀
所有記錄集欄位函式都是使用 C++ 程式代碼完成。 沒有特殊的資源或魔術宏。 機制的核心是必須在每個衍生記錄集類別中覆寫的虛擬函式。 它一律會以下列形式找到:
void CMySet::DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CMySet)
<recordset exchange field type call>
<recordset exchange function call>
//}}AFX_FIELD_MAP
}
特殊格式 AFX 批注可讓 ClassWizard 在此函式中尋找和編輯程式代碼。 與 ClassWizard 不相容的程式代碼應該放在特殊格式批注之外。
在上述範例中, <recordset_exchange_field_type_call> 的格式如下:
pFX->SetFieldType(CFieldExchange::outputColumn);
與 <recordset_exchange_function_call> 格式如下:
RFX_Custom(pFX, "Col2", m_Col2);
大部分 的RFX_函 式都有三個如上所示的自變數,但有些函式(例如 RFX_Text
和 RFX_Binary
)有額外的選擇性自變數。
每個DoDataExchange
函式中可能會包含一個以上的RFX_。
如需 MFC 提供的所有記錄集字段交換例程清單,請參閱 'afxdb.h'。
Recordset 欄位呼叫是註冊記憶體位置(通常是數據成員)以儲存類別的欄位數據 CMySet
的方式。
備註
Recordset 欄位函式的設計只能與類別搭配使用 CRecordset
。 任何其他 MFC 類別通常都無法使用它們。
數據的初始值是在標準 C++ 建構函式中設定,通常是在具有 //{{AFX_FIELD_INIT(CMylSet)
和 //}}AFX_FIELD_INIT
批注的區塊中。
每個 RFX_ 函式都必須支援各種作業,範圍從傳回欄位的骯髒狀態到封存欄位,以準備編輯欄位。
每個呼叫 DoFieldExchange
的函式(例如 SetFieldNull
, IsFieldDirty
),都會在呼叫 DoFieldExchange
前後執行自己的初始化。
其運作方式
您不需要瞭解下列專案,即可使用記錄欄位交換。 不過,瞭解這在幕後的運作方式將協助您撰寫自己的交換程式。
成員 DoFieldExchange
函式與成員函式非常類似 Serialize
,它負責從外部窗體取得或設定數據(在此案例中為 ODBC 查詢結果的數據行)從 類別中的成員數據。 pFX 參數是執行數據交換的內容,類似於 CArchive 參數。CObject::Serialize
pFX (a CFieldExchange
物件) 具有作業指標,類似於 CArchive 方向旗標的一般化。 RFX 函式可能必須支援下列作業:
BindParam
— 指出 ODBC 應該擷取參數數據的位置BindFieldToColumn
- 指出 ODBC 必須擷取/儲存輸出Column 數據的位置Fixup
— 設定CString/CByteArray
長度、設定 NULL 狀態位MarkForAddNew
— 如果值自 AddNew 呼叫後變更,則標示已變更MarkForUpdate
— 如果值自編輯呼叫后變更,則標示已變更Name
— 為標示為已變更的欄位附加功能變數名稱NameValue
— 針對標示為已變更的字段附加 “<column name>=”Value
— 附加 “” 後面接著分隔符,例如 ',' 或 'SetFieldDirty
— 設定狀態位已變更 (亦即已變更) 欄位SetFieldNull
— 設定狀態位,指出欄位的 Null 值IsFieldDirty
— 傳回骯髒狀態位的值IsFieldNull
— Null 狀態位的傳回值IsFieldNullable
— 如果欄位可以保存 NULL 值,則傳回 TRUEStoreField
— 封存域值LoadField
— 重載封存的域值GetFieldInfoValue
— 傳回欄位的一般資訊GetFieldInfoOrdinal
— 傳回欄位的一般資訊
用戶擴充功能
有數種方式可以擴充預設 RFX 機制。 您可以
新增數據類型。 例如:
CBookmark
新增交換程式(RFX_)。
void AFXAPI RFX_Bigint(CFieldExchange* pFX, const char *szName, BIGINT& value);
DoFieldExchange
讓成員函式有條件地包含其他 RFX 呼叫或任何其他有效的 C++ 語句。while (posExtraFields != NULL) { RFX_Text(pFX, m_listName.GetNext(posExtraFields), m_listValue.GetNext(posExtraValues)); }
注意
ClassWizard 無法編輯這類程式代碼,而且應該只在特殊格式批注之外使用。
撰寫自定義 RFX
若要撰寫您自己的自定義 RFX 函式,建議您複製現有的 RFX 函式,並將其修改為您自己的用途。 選取要複製的正確 RFX 可讓作業更容易。 有些 RFX 函式有一些唯一的屬性,您應該在決定要複製哪些屬性時加以考慮。
RFX_Long
和 RFX_Int
:這些是最簡單的 RFX 函式。 數據值不需要任何特殊的解譯,而且數據大小是固定的。
RFX_Single
和 RFX_Double
:如同上述RFX_Long和RFX_Int,這些函式很簡單,而且可以廣泛使用預設實作。 它們會儲存在 dbflt.cpp 中,而不是 dbrfx.cpp,不過,只有在明確參考時,才能啟用載入運行時間浮點連結庫。
RFX_Text
和 RFX_Binary
:這兩個函式會預先配置靜態緩衝區來保存字串/二進位資訊,而且必須使用 ODBC SQLBindCol 註冊這些緩衝區,而不是註冊 &value。 因此,這兩個函式有許多特殊案例程序代碼。
RFX_Date
:ODBC 會傳回自己TIMESTAMP_STRUCT數據結構中的日期和時間資訊。 此函式會將TIMESTAMP_STRUCT動態配置為「Proxy」,以便傳送和接收日期時間數據。 各種作業必須在 C++ CTime
物件與TIMESTAMP_STRUCT Proxy 之間傳送日期和時間資訊。 這讓此函式變得相當複雜,但這是如何使用 Proxy 進行數據傳輸的好範例。
RFX_LongBinary
:這是唯一不使用數據行系結來接收和傳送數據的類別庫 RFX 函式。 此函式會忽略 BindFieldToColumn 作業,而是在 Fixup 作業期間,配置記憶體來保存傳入SQL_LONGVARCHAR或SQL_LONGVARBINARY數據,然後執行 SQLGetData 呼叫,以擷取配置記憶體中的值。 準備將數據值傳回數據源時(例如 NameValue 和 Value 作業),此函式會使用 ODBC 的DATA_AT_EXEC功能。 如需使用SQL_LONGVARBINARY和SQL_LONGVARCHARs的詳細資訊,請參閱 技術附註 45 。
撰寫自己的 RFX_ 函式時,您通常可以使用 CFieldExchange::Default
來實作指定的作業。 查看有關作業的 Default 實作。 如果它會執行作業,您會在RFX_函式中撰寫,您可以將 委派給 CFieldExchange::Default
。 您可以在 dbrfx.cpp 中看到呼叫 CFieldExchange::Default
的範例
請務必在 RFX 函式開頭呼叫 IsFieldType
,並在傳回 FALSE 時立即傳回 。 此機制可讓參數作業在 outputColumns 上執行,反之亦然(例如呼叫 BindParam
outputColumn)。 此外,IsFieldType
自動追蹤 outputColumns (m_nFields) 和參數 (m_nParams) 的計數。