TN043: Rutinitas RFX
Catatan
Catatan teknis berikut belum diperbarui sejak pertama kali disertakan dalam dokumentasi online. Akibatnya, beberapa prosedur dan topik mungkin kedaluarsa atau salah. Untuk informasi terbaru, disarankan agar Anda mencari topik yang menarik dalam indeks dokumentasi online.
Catatan ini menjelaskan arsitektur pertukaran bidang rekaman (RFX). Ini juga menjelaskan bagaimana Anda menulis prosedur RFX_ .
Gambaran Umum Pertukaran Bidang Rekaman
Semua fungsi bidang recordset dilakukan dengan kode C++. Tidak ada sumber daya khusus atau makro ajaib. Inti mekanisme adalah fungsi virtual yang harus ditimpa di setiap kelas recordset turunan. Ini selalu ditemukan dalam bentuk ini:
void CMySet::DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CMySet)
<recordset exchange field type call>
<recordset exchange function call>
//}}AFX_FIELD_MAP
}
Format khusus komentar AFX memungkinkan ClassWizard menemukan dan mengedit kode dalam fungsi ini. Kode yang tidak kompatibel dengan ClassWizard harus ditempatkan di luar komentar format khusus.
Dalam contoh di atas, <recordset_exchange_field_type_call> dalam formulir:
pFX->SetFieldType(CFieldExchange::outputColumn);
dan <recordset_exchange_function_call> dalam bentuk:
RFX_Custom(pFX, "Col2", m_Col2);
Sebagian besar fungsi RFX_ memiliki tiga argumen seperti yang ditunjukkan di atas, tetapi beberapa (misalnya RFX_Text
dan RFX_Binary
) memiliki argumen opsional tambahan.
Lebih dari satu RFX_ dapat disertakan dalam setiap DoDataExchange
fungsi.
Lihat 'afxdb.h' untuk daftar semua rutinitas pertukaran bidang recordset yang disediakan dengan MFC.
Panggilan bidang recordset adalah cara mendaftarkan lokasi memori (biasanya anggota data) untuk menyimpan data bidang untuk kelas CMySet
.
Catatan
Fungsi bidang recordset dirancang untuk hanya berfungsi dengan CRecordset
kelas. Mereka umumnya tidak dapat digunakan oleh kelas MFC lainnya.
Nilai awal data diatur dalam konstruktor C++ standar, biasanya dalam blok dengan //{{AFX_FIELD_INIT(CMylSet)
komentar dan //}}AFX_FIELD_INIT
.
Setiap fungsi RFX_ harus mendukung berbagai operasi, mulai dari mengembalikan status kotor bidang hingga pengarsipan bidang sebagai persiapan untuk mengedit bidang.
Setiap fungsi yang memanggil (misalnya , ), melakukan inisialisasinya DoFieldExchange
sendiri di sekitar panggilan ke DoFieldExchange
. IsFieldDirty
SetFieldNull
Bagaimana Cara Kerjanya
Anda tidak perlu memahami hal berikut untuk menggunakan pertukaran bidang rekaman. Namun, memahami cara kerjanya di belakang layar akan membantu Anda menulis prosedur pertukaran Anda sendiri.
Fungsi DoFieldExchange
anggota mirip dengan Serialize
fungsi anggota — bertanggung jawab untuk mendapatkan atau mengatur data ke/dari formulir eksternal (dalam hal ini kolom dari hasil kueri ODBC) dari/ke data anggota di kelas. Parameter pFX adalah konteks untuk melakukan pertukaran data dan mirip dengan parameter CArchive dengan CObject::Serialize
. pFX (CFieldExchange
objek) memiliki indikator operasi, yang mirip dengan, tetapi generalisasi bendera arah CArchive. Fungsi RFX mungkin harus mendukung operasi berikut:
BindParam
— Menunjukkan di mana ODBC harus mengambil data parameterBindFieldToColumn
— Menunjukkan di mana ODBC harus mengambil/mendepositkan data outputColumnFixup
— AturCString/CByteArray
panjang, atur bit status NULLMarkForAddNew
— Tandai kotor jika nilai telah berubah sejak AddNew callMarkForUpdate
— Tandai kotor jika nilai telah berubah sejak Edit panggilanName
— Tambahkan nama bidang untuk bidang yang ditandai kotorNameValue
— Tambahkan "<nama> kolom=" untuk bidang yang ditandai kotorValue
— Tambahkan "" diikuti oleh pemisah, seperti ',' atau ' 'SetFieldDirty
— Atur status bit kotor (yaitu diubah) bidangSetFieldNull
— Atur bit status yang menunjukkan nilai null untuk bidangIsFieldDirty
— Mengembalikan nilai bit status kotorIsFieldNull
— Mengembalikan nilai bit status nullIsFieldNullable
— Mengembalikan TRUE jika bidang dapat menyimpan nilai NULLStoreField
— Nilai bidang arsipLoadField
— Muat ulang nilai bidang yang diarsipkanGetFieldInfoValue
— Mengembalikan informasi umum pada bidangGetFieldInfoOrdinal
— Mengembalikan informasi umum pada bidang
Ekstensi Pengguna
Ada beberapa cara untuk memperluas mekanisme RFX default. Anda dapat
Tambahkan jenis data baru. Misalnya:
CBookmark
Tambahkan prosedur pertukaran baru (RFX_).
void AFXAPI RFX_Bigint(CFieldExchange* pFX, const char *szName, BIGINT& value);
Minta anggota
DoFieldExchange
berfungsi secara kondisional menyertakan panggilan RFX tambahan atau pernyataan C++ lain yang valid.while (posExtraFields != NULL) { RFX_Text(pFX, m_listName.GetNext(posExtraFields), m_listValue.GetNext(posExtraValues)); }
Catatan
Kode tersebut tidak dapat diedit oleh ClassWizard dan harus digunakan hanya di luar komentar format khusus.
Menulis RFX Kustom
Untuk menulis fungsi RFX Kustom Anda sendiri, disarankan agar Anda menyalin fungsi RFX yang ada dan memodifikasinya ke tujuan Anda sendiri. Memilih RFX yang tepat untuk disalin dapat membuat pekerjaan Anda jauh lebih mudah. Beberapa fungsi RFX memiliki beberapa properti unik yang harus Anda perhitungkan saat memutuskan mana yang akan disalin.
RFX_Long
dan RFX_Int
: Ini adalah fungsi RFX paling sederhana. Nilai data tidak memerlukan interpretasi khusus, dan ukuran data diperbaiki.
RFX_Single
dan RFX_Double
: Seperti RFX_Long dan RFX_Int di atas, fungsi-fungsi ini sederhana dan dapat menggunakan implementasi default secara ekstensif. Mereka disimpan dalam dbflt.cpp alih-alih dbrfx.cpp, namun, untuk mengaktifkan pemuatan pustaka titik float runtime hanya ketika mereka secara eksplisit mereferensikan.
RFX_Text
dan RFX_Binary
: Kedua fungsi ini melakukan prealokasi buffer statis untuk menyimpan informasi string/biner, dan harus mendaftarkan buffer ini dengan ODBC SQLBindCol alih-alih mendaftarkan &value. Karena itu, kedua fungsi ini memiliki banyak kode kasus khusus.
RFX_Date
: ODBC mengembalikan informasi tanggal dan waktu dalam struktur data TIMESTAMP_STRUCT mereka sendiri. Fungsi ini secara dinamis mengalokasikan TIMESTAMP_STRUCT sebagai "proksi" untuk mengirim dan menerima data waktu tanggal. Berbagai operasi harus mentransfer informasi tanggal dan waktu antara objek C++ CTime
dan proksi TIMESTAMP_STRUCT. Ini sangat mempersulit fungsi ini, tetapi ini adalah contoh yang baik tentang cara menggunakan proksi untuk transfer data.
RFX_LongBinary
: Ini adalah satu-satunya fungsi RFX pustaka kelas yang tidak menggunakan pengikatan kolom untuk menerima dan mengirim data. Fungsi ini mengabaikan operasi BindFieldToColumn dan sebagai gantinya, selama operasi Perbaikan, mengalokasikan penyimpanan untuk menyimpan data SQL_LONGVARCHAR atau SQL_LONGVARBINARY masuk, lalu melakukan panggilan SQLGetData untuk mengambil nilai ke penyimpanan yang dialokasikan. Saat bersiap untuk mengirim nilai data kembali ke sumber data (seperti operasi NameValue dan Value), fungsi ini menggunakan fungsionalitas DATA_AT_EXEC ODBC. Lihat Catatan Teknis 45 untuk informasi selengkapnya tentang bekerja dengan SQL_LONGVARBINARY dan SQL_LONGVARCHARs.
Saat menulis fungsi RFX_ Anda sendiri, Anda akan sering dapat menggunakan CFieldExchange::Default
untuk menerapkan operasi tertentu. Lihat implementasi Default untuk operasi yang dimaksud. Jika melakukan operasi, Anda akan menulis dalam fungsi RFX_ Anda, Anda dapat mendelegasikan ke CFieldExchange::Default
. Anda dapat melihat contoh panggilan CFieldExchange::Default
di dbrfx.cpp
Penting untuk memanggil IsFieldType
di awal fungsi RFX Anda, dan segera kembali jika mengembalikan FALSE. Mekanisme ini menjaga operasi parameter tidak dilakukan pada outputColumns, dan sebaliknya (seperti memanggil BindParam
pada outputColumn). Selain itu, IsFieldType
secara otomatis melacak jumlah outputColumns (m_nFields) dan param (m_nParams).
Baca juga
Catatan Teknis menurut Angka
Catatan Teknis menurut Kategori