PRB: Problem Using -1 with Double or Float Field VariableLast reviewed: July 18, 1997Article ID: Q118420 |
1.50
WINDOWS
kbprg kbprb
The information in this article applies to:
SYMPTOMSIf an edit control is mapped to a double or float field variable using DDX and RFX functions, a value of -1 for the variable is changed to NULL when a CRecordView moves past the record. To see how this works, perform the follow steps:
CAUSEThe Microsoft Foundation Classes need some way of determining whether a field value is NULL (no value). Because a double variable always has some value, MFC has defined what it calls "pseudo-null" values. If a variable contains a pseudo-null value, it is basically considered NULL. In the file AFXDB.H, you can see what the pseudo-null values are:
#define AFX_RFX_INT_PSEUDO_NULL (0x7EE4) #define AFX_RFX_LONG_PSEUDO_NULL (0x4a4d4120L) #define AFX_RFX_BYTE_PSEUDO_NULL 255 #define AFX_RFX_SINGLE_PSEUDO_NULL (-1.0) #define AFX_RFX_DOUBLE_PSEUDO_NULL (-1.0) #define AFX_RFX_BOOL_PSEUDO_NULL 2 #define AFX_RFX_DATE_PSEUDO_NULL CTime(0)You can see that a value of -1.0 in a double or float field variable means that the field is to have a NULL value. This is not the only item that the database code uses for determining whether a field is NULL. A NULL flag is also used for each field variable, which indicates whether it contains a NULL value. The fundamental problem is in the code for "RFX_Double()" and "RFX_Float()" functions where the MarkForUpdate case is handled. Here is the code for RFX_Double():
case CFieldExchange::MarkForUpdate: if (value == AFX_RFX_DOUBLE_PSEUDO_NULL) pFX->m_prs->SetFieldFlags(nField, AFX_SQL_FIELD_FLAG_NULL, pFX->m_nFieldType); else pFX->m_prs->ClearFieldFlags(nField, AFX_SQL_FIELD_FLAG_NULL, pFX->m_nFieldType); goto LDefault;The problem is that the code simply checks the value of the double field variable and sets the NULL flag if its value is -1 (the pseudo-null value). The MarkForUpdate code is executed every time a CRecordView moves off of a record. Here is some of the code in CRecordView::OnMove():
if (pSet->CanUpdate()) { pSet->Edit(); if (!UpdateData()) return FALSE; pSet->Update(); } RESOLUTIONThere are two possible workarounds. The value of the pseudo-null value can be changed to something that a user of the application is not expected to type into the edit control. So, in the case of RFX_Double(), "AFX_RFX_DOUBLE_PSEUDO_NULL" can be changed in AFXDB.H to something like the following:
#define AFX_RFX_DOUBLE_PSEUDO_NULL (-9.123e19)It would be uncommon for a user to type this. If you decide to fix the problem this way, you need to rebuild the MFC library using the information in the README.TXT file in the \MSVC\MFC\SRC directory. Another way to work around this problem is to copy the code for RFX_Double into the .CPP file where your CRecordset class implementation code is. Change the function name to "RFX_NewDouble()" or whatever you want to call it. Then, delete the "MarkForUpdate" case statement shown above. You can also remove the "LDefault:" label, which is used by the goto statement at the end of the MarkForUpdate case. Once you have created this new RFX_NewDouble() function, you need to replace the call to RFX_Double() in your CRecordset's DoFieldExchange() function with RFX_NewDouble().
MORE INFORMATIONBeginning with Visual C++ for Windows version 1.51 and Visual C++ 32-bit Edition version 2.0, the definitions of AFX_RFX_SINGLE_PSEUDO_NULL and AFX_RFX_DOUBLE_PSEUDO_NULL use a value of -9.123e19 instead of -1.0.
|
Additional reference words: 1.50 2.50 ODBC no32bit noupdate
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |