home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / dbview.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  16KB  |  659 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_DB_SEG
  14. #pragma code_seg(AFX_DB_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25.  
  26. BEGIN_MESSAGE_MAP(CRecordView, CFormView)
  27.     //{{AFX_MSG_MAP(CRecordView)
  28.         // NOTE - the ClassWizard will add and remove mapping macros here.
  29.     //}}AFX_MSG_MAP
  30.     ON_COMMAND_EX(ID_RECORD_FIRST, OnMove)
  31.     ON_UPDATE_COMMAND_UI(ID_RECORD_FIRST, OnUpdateRecordFirst)
  32.     ON_COMMAND_EX(ID_RECORD_PREV, OnMove)
  33.     ON_UPDATE_COMMAND_UI(ID_RECORD_PREV, OnUpdateRecordPrev)
  34.     ON_COMMAND_EX(ID_RECORD_NEXT, OnMove)
  35.     ON_UPDATE_COMMAND_UI(ID_RECORD_NEXT, OnUpdateRecordNext)
  36.     ON_COMMAND_EX(ID_RECORD_LAST, OnMove)
  37.     ON_UPDATE_COMMAND_UI(ID_RECORD_LAST, OnUpdateRecordLast)
  38. END_MESSAGE_MAP()
  39.  
  40.  
  41. CRecordView::CRecordView(LPCTSTR lpszTemplateName)
  42.     : CFormView(lpszTemplateName)
  43. {
  44. }
  45.  
  46. CRecordView::CRecordView(UINT nIDTemplate)
  47.     : CFormView(nIDTemplate)
  48. {
  49. }
  50.  
  51. CRecordView::~CRecordView()
  52. {
  53. }
  54.  
  55. void CRecordView::OnInitialUpdate()
  56. {
  57.     CRecordset* pRecordset = OnGetRecordset();
  58.     // recordset must be allocated already
  59.     ASSERT(pRecordset != NULL);
  60.  
  61.     if (!pRecordset->IsOpen())
  62.     {
  63.         CWaitCursor wait;
  64.         pRecordset->Open();
  65.     }
  66.  
  67.     CFormView::OnInitialUpdate();
  68. }
  69.  
  70. BOOL CRecordView::IsOnFirstRecord()
  71. {
  72.     ASSERT_VALID(this);
  73.     CRecordsetStatus status;
  74.     OnGetRecordset()->GetStatus(status);
  75.     return status.m_lCurrentRecord == 0;
  76. }
  77.  
  78. BOOL CRecordView::IsOnLastRecord()
  79. {
  80.     ASSERT_VALID(this);
  81.     CRecordset* pRecordset = OnGetRecordset();
  82.     CRecordsetStatus status;
  83.     pRecordset->GetStatus(status);
  84.     if (!status.m_bRecordCountFinal)
  85.         return FALSE;
  86.     return ((status.m_lCurrentRecord+1 == pRecordset->GetRecordCount()));
  87. }
  88.  
  89. BOOL CRecordView::OnMove(UINT nIDMoveCommand)
  90. {
  91.     CRecordset* pSet = OnGetRecordset();
  92.     if (pSet->CanUpdate() && !pSet->IsDeleted())
  93.     {
  94.         pSet->Edit();
  95.         if (!UpdateData())
  96.             return TRUE;
  97.  
  98.         pSet->Update();
  99.     }
  100.  
  101.     switch (nIDMoveCommand)
  102.     {
  103.         case ID_RECORD_PREV:
  104.             pSet->MovePrev();
  105.             if (!pSet->IsBOF())
  106.                 break;
  107.  
  108.         case ID_RECORD_FIRST:
  109.             pSet->MoveFirst();
  110.             break;
  111.  
  112.         case ID_RECORD_NEXT:
  113.             pSet->MoveNext();
  114.             if (!pSet->IsEOF())
  115.                 break;
  116.             if (!pSet->CanScroll())
  117.             {
  118.                 // clear out screen since we're sitting on EOF
  119.                 pSet->SetFieldNull(NULL);
  120.                 break;
  121.             }
  122.  
  123.         case ID_RECORD_LAST:
  124.             pSet->MoveLast();
  125.             break;
  126.  
  127.         default:
  128.             // Unexpected case value
  129.             ASSERT(FALSE);
  130.     }
  131.  
  132.     // Show results of move operation
  133.     UpdateData(FALSE);
  134.     return TRUE;
  135. }
  136.  
  137. void CRecordView::OnUpdateRecordFirst(CCmdUI* pCmdUI)
  138. {
  139.     CRecordset* prs = OnGetRecordset();
  140.  
  141.     // enable if opened, can scroll backwards,
  142.     pCmdUI->Enable(prs->IsOpen() && prs->CanScroll() &&
  143.         // >= 1 records present and not already on first record
  144.         !(prs->IsEOF() && prs->IsBOF()) && !IsOnFirstRecord());
  145. }
  146.  
  147. void CRecordView::OnUpdateRecordPrev(CCmdUI* pCmdUI)
  148. {
  149.     CRecordView::OnUpdateRecordFirst(pCmdUI);
  150. }
  151.  
  152. void CRecordView::OnUpdateRecordNext(CCmdUI* pCmdUI)
  153. {
  154.     CRecordset* prs = OnGetRecordset();
  155.  
  156.     // enable if opened and >= 1 records present
  157.     pCmdUI->Enable(prs->IsOpen() && !(prs->IsEOF() && prs->IsBOF())
  158.         // and not already on last record
  159.         && !IsOnLastRecord());
  160. }
  161.  
  162. void CRecordView::OnUpdateRecordLast(CCmdUI* pCmdUI)
  163. {
  164.     CRecordset* prs = OnGetRecordset();
  165.  
  166.     // enable if opened, can scroll,
  167.     pCmdUI->Enable(prs->IsOpen() && prs->CanScroll() &&
  168.         // >= 1 records present and not already on last record
  169.         !(prs->IsEOF() && prs->IsBOF()) && !IsOnLastRecord());
  170. }
  171.  
  172.  
  173.  
  174. /////////////////////////////////////////////////////////////////////////////
  175. // DDX Cover functions for use with fields of a recordset
  176.  
  177. /////////////////////////////////////////////////////////////////////////////
  178. // Simple field formatting to text item
  179.  
  180. BOOL AFXAPI AfxFieldText(CDataExchange* pDX, int nIDC, void* pv,
  181.     CRecordset* pRecordset)
  182. {
  183.     ASSERT_VALID(pRecordset);
  184.  
  185.     HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  186.     TCHAR szT[2];
  187.     if (pDX->m_bSaveAndValidate)
  188.     {
  189.         ::GetWindowText(hWndCtrl, szT, _countof(szT));
  190.         if (szT[0] == '\0')
  191.         {
  192.             if (pRecordset->IsFieldNullable(pv))
  193.             {
  194.                 pRecordset->SetFieldNull(pv);
  195.                 return TRUE;
  196.             }
  197.         }
  198.         else
  199.             pRecordset->SetFieldNull(pv, FALSE);
  200.     }
  201.     else
  202.     {
  203.         if (!pRecordset->IsOpen() || pRecordset->IsFieldNull(pv))
  204.         {
  205.             szT[0] = '\0';
  206.             AfxSetWindowText(hWndCtrl, szT);
  207.             return TRUE;
  208.         }
  209.         else if (pRecordset->IsDeleted())
  210.         {
  211.             CString strDeleted(MAKEINTRESOURCE(AFX_IDS_DELETED));
  212.             AfxSetWindowText(hWndCtrl, strDeleted);
  213.             return TRUE;
  214.         }
  215.     }
  216.     return FALSE;
  217. }
  218.  
  219. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, int& value,
  220.     CRecordset* pRecordset)
  221. {
  222.     if (!AfxFieldText(pDX, nIDC, &value, pRecordset))
  223.         DDX_Text(pDX, nIDC, value);
  224. }
  225.  
  226. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, BYTE& value,
  227.     CRecordset* pRecordset)
  228. {
  229.     if (!AfxFieldText(pDX, nIDC, &value, pRecordset))
  230.         DDX_Text(pDX, nIDC, value);
  231. }
  232.  
  233. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, UINT& value,
  234.     CRecordset* pRecordset)
  235. {
  236.     if (!AfxFieldText(pDX, nIDC, &value, pRecordset))
  237.         DDX_Text(pDX, nIDC, value);
  238. }
  239.  
  240. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, long& value,
  241.     CRecordset* pRecordset)
  242. {
  243.     if (!AfxFieldText(pDX, nIDC, &value, pRecordset))
  244.         DDX_Text(pDX, nIDC, value);
  245. }
  246.  
  247. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, DWORD& value,
  248.     CRecordset* pRecordset)
  249. {
  250.     if (!AfxFieldText(pDX, nIDC, &value, pRecordset))
  251.         DDX_Text(pDX, nIDC, value);
  252. }
  253.  
  254. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, CString& value,
  255.     CRecordset* pRecordset)
  256. {
  257.     ASSERT_VALID(pRecordset);
  258.     HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  259.     if (pDX->m_bSaveAndValidate)
  260.     {
  261.         // check if length is too long (this is complicated by Windows NT/J)
  262.         int nLen = ::GetWindowTextLength(hWndCtrl);
  263.         if (nLen > value.GetAllocLength())
  264.         {
  265.             if (!_afxDBCS)
  266.                 AfxFailMaxChars(pDX, value.GetAllocLength());
  267.             CString strTemp;
  268.             ::GetWindowText(hWndCtrl, strTemp.GetBuffer(nLen), nLen+1);
  269.             strTemp.ReleaseBuffer();
  270.             nLen = strTemp.GetLength();
  271.             if (nLen > value.GetAllocLength())
  272.                 AfxFailMaxChars(pDX, value.GetAllocLength());
  273.         }
  274.         // get known length
  275.         ::GetWindowText(hWndCtrl, value.GetBuffer(0), nLen+1);
  276.         value.ReleaseBuffer();
  277.         if (nLen == 0)
  278.         {
  279.             if (pRecordset->IsFieldNullable(&value))
  280.                 pRecordset->SetFieldNull(&value, TRUE);
  281.         }
  282.         else
  283.         {
  284.             pRecordset->SetFieldNull(&value, FALSE);
  285.         }
  286.     }
  287.     else if (pRecordset->IsDeleted())
  288.     {
  289.         CString strDeleted(MAKEINTRESOURCE(AFX_IDS_DELETED));
  290.         AfxSetWindowText(hWndCtrl, strDeleted);
  291.     }
  292.     else
  293.     {
  294.         AfxSetWindowText(hWndCtrl, value);
  295.     }
  296. }
  297.  
  298. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, LPTSTR pstrValue,
  299.     int nMaxLength, CRecordset* pRecordset)
  300. {
  301.     ASSERT_VALID(pRecordset);
  302.     HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  303.     if (pDX->m_bSaveAndValidate)
  304.     {
  305.         int nLen = ::GetWindowText(hWndCtrl, pstrValue, nMaxLength);
  306.  
  307.         if (nLen == 0)
  308.         {
  309.             if (pRecordset->IsFieldNullable(pstrValue))
  310.                 pRecordset->SetFieldNull(pstrValue, TRUE);
  311.         }
  312.         else
  313.             pRecordset->SetFieldNull(pstrValue, FALSE);
  314.     }
  315.     else if (pRecordset->IsDeleted())
  316.     {
  317.         CString strDeleted(MAKEINTRESOURCE(AFX_IDS_DELETED));
  318.         AfxSetWindowText(hWndCtrl, strDeleted);
  319.     }
  320.     else
  321.         AfxSetWindowText(hWndCtrl, pstrValue);
  322. }
  323.  
  324. void AFXAPI DDX_FieldLBString(CDataExchange* pDX, int nIDC, CString& value,
  325.     CRecordset* pRecordset)
  326. {
  327.     ASSERT_VALID(pRecordset);
  328.  
  329.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  330.     if (pDX->m_bSaveAndValidate)
  331.     {
  332.         int nIndex = (int)::SendMessage(hWndCtrl, LB_GETCURSEL, 0, 0L);
  333.         if (nIndex != -1)
  334.         {
  335.             int nLen = (int)::SendMessage(hWndCtrl, LB_GETTEXTLEN, nIndex, 0L);
  336.             if (nLen > value.GetAllocLength())
  337.                 AfxFailMaxChars(pDX, value.GetAllocLength());
  338.             ::SendMessage(hWndCtrl, LB_GETTEXT, nIndex,
  339.                     (LPARAM)(LPSTR)value.GetBuffer(0));
  340.             if (nLen == 0)
  341.             {
  342.                 if (pRecordset->IsFieldNullable(&value))
  343.                     pRecordset->SetFieldNull(&value, TRUE);
  344.             }
  345.             else
  346.             {
  347.                 pRecordset->SetFieldNull(&value, FALSE);
  348.             }
  349.             value.ReleaseBuffer();
  350.         }
  351.         else
  352.         {
  353.             // no selection
  354.             value.GetBufferSetLength(0);
  355.             if (pRecordset->IsFieldNullable(&value))
  356.                 pRecordset->SetFieldNull(&value);
  357.         }
  358.     }
  359.     else
  360.     {
  361.         if (!pRecordset->IsOpen() || pRecordset->IsFieldNull(&value))
  362.         {
  363.             SendMessage(hWndCtrl, LB_SETCURSEL, (WPARAM)-1, 0L);
  364.         }
  365.         else
  366.         {
  367.             // set current selection based on data string
  368.             if (::SendMessage(hWndCtrl, LB_SELECTSTRING, (WPARAM)-1,
  369.               (LPARAM)(LPCTSTR)value) == LB_ERR)
  370.             {
  371.                 // no selection match
  372.                 TRACE0("Warning: no listbox item selected.\n");
  373.             }
  374.         }
  375.     }
  376. }
  377.  
  378. void AFXAPI DDX_FieldLBStringExact(CDataExchange* pDX, int nIDC, CString& value,
  379.     CRecordset* pRecordset)
  380. {
  381.     ASSERT_VALID(pRecordset);
  382.  
  383.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  384.     if (pDX->m_bSaveAndValidate)
  385.     {
  386.         DDX_FieldLBString(pDX, nIDC, value, pRecordset);
  387.     }
  388.     else
  389.     {
  390.         if (!pRecordset->IsOpen() || pRecordset->IsFieldNull(&value))
  391.         {
  392.             SendMessage(hWndCtrl, LB_SETCURSEL, (WPARAM)-1, 0L);
  393.         }
  394.         else
  395.         {
  396.             // set current selection based on data string
  397.             int i = (int)::SendMessage(hWndCtrl, LB_FINDSTRINGEXACT, (WPARAM)-1,
  398.               (LPARAM)(LPCTSTR)value);
  399.             if (i < 0)
  400.             {
  401.                 // no selection match
  402.                 TRACE0("Warning: no listbox item selected.\n");
  403.             }
  404.             else
  405.             {
  406.                 // select it
  407.                 SendMessage(hWndCtrl, LB_SETCURSEL, i, 0L);
  408.             }
  409.         }
  410.     }
  411. }
  412.  
  413. void AFXAPI DDX_FieldLBIndex(CDataExchange* pDX, int nIDC, int& index,
  414.     CRecordset* pRecordset)
  415. {
  416.     ASSERT_VALID(pRecordset);
  417.  
  418.     if (!pDX->m_bSaveAndValidate &&
  419.         (!pRecordset->IsOpen() || pRecordset->IsFieldNull(&index)))
  420.     {
  421.         int nIndex = 0;
  422.         DDX_LBIndex(pDX, nIDC, nIndex);
  423.     }
  424.     else
  425.         DDX_LBIndex(pDX, nIDC, index);
  426. }
  427.  
  428. void AFXAPI DDX_FieldCBString(CDataExchange* pDX, int nIDC, CString& value,
  429.     CRecordset* pRecordset)
  430. {
  431.     ASSERT_VALID(pRecordset);
  432.  
  433.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  434.     if (pDX->m_bSaveAndValidate)
  435.     {
  436.         // just get current edit item text (or drop list static)
  437.         int nLen = ::GetWindowTextLength(hWndCtrl);
  438.         if (nLen != -1)
  439.         {
  440.             CString strTemp;
  441.             ::GetWindowText(hWndCtrl, strTemp.GetBuffer(nLen), nLen+1);
  442.             strTemp.ReleaseBuffer();
  443.             nLen = strTemp.GetLength();
  444.             if (nLen > value.GetAllocLength())
  445.                 AfxFailMaxChars(pDX, value.GetAllocLength());
  446.             // get known length
  447.             ::GetWindowText(hWndCtrl, value.GetBuffer(0), nLen+1);
  448.         }
  449.         else
  450.         {
  451.             // for drop lists GetWindowTextLength does not work - assume
  452.             //  preallocated length
  453.             ::GetWindowText(hWndCtrl, value.GetBuffer(0), value.GetAllocLength()+1);
  454.         }
  455.         value.ReleaseBuffer();
  456.         if (value.GetLength() == 0)
  457.         {
  458.             if (pRecordset->IsFieldNullable(&value))
  459.                 pRecordset->SetFieldNull(&value, TRUE);
  460.         }
  461.         else
  462.         {
  463.             pRecordset->SetFieldNull(&value, FALSE);
  464.         }
  465.     }
  466.     else
  467.     {
  468.         if (!pRecordset->IsOpen() || pRecordset->IsFieldNull(&value))
  469.         {
  470.             SendMessage(hWndCtrl, CB_SETCURSEL, (WPARAM)-1, 0L);
  471.         }
  472.         else
  473.         {
  474.             // set current selection based on model string
  475.             if (::SendMessage(hWndCtrl, CB_SELECTSTRING, (WPARAM)-1,
  476.                 (LPARAM)(LPCTSTR)value) == CB_ERR)
  477.             {
  478.                 // just set the edit text (will be ignored if DROPDOWNLIST)
  479.                 AfxSetWindowText(hWndCtrl, value);
  480.             }
  481.         }
  482.     }
  483. }
  484.  
  485. void AFXAPI DDX_FieldCBStringExact(CDataExchange* pDX, int nIDC, CString& value,
  486.     CRecordset* pRecordset)
  487. {
  488.     ASSERT_VALID(pRecordset);
  489.  
  490.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  491.     if (pDX->m_bSaveAndValidate)
  492.     {
  493.         DDX_FieldCBString(pDX, nIDC, value, pRecordset);
  494.     }
  495.     else
  496.     {
  497.         if (!pRecordset->IsOpen() || pRecordset->IsFieldNull(&value))
  498.         {
  499.             SendMessage(hWndCtrl, CB_SETCURSEL, (WPARAM)-1, 0L);
  500.         }
  501.         else
  502.         {
  503.             // set current selection based on data string
  504.             int i = (int)::SendMessage(hWndCtrl, CB_FINDSTRINGEXACT, (WPARAM)-1,
  505.               (LPARAM)(LPCTSTR)value);
  506.             if (i < 0)
  507.             {
  508.                 // no selection match
  509.                 TRACE0("Warning: no combobox item selected.\n");
  510.             }
  511.             else
  512.             {
  513.                 // select it
  514.                 SendMessage(hWndCtrl, CB_SETCURSEL, i, 0L);
  515.             }
  516.         }
  517.     }
  518. }
  519.  
  520. void AFXAPI DDX_FieldCBIndex(CDataExchange* pDX, int nIDC, int& index,
  521.     CRecordset* pRecordset)
  522. {
  523.     ASSERT_VALID(pRecordset);
  524.  
  525.     if (!pDX->m_bSaveAndValidate &&
  526.         (!pRecordset->IsOpen() || pRecordset->IsFieldNull(&index)))
  527.     {
  528.         int nIndex = 0;
  529.         DDX_CBIndex(pDX, nIDC, nIndex);
  530.     }
  531.     else
  532.         DDX_CBIndex(pDX, nIDC, index);
  533. }
  534.  
  535. void AFXAPI DDX_FieldScroll(CDataExchange* pDX, int nIDC, int& value,
  536.     CRecordset* pRecordset)
  537. {
  538.     ASSERT_VALID(pRecordset);
  539.  
  540.     if (!pDX->m_bSaveAndValidate &&
  541.         (!pRecordset->IsOpen() || pRecordset->IsFieldNull(&value)))
  542.     {
  543.         int nValue = 0;
  544.         DDX_Scroll(pDX, nIDC, nValue);
  545.     }
  546.     else
  547.         DDX_Scroll(pDX, nIDC, value);
  548. }
  549.  
  550. /////////////////////////////////////////////////////////////////////////////
  551. // Data exchange for special controls
  552.  
  553. void AFXAPI DDX_FieldCheck(CDataExchange* pDX, int nIDC, int& value, CRecordset* pRecordset)
  554. {
  555.     ASSERT_VALID(pRecordset);
  556.  
  557.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  558.     if (pDX->m_bSaveAndValidate)
  559.     {
  560.         value = (int)::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L);
  561.         ASSERT(value >= 0 && value <= 2);
  562.         if (value == 2)
  563.         {
  564.             if (pRecordset->IsFieldNullable(&value))
  565.                 pRecordset->SetFieldNull(&value);
  566.             else
  567.             {
  568.                 TRACE0("Warning: checkbox value indeterminate and field can't be NULL.\n");
  569.                 // Default to unchecked
  570.                 value = 0;
  571.             }
  572.         }
  573.     }
  574.     else
  575.     {
  576.         if (!pRecordset->IsOpen() || pRecordset->IsFieldNull(&value))
  577.         {
  578.             int style = ((int)::GetWindowLong(hWndCtrl, GWL_STYLE) & 0xf);
  579.             if ((style == BS_3STATE || style == BS_AUTO3STATE))
  580.                 value = 2;
  581.             else
  582.             {
  583.                 TRACE0("Warning: field NULL and checkbox can't be indeterminate.\n");
  584.                 // Default to unchecked
  585.                 value = 0;
  586.             }
  587.         }
  588.         if (value < 0 || value > 2)
  589.         {
  590.             value = 0;      // default to off
  591.             TRACE1("Warning: dialog data checkbox value (%d) out of range.\n",
  592.                 value);
  593.         }
  594.         ::SendMessage(hWndCtrl, BM_SETCHECK, (WPARAM)value, 0L);
  595.     }
  596. }
  597.  
  598. void AFXAPI DDX_FieldRadio(CDataExchange* pDX, int nIDC, int& value,
  599.     CRecordset* pRecordset)
  600. {
  601.     ASSERT_VALID(pRecordset);
  602.  
  603.     if (!pDX->m_bSaveAndValidate &&
  604.         (!pRecordset->IsOpen() || pRecordset->IsFieldNull(&value)))
  605.         value = -1;
  606.     DDX_Radio(pDX, nIDC, value);
  607.     if (pDX->m_bSaveAndValidate)
  608.     {
  609.         if (value == -1 && !pRecordset->IsFieldNullable(&value))
  610.         {
  611.             AfxFailRadio(pDX);
  612.         }
  613.         else
  614.         {
  615.             pRecordset->SetFieldNull(&value, (value == -1));
  616.         }
  617.     }
  618. }
  619.  
  620. /////////////////////////////////////////////////////////////////////////////
  621.  
  622. #ifdef _DEBUG
  623. void CRecordView::AssertValid() const
  624. {
  625.     CFormView::AssertValid();
  626. }
  627.  
  628. void CRecordView::Dump(CDumpContext& dc) const
  629. {
  630.     CFormView::Dump(dc);
  631.  
  632.     dc << "m_bOnFirstRecord = " << m_bOnFirstRecord;
  633.     dc << "\nm_bOnLastRecord = " << m_bOnLastRecord;
  634.  
  635.     dc << "\n";
  636. }
  637. #endif
  638.  
  639. //////////////////////////////////////////////////////////////////////////////
  640. // Inline function declarations expanded out-of-line
  641.  
  642. #ifndef _AFX_ENABLE_INLINES
  643.  
  644. static char _szAfxDbInl[] = "afxdb.inl";
  645. #undef THIS_FILE
  646. #define THIS_FILE _szAfxDbInl
  647. #define _AFXDBVIEW_INLINE
  648. #include "afxdb.inl"
  649.  
  650. #endif
  651.  
  652. #ifdef AFX_INIT_SEG
  653. #pragma code_seg(AFX_INIT_SEG)
  654. #endif
  655.  
  656. IMPLEMENT_DYNAMIC(CRecordView, CFormView)
  657.  
  658. /////////////////////////////////////////////////////////////////////////////
  659.