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 定位和编辑此函数内的代码。 代码与类向导兼容应放置在特殊形式注释外部。

在上面的示例中, <recordset_exchange_field_type_call> 在窗体中:

pFX->SetFieldType(CFieldExchange::outputColumn);

并 <recordset_exchange_function_call> 在窗体中:

RFX_Custom(pFX, "Col2", m_Col2);

大多数 RFX_ 函数具有三个参数如上所述,但是,某些 (即。 RFX_TextRFX_Binary) 具有不同的可选参数。

多个 RFX_ 在每个 DoDataExchange 功能可以包括。

请参见 “所有记录集字段交换实例列表的 afxdb.h 随 MFC。

记录集字段调用是一种寄存器内存位置 (通常是数据成员) 存储字段数据。 CMySet 类。

注释

记录集字段功能旨在仅与 CRecordset 类一起使用。 它们由任何其他 MFC 类通常不可用。

数据的初始值对标准 C++ 构造函数设置,通常在与 //{{AFX_FIELD_INIT(CMylSet) 和 //}}AFX_FIELD_INIT 注释的块。

每个 RFX_ 函数必须支持各种操作,范围从返回字段的已更新状态到存档字段准备编辑该字段。

调用 DoFieldExchange 的每个函数 (例如 SetFieldNullIsFieldDirty),则调用周围自行初始化为 DoFieldExchange

它如何工作?

您无需了解以下为了使用记录字段交换。 但是,了解了如何在幕后工作将帮助您编写替换程序。

DoFieldExchange 成员函数十分类似于 Serialize 成员函数 —到获取或设置为/从外部窗体 (在这种情况下从 ODBC 查询结果的列的数据负责) from/to 在类的成员数据。 pFX 参数是执行上下文数据交换和类似于 CArchive 参数于 CObject::Serialize。 pFX ( CFieldExchange 对象) 具有操作指示符,类似,但是, CArchive 定向标志的泛化。 RFX 函数可能必须支持以下操作:

  • BindParam —指示 ODBC 应检索参数数据

  • BindFieldToColumn —指示 ODBC 位置必须检索/存款 outputColumn 数据

  • Fixup —设置的 CString/CByteArray 长度,将 NULL 状态位

  • MarkForAddNew —标记错误,如果值已更改,因为 AddNew 调用

  • MarkForUpdate —标记错误,如果值已更改,因为 " 调用

  • 名称 —追加字段名称为字段标记为错误

  • NameValue —追加 “<列名>=?”对字段标记的错误

  • —追加 “?”后跟分隔符,如 “,”或 "

  • SetFieldDirty —错误设置的状态位 (即。 已更改的字段)

  • SetFieldNull —指示字段设置的状态个 null 值

  • IsFieldDirty —返回错误的状态位的值

  • IsFieldNull —返回 null 状态位的值

  • 字段,则可以表示空值,IsFieldNullable —返回 TRUE

  • StoreField —存档字段值

  • LoadField — Reload 存档的字段值

  • 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 and RFX_Int:
    以下是最简单的 RFX 函数。 数据值不需要任何特殊解释,因此,数据大小是固定的。

  • RFX_Single and RFX_Double:
    与上面 RFX_Long 和 RFX_Int,这些功能是简单的,可广泛使用默认实现。 它们在 dbflt.cpp 中而不是 dbrfx.cpp,但是,启用加载运行时浮点库,才会显式时是引用。

  • RFX_Text and RFX_Binary:
    这两种功能预分配一个静态缓冲区包含字符串/二进制信息,并且必须注册 ODBC SQLBindCol 的这些缓冲区而不是注册 &value。 因此,这两个函数具有许多专用代码。

  • RFX_Date:
    ODBC 在其 TIMESTAMP_STRUCT 数据结构的将返回时和时间信息。 此功能动态分配 TIMESTAMP_STRUCT 作为一个 “代理”发送和接收的 datetime 数据。 各种操作必须调用日期和时间信息在 C++ CTime 对象和 TIMESTAMP_STRUCT 代理之间。 这相当复杂此功能,但是,它是一个很好的示例说明如何为数据传输使用代理。

  • RFX_LongBinary:
    这是不使用列绑定接收和发送数据的唯一类库 RFX 函数。 此函数在 Fixup 操作时忽略 BindFieldToColumn 操作,并且,分配存储区保存传入的 SQL_LONGVARCHAR 或 SQL_LONGVARBINARY 数据,然后执行 SQLGetData 调用检索值分配到的存储。 准备将数据值到数据源 (例如 NameValue 和值操作) 时,此函数使用 ODBC 的 DATA_AT_EXEC 功能。 请参见 技术说明 45 有关 SQL_LONGVARBINARY 和 SQL_LONGVARCHARs 处理的更多信息。

当编写您的 RFX_ 功能时,您通常可以使用 CFieldExchange::Default 实现特定操作。 查看默认的实现用于相关的操作。 如果它执行操作可以将委托到 **CFieldExchange::Default.**的 RFX_ 功能并您可以查看对 dbrfx.cpp 的 CFieldExchange::Default 的示例

; 如果返回 FALSE,在您的 RFX 函数的起始页 IsFieldType ,并立即返回非常重要。 此机制在 outputColumns阻止执行的参数操作,反之亦然 (如调用 outputColumnBindParam )。 此外, IsFieldType 自动记录计数 outputColumns (m_nFields) 和 params (m_nParams)。

请参见

其他资源

由Number "技术说明

技术说明按类别