Поделиться через


TN043. Процедуры RFX

Примечание.

Следующее техническое примечание не было обновлено, поскольку сначала оно было включено в электронную документацию. В результате некоторые процедуры и разделы могут быть устаревшими или неверными. Для получения последних сведений рекомендуется выполнить поиск интересующей темы в алфавитном указателе документации в Интернете.

В этом примечании описывается архитектура обмена полями записей (RFX). В нем также описывается написание процедуры RFX_ .

Общие сведения об Exchange полей записей

Все функции полей набора записей выполняются с кодом 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.

Вызовы полей набора записей — это способ регистрации расположений памяти (обычно членов данных) для хранения данных поля для CMySet класса.

Примечания.

Функции полей набора записей предназначены для работы только с CRecordset классами. Они обычно не доступны для использования другими классами MFC.

Начальные значения данных задаются в стандартном конструкторе C++, как правило, в блоке с комментариями //{{AFX_FIELD_INIT(CMylSet) и //}}AFX_FIELD_INIT комментариями.

Каждая функция RFX_ должна поддерживать различные операции, начиная от возврата состояния грязное поля до архивации поля в подготовке к редактированию поля.

Каждая функция, которая вызывает DoFieldExchange (например SetFieldNull, IsFieldDirty), выполняет собственную инициализацию вокруг вызова DoFieldExchange.

Как это работает

Вам не нужно понимать следующее, чтобы использовать обмен полями записей. Однако понимание того, как это работает за кулисами, поможет вам написать собственную процедуру обмена.

Функция-член DoFieldExchange очень похожа Serialize на функцию-член — она отвечает за получение или настройку данных во внешнюю форму (в данном случае столбцы из результата запроса ODBC) из/в данные-члены класса. Параметр pFX — это контекст для обмена данными и аналогичен параметру CObject::SerializeCArchive. PFX (CFieldExchangeобъект) имеет индикатор операции, аналогичный обобщению флага направления CArchive. Функция RFX может поддерживать следующие операции:

  • BindParam — указывает, где ODBC должен получать данные параметров

  • BindFieldToColumn — указывает, где ODBC должен получать и откладывать выходные данныеColumn

  • Fixup — задать длину, задать CString/CByteArray бит состояния NULL

  • MarkForAddNew— пометить грязное, если значение изменилось с момента вызова AddNew

  • MarkForUpdate— пометить грязное, если значение изменилось с момента вызова Edit

  • Name— добавление имен полей для полей, помеченных грязное

  • NameValue— добавление "<column name>=" для полей, помеченных грязное

  • Value — добавление "", за которым следует разделитель, например "," или "

  • SetFieldDirty— задайте бит состояния грязное (т. е. изменено) поле

  • SetFieldNull — задать бит состояния, указывающий значение NULL для поля

  • IsFieldDirty— возвращаемое значение бита состояния грязное

  • IsFieldNull — возвращаемое значение бита состояния NULL

  • IsFieldNullable — возвращает значение TRUE, если поле может содержать значения NULL

  • 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));
    }
    

Примечание.

Такой код не может быть изменен классомWizard и должен использоваться только за пределами специальных комментариев формата.

Написание пользовательского 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 в качестве прокси-сервера для отправки и получения данных даты и времени. Различные операции должны передавать сведения о дате и времени между объектом C++ CTime и прокси-сервером TIMESTAMP_STRUCT. Это значительно усложняет эту функцию, но это хороший пример использования прокси-сервера для передачи данных.

RFX_LongBinary: это единственная функция RFX библиотеки классов, которая не использует привязку столбцов для получения и отправки данных. Эта функция игнорирует операцию BindFieldToColumn, а во время операции исправления выделяет хранилище для хранения входящих SQL_LONGVARCHAR или SQL_LONGVARBINARY данных, а затем выполняет вызов SQLGetData для получения значения в выделенное хранилище. При подготовке к отправке значений данных обратно в источник данных (например, операции NameValue и Value), эта функция использует DATA_AT_EXEC функции ODBC. Дополнительные сведения о работе с SQL_LONGVARBINARY и SQL_LONGVARCHARs см . в техническом примечание 45 .

При написании собственной функции RFX_ часто можно использовать CFieldExchange::Default для реализации данной операции. Ознакомьтесь с реализацией по умолчанию для этой операции. Если она выполняет операцию, в RFX_ функцию можно делегировать.CFieldExchange::Default Примеры вызова CFieldExchange::Default в dbrfx.cpp

Важно вызывать IsFieldType функцию RFX в начале функции RFX и возвращать немедленно, если она возвращает значение FALSE. Этот механизм позволяет выполнять операции параметров для outputColumns и наоборот (например, вызов выходных BindParam данныхColumn). Кроме того, IsFieldType автоматически отслеживает количество выходных данныхColumns (m_nFields) и params (m_nParams).

См. также

Технические примечания по номеру
Технические примечания по категории