daoview.cpp 18 KB

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