TN043: procedury RFX
Uwaga
Następująca uwaga techniczna nie została zaktualizowana, ponieważ została po raz pierwszy uwzględniona w dokumentacji online. W związku z tym niektóre procedury i tematy mogą być nieaktualne lub nieprawidłowe. Aby uzyskać najnowsze informacje, zaleca się wyszukanie interesującego tematu w indeksie dokumentacji online.
W tej notatce opisano architekturę wymiany pól rekordów (RFX). W tym artykule opisano również sposób pisania procedury RFX_ .
Omówienie wymiany pól rekordów
Wszystkie funkcje pól zestawu rekordów są wykonywane przy użyciu kodu C++. Brak specjalnych zasobów ani makr magicznych. Sercem mechanizmu jest funkcja wirtualna, która musi zostać zastąpiona w każdej pochodnej klasie zestawu rekordów. Zawsze można go znaleźć w tej formie:
void CMySet::DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CMySet)
<recordset exchange field type call>
<recordset exchange function call>
//}}AFX_FIELD_MAP
}
Komentarze AFX w specjalnym formacie umożliwiają klasyWizard lokalizowanie i edytowanie kodu w tej funkcji. Kod niezgodny z klasą ClassWizard powinien zostać umieszczony poza specjalnymi komentarzami w formacie.
W powyższym przykładzie <recordset_exchange_field_type_call> ma postać:
pFX->SetFieldType(CFieldExchange::outputColumn);
a <recordset_exchange_function_call> ma postać:
RFX_Custom(pFX, "Col2", m_Col2);
Większość funkcji RFX_ ma trzy argumenty, jak pokazano powyżej, ale niektóre (np. RFX_Text
i RFX_Binary
) mają dodatkowe argumenty opcjonalne.
W każdej DoDataExchange
funkcji może znajdować się więcej niż jeden RFX_.
Zobacz "afxdb.h", aby uzyskać listę wszystkich procedur wymiany pól zestawu rekordów dostarczonych z MFC.
Wywołania pól zestawu rekordów to sposób rejestrowania lokalizacji pamięci (zazwyczaj składowych danych) do przechowywania danych pól dla CMySet
klasy.
Uwagi
Funkcje pól zestawu rekordów są przeznaczone do pracy tylko z klasami CRecordset
. Nie są one ogólnie używane przez inne klasy MFC.
Początkowe wartości danych są ustawiane w standardowym konstruktorze języka C++, zwykle w bloku z komentarzami //{{AFX_FIELD_INIT(CMylSet)
i //}}AFX_FIELD_INIT
.
Każda funkcja RFX_ musi obsługiwać różne operacje, począwszy od zwracania stanu zanieczyszczonego pola do archiwizowania pola w ramach przygotowań do edycji pola.
Każda funkcja, która wywołuje DoFieldExchange
(na przykład SetFieldNull
, IsFieldDirty
), wykonuje własną inicjację wokół wywołania metody DoFieldExchange
.
Jak to działa
Nie musisz rozumieć następujących informacji, aby użyć wymiany pól rekordów. Jednak zrozumienie, jak to działa w tle, pomoże Ci napisać własną procedurę wymiany.
DoFieldExchange
Funkcja składowa jest podobnie jak Serialize
funkcja składowa — jest odpowiedzialna za pobieranie lub ustawianie danych do/z formularza zewnętrznego (w tym przypadku kolumn z wyniku zapytania ODBC) z/do danych składowych w klasie. Parametr pFX jest kontekstem do wymiany danych i jest podobny do parametru CArchive do CObject::Serialize
. PFX (CFieldExchange
obiekt) ma wskaźnik operacji, który jest podobny do, ale uogólnienie flagi kierunku CArchive. Funkcja RFX może wymagać obsługi następujących operacji:
BindParam
— Wskazuje, gdzie odBC ma pobierać dane parametrówBindFieldToColumn
— wskazuje, gdzie odBC musi pobrać/złóż dane wyjścioweKolumnFixup
— UstawianieCString/CByteArray
długości, ustawianie bitu stanu NULLMarkForAddNew
— Oznacz wartość jako zanieczyszczoną, jeśli wartość została zmieniona od wywołania AddNewMarkForUpdate
— Oznacz wartość jako zanieczyszczoną, jeśli wartość została zmieniona od wywołania edycjiName
— Dołączanie nazw pól dla pól oznaczonych jako zanieczyszczoneNameValue
— Dołącz "<nazwa> kolumny=" dla pól oznaczonych jako zanieczyszczoneValue
— Dołącz znak "", po którym następuje separator, na przykład ',' lub 'SetFieldDirty
— Ustawianie stanu bitu zanieczyszczonego (tj. zmienionego) polaSetFieldNull
— Ustaw bit stanu wskazujący wartość null dla polaIsFieldDirty
— Zwraca wartość bitu stanu zanieczyszczonegoIsFieldNull
— Zwracana wartość bitu stanu o wartości nullIsFieldNullable
— Zwraca wartość TRUE, jeśli pole może przechowywać wartości NULLStoreField
— Wartość pola ArchiwumLoadField
— Załaduj ponownie zarchiwizowane wartości polaGetFieldInfoValue
— Zwraca ogólne informacje dotyczące polaGetFieldInfoOrdinal
— Zwraca ogólne informacje dotyczące pola
Rozszerzenia użytkownika
Istnieje kilka sposobów rozszerzenia domyślnego mechanizmu RFX. Można
Dodaj nowe typy danych. Na przykład:
CBookmark
Dodaj nowe procedury wymiany (RFX_).
void AFXAPI RFX_Bigint(CFieldExchange* pFX, const char *szName, BIGINT& value);
Funkcja składowa
DoFieldExchange
warunkowo zawiera dodatkowe wywołania RFX lub inne prawidłowe instrukcje języka C++.while (posExtraFields != NULL) { RFX_Text(pFX, m_listName.GetNext(posExtraFields), m_listValue.GetNext(posExtraValues)); }
Uwaga
Taki kod nie może być edytowany przez klasę ClassWizard i powinien być używany tylko poza specjalnymi komentarzami w formacie.
Pisanie niestandardowego RFX
Aby napisać własną funkcję Custom RFX, zaleca się skopiowanie istniejącej funkcji RFX i zmodyfikowanie jej do własnych celów. Wybranie odpowiedniego RFX do skopiowania może znacznie ułatwić zadanie. Niektóre funkcje RFX mają pewne unikatowe właściwości, które należy wziąć pod uwagę podczas podejmowania decyzji, które mają zostać skopiowane.
RFX_Long
i RFX_Int
: Są to najprostsze funkcje RFX. Wartość danych nie wymaga żadnej specjalnej interpretacji, a rozmiar danych jest stały.
RFX_Single
i RFX_Double
: Podobnie jak RFX_Long i RFX_Int powyżej, te funkcje są proste i mogą korzystać z domyślnej implementacji w szerokim zakresie. Są one jednak przechowywane w pliku dbflt.cpp zamiast dbrfx.cpp, jednak w celu włączenia ładowania biblioteki zmiennoprzecinkowych środowiska uruchomieniowego tylko wtedy, gdy jawnie się odwołują.
RFX_Text
i RFX_Binary
: Te dwie funkcje wstępnie przydzielą bufor statyczny do przechowywania informacji ciągowych/binarnych i muszą zarejestrować te bufory za pomocą funkcji ODBC SQLBindCol zamiast rejestrować i rejestrować wartość. W związku z tym te dwie funkcje mają wiele specjalnych kodów przypadków.
RFX_Date
: FUNKCJA ODBC zwraca informacje o dacie i godzinie we własnej strukturze danych TIMESTAMP_STRUCT. Ta funkcja dynamicznie przydziela TIMESTAMP_STRUCT jako "serwer proxy" do wysyłania i odbierania danych daty i godziny. Różne operacje muszą przesyłać informacje o dacie i godzinie między obiektem C++ CTime
a serwerem proxy TIMESTAMP_STRUCT. To komplikuje tę funkcję znacznie, ale jest dobrym przykładem używania serwera proxy do transferu danych.
RFX_LongBinary
: Jest to jedyna funkcja RFX biblioteki klas, która nie używa powiązania kolumn do odbierania i wysyłania danych. Ta funkcja ignoruje operację BindFieldToColumn, a zamiast tego podczas operacji Fixup przydziela magazyn do przechowywania przychodzących SQL_LONGVARCHAR lub SQL_LONGVARBINARY danych, a następnie wykonuje wywołanie SQLGetData w celu pobrania wartości do przydzielonego magazynu. Podczas przygotowywania do wysyłania wartości danych z powrotem do źródła danych (na przykład operacji NameValue i Value) ta funkcja używa funkcji DATA_AT_EXEC ODBC. Aby uzyskać więcej informacji na temat pracy z SQL_LONGVARBINARY i SQL_LONGVARCHARs, zobacz Technical Note 45 (Uwaga techniczna 45 ).
Podczas pisania własnej funkcji RFX_ często można używać CFieldExchange::Default
jej do implementowania danej operacji. Przyjrzyj się implementacji domyślnej dla danej operacji. Jeśli wykonuje operację, którą będziesz zapisywać w funkcji RFX_ , możesz delegować do funkcji CFieldExchange::Default
. Przykłady wywoływania CFieldExchange::Default
można zobaczyć w pliku dbrfx.cpp
Ważne jest, aby wywołać IsFieldType
funkcję RFX na początku funkcji RFX i zwrócić natychmiast, jeśli zwraca wartość FALSE. Ten mechanizm uniemożliwia wykonywanie operacji parametrów na danych wyjściowychColumns i na odwrót (na przykład wywołanie BindParam
elementu outputColumn). Ponadto IsFieldType
funkcja automatycznie śledzi liczbę parametrów wyjściowych (m_nFields) i parametrów (m_nParams).
Zobacz też
Uwagi techniczne według numerów
Uwagi techniczne według kategorii