分享方式:


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_TextRFX_Binary)有額外的選擇性自變數。

每個DoDataExchange函式中可能會包含一個以上的RFX_

如需 MFC 提供的所有記錄集字段交換例程清單,請參閱 'afxdb.h'。

Recordset 欄位呼叫是註冊記憶體位置(通常是數據成員)以儲存類別的欄位數據 CMySet 的方式。

備註

Recordset 欄位函式的設計只能與類別搭配使用 CRecordset 。 任何其他 MFC 類別通常都無法使用它們。

數據的初始值是在標準 C++ 建構函式中設定,通常是在具有 //{{AFX_FIELD_INIT(CMylSet)//}}AFX_FIELD_INIT 批注的區塊中。

每個 RFX_ 函式都必須支援各種作業,範圍從傳回欄位的骯髒狀態到封存欄位,以準備編輯欄位。

每個呼叫 DoFieldExchange 的函式(例如 SetFieldNullIsFieldDirty),都會在呼叫 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 值,則傳回 TRUE

  • StoreField — 封存域值

  • 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_LongRFX_Int:這些是最簡單的 RFX 函式。 數據值不需要任何特殊的解譯,而且數據大小是固定的。

RFX_SingleRFX_Double:如同上述RFX_Long和RFX_Int,這些函式很簡單,而且可以廣泛使用預設實作。 它們會儲存在 dbflt.cpp 中,而不是 dbrfx.cpp,不過,只有在明確參考時,才能啟用載入運行時間浮點連結庫。

RFX_TextRFX_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自動追蹤 outputColumnsm_nFields) 和參數 (m_nParams) 的計數。

另請參閱

依編號顯示的技術提示
依分類區分的技術提示