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::Serialize
CArchive. PFX (CFieldExchange
объект) имеет индикатор операции, аналогичный обобщению флага направления CArchive. Функция RFX может поддерживать следующие операции:
BindParam
— указывает, где ODBC должен получать данные параметровBindFieldToColumn
— указывает, где ODBC должен получать и откладывать выходные данныеColumnFixup
— задать длину, задатьCString/CByteArray
бит состояния NULLMarkForAddNew
— пометить грязное, если значение изменилось с момента вызова AddNewMarkForUpdate
— пометить грязное, если значение изменилось с момента вызова EditName
— добавление имен полей для полей, помеченных грязноеNameValue
— добавление "<column name>=" для полей, помеченных грязноеValue
— добавление "", за которым следует разделитель, например "," или "SetFieldDirty
— задайте бит состояния грязное (т. е. изменено) полеSetFieldNull
— задать бит состояния, указывающий значение NULL для поляIsFieldDirty
— возвращаемое значение бита состояния грязноеIsFieldNull
— возвращаемое значение бита состояния NULLIsFieldNullable
— возвращает значение TRUE, если поле может содержать значения NULLStoreField
— значение поля архивации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).
См. также
Технические примечания по номеру
Технические примечания по категории