Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1074 lines
29 KiB

  1. /*******************************************************************************
  2. *
  3. * rowview.cpp
  4. *
  5. * implementation of the CRowView class and CRowViewHeaderBar class
  6. *
  7. * Modified from the Microsoft Foundation Classes C++ library.
  8. * Copyright (C) 1992 Microsoft Corporation
  9. * All rights reserved.
  10. *
  11. * additional copyright notice: Copyright 1995, Citrix Systems Inc.
  12. *
  13. * $Author: butchd $ Butch Davis
  14. *
  15. * $Log: N:\NT\PRIVATE\UTILS\CITRIX\WINUTILS\COMMON\VCS\ROWVIEW.CPP $
  16. *
  17. * Rev 1.1 18 Jul 1995 06:50:06 butchd
  18. * Scrolling fix for Windows95 / MFC 3.0
  19. *
  20. * Rev 1.0 01 Mar 1995 10:54:46 butchd
  21. * Initial revision.
  22. *
  23. * Rev 1.0 02 Aug 1994 18:18:30 butchd
  24. * (Initial revision: was duplicated in each app directory).
  25. *
  26. *******************************************************************************/
  27. /*
  28. * include files
  29. */
  30. #include "stdafx.h"
  31. #include <afxwin.h> // MFC core and standard components
  32. #include <afxext.h> // MFC extensions
  33. #include "rowview.h"
  34. #include "resource.h"
  35. #include <stdlib.h>
  36. #include <limits.h> // for INT_MAX
  37. #ifdef _DEBUG
  38. #undef THIS_FILE
  39. static char BASED_CODE THIS_FILE[] = __FILE__;
  40. #endif
  41. ////////////////////////////////////////////////////////////////////////////////
  42. // CRowViewHeaderBar class implementation / construction, destruction
  43. IMPLEMENT_DYNAMIC(CRowViewHeaderBar, CStatusBar)
  44. CRowViewHeaderBar::CRowViewHeaderBar()
  45. {
  46. }
  47. CRowViewHeaderBar::~CRowViewHeaderBar()
  48. {
  49. }
  50. /*******************************************************************************
  51. *
  52. * DoPaint - CRowViewHeaderBar member function: CStatusBar class override
  53. *
  54. * Draw the view's header bar.
  55. *
  56. * ENTRY:
  57. *
  58. * pDC (input)
  59. * Points to the current CDC device-context object for drawing
  60. * the header bar.
  61. *
  62. * NOTE: The view's
  63. * DoPaint function.
  64. *
  65. ******************************************************************************/
  66. void
  67. CRowViewHeaderBar::DoPaint( CDC* pDC )
  68. {
  69. /*
  70. * Perform the CControlBar base class' DoPaint first.
  71. */
  72. CControlBar::DoPaint(pDC);
  73. /*
  74. * Default the y position for drawing the header bar to the m_cyTopBorder
  75. * member variable setting and call the view's OnDrawHeaderBar() member
  76. * function to perform the desired header bar drawing.
  77. */
  78. int y = m_cyTopBorder;
  79. ((CRowView *)m_pView)->OnDrawHeaderBar( pDC, y );
  80. } // end CRowViewHeaderBar::DoPaint
  81. ////////////////////////////////////////////////////////////////////////////////
  82. // CRowViewHeaderBar message map
  83. BEGIN_MESSAGE_MAP(CRowViewHeaderBar, CStatusBar)
  84. //{{AFX_MSG_MAP(CRowViewHeaderBar)
  85. #if _MFC_VER >= 0x400
  86. ON_WM_PAINT()
  87. #endif
  88. //}}AFX_MSG_MAP
  89. END_MESSAGE_MAP()
  90. ////////////////////////////////////////////////////////////////////////////////
  91. // CRowViewHeaderBar commands
  92. ////////////////////////////////////////////////////////////////////////////////
  93. // CRowView implementation / construction, destruction
  94. IMPLEMENT_DYNAMIC(CRowView, CScrollView)
  95. CRowView::CRowView()
  96. {
  97. m_nPrevSelectedRow = 0;
  98. m_bThumbTrack = TRUE; // default to handle SB_THUMBTRACK messages.
  99. m_pHeaderBar = NULL; // default to no header bar
  100. }
  101. CRowView::~CRowView()
  102. {
  103. }
  104. int
  105. CRowView::OnCreate( LPCREATESTRUCT lpCreateStruct )
  106. {
  107. if ( CScrollView::OnCreate(lpCreateStruct) == -1 )
  108. return -1;
  109. /*
  110. * If the derived class has constructed a header bar, call CreateHeaderBar
  111. * to create the header-bar window and initialize.
  112. */
  113. if ( m_pHeaderBar )
  114. if ( !CreateHeaderBar() )
  115. return( -1 );
  116. return( 0 );
  117. } // end CRowView::OnCreate
  118. BOOL
  119. CRowView::CreateHeaderBar()
  120. {
  121. /*
  122. * Invoke the CRowViewHeaderBar's Create member function (CStatusBar defined)
  123. * to create the header bar, which will be hooked to this document/view's
  124. * parent window. Set the header bar's m_pView pointer to this view.
  125. */
  126. if ( !m_pHeaderBar->Create( GetParent(), WS_CHILD | WS_VISIBLE | CBRS_TOP,
  127. IDW_HEADER_BAR ) ) {
  128. return ( FALSE );
  129. } else {
  130. m_pHeaderBar->m_pView = this;
  131. return ( TRUE );
  132. }
  133. } // end CRowView::CreateHeaderBar
  134. ////////////////////////////////////////////////////////////////////////////////
  135. // CRowView class optional derived class override
  136. /*******************************************************************************
  137. *
  138. * ResetHeaderBar - CRowView member function: optional derived class override
  139. *
  140. * Reset the header bar width and height based on the view's total width
  141. * and view's row height. Will also instruct the parent frame to
  142. * recalculate it's layout based on the new header bar metrics.
  143. *
  144. * NOTE: A derived class will typically override this member function to
  145. * set the desired header bar font, then call this function.
  146. *
  147. ******************************************************************************/
  148. void
  149. CRowView::ResetHeaderBar()
  150. {
  151. /*
  152. * If no header bar was created, return.
  153. */
  154. if ( !m_pHeaderBar )
  155. return;
  156. /*
  157. * Set the header bar's width and height.
  158. */
  159. m_pHeaderBar->SendMessage( WM_SIZE, 0, MAKELONG(m_nRowWidth, m_nRowHeight) );
  160. /*
  161. * Recalculate parent frame's layout with new header bar.
  162. */
  163. ((CFrameWnd *)m_pHeaderBar->GetParent())->RecalcLayout();
  164. } // end CRowView::ResetHeaderBar
  165. ////////////////////////////////////////////////////////////////////////////////
  166. // CRowView class override member functions
  167. /*******************************************************************************
  168. *
  169. * OnInitialUpdate - CRowView member function: CView class override
  170. *
  171. * Called before the view is initially displayed.
  172. *
  173. * (Refer to the MFC CView::OnInitialUpdate documentation)
  174. *
  175. ******************************************************************************/
  176. void
  177. CRowView::OnInitialUpdate()
  178. {
  179. m_nPrevRowCount = GetRowCount();
  180. m_nPrevSelectedRow = GetActiveRow();
  181. } // end CRowView::OnInitialUpdate
  182. /*******************************************************************************
  183. *
  184. * OnPrepareDC - CRowView member function: CView class override
  185. *
  186. * Prepare the DC for screen or printer output.
  187. *
  188. * (Refer to the MFC CView::OnPrepareDC documentation)
  189. *
  190. ******************************************************************************/
  191. void
  192. CRowView::OnPrepareDC( CDC* pDC,
  193. CPrintInfo* pInfo )
  194. {
  195. /*
  196. * The size of text that is displayed, printed or previewed changes
  197. * depending on the DC. We explicitly call OnPrepareDC() to prepare
  198. * CClientDC objects used for calculating text positions and to
  199. * prepare the text metric member variables of the CRowView object.
  200. * The framework also calls OnPrepareDC() before passing the DC to
  201. * OnDraw().
  202. */
  203. CScrollView::OnPrepareDC( pDC, pInfo );
  204. CalculateRowMetrics( pDC );
  205. } // end CRowView::OnPrepareDC
  206. /*******************************************************************************
  207. *
  208. * OnDraw - CRowView member function: CView class override
  209. *
  210. * Draw on the view as needed.
  211. *
  212. * (Refer to the MFC CView::OnDraw documentation)
  213. *
  214. ******************************************************************************/
  215. void
  216. CRowView::OnDraw( CDC* pDC )
  217. {
  218. /*
  219. * If there are no rows to draw, don't do anything.
  220. */
  221. if ( GetRowCount() == 0 )
  222. return;
  223. /*
  224. * The window has been invalidated and needs to be repainted;
  225. * or a page needs to be printed (or previewed).
  226. * First, determine the range of rows that need to be displayed or
  227. * printed by fetching the invalidated region.
  228. */
  229. int nFirstRow, nLastRow;
  230. CRect rectClip;
  231. pDC->GetClipBox( &rectClip );
  232. RectLPtoRowRange( rectClip, nFirstRow, nLastRow, TRUE );
  233. /*
  234. * Draw each row in the invalidated region of the window,
  235. * or on the printed (previewed) page.
  236. */
  237. int nActiveRow = GetActiveRow();
  238. int nRow, y;
  239. int nLastViewableRow = LastViewableRow();
  240. for ( nRow = nFirstRow, y = m_nRowHeight * nFirstRow;
  241. nRow <= nLastRow;
  242. nRow++, y += m_nRowHeight ) {
  243. if ( nRow > nLastViewableRow ) {
  244. CString strWarning;
  245. strWarning.LoadString( IDS_TOO_MANY_ROWS );
  246. pDC->TextOut( 0, y, strWarning );
  247. break;
  248. }
  249. OnDrawRow( pDC, nRow, y, nRow == nActiveRow );
  250. }
  251. } // end CRowView::OnDraw
  252. /*******************************************************************************
  253. *
  254. * OnPreparePrinting - CRowView member function: CView class override
  255. *
  256. * Prepare the view for printing or print preview.
  257. *
  258. * (Refer to the MFC CView::OnPreparePrinting documentation)
  259. *
  260. ******************************************************************************/
  261. BOOL
  262. CRowView::OnPreparePrinting( CPrintInfo* pInfo )
  263. {
  264. return ( DoPreparePrinting( pInfo ) );
  265. } // end CRowView::OnPreparePrinting
  266. /*******************************************************************************
  267. *
  268. * OnBeginPrinting - CRowView member function: CView class override
  269. *
  270. * Setup before beginning to print.
  271. *
  272. * (Refer to the MFC CView::OnBeginPrinting documentation)
  273. *
  274. ******************************************************************************/
  275. void
  276. CRowView::OnBeginPrinting( CDC* pDC,
  277. CPrintInfo* pInfo )
  278. {
  279. /*
  280. * OnBeginPrinting() is called after the user has committed to
  281. * printing by OK'ing the Print dialog, and after the framework
  282. * has created a CDC object for the printer or the preview view.
  283. */
  284. /*
  285. * This is the right opportunity to set up the page range.
  286. * Given the CDC object, we can determine how many rows will
  287. * fit on a page, so we can in turn determine how many printed
  288. * pages represent the entire document.
  289. */
  290. int nPageHeight = pDC->GetDeviceCaps(VERTRES);
  291. CalculateRowMetrics(pDC);
  292. m_nRowsPerPrintedPage = nPageHeight / m_nRowHeight;
  293. int nPrintableRowCount = LastViewableRow() + 1;
  294. if ( GetRowCount() < nPrintableRowCount )
  295. nPrintableRowCount = GetRowCount();
  296. pInfo->SetMaxPage( (nPrintableRowCount + m_nRowsPerPrintedPage - 1)
  297. / m_nRowsPerPrintedPage );
  298. /*
  299. * Start previewing at page #1.
  300. */
  301. pInfo->m_nCurPage = 1;
  302. } // end CRowView::OnBeginPrinting
  303. /*******************************************************************************
  304. *
  305. * OnPrint - CRowView member function: CView class override
  306. *
  307. * Print or preview a page of the view's document.
  308. *
  309. * (Refer to the MFC CView::OnPrint documentation)
  310. *
  311. ******************************************************************************/
  312. void
  313. CRowView::OnPrint( CDC* pDC,
  314. CPrintInfo* pInfo )
  315. {
  316. /*
  317. * Print the rows for the current page.
  318. */
  319. int yTopOfPage = (pInfo->m_nCurPage -1) * m_nRowsPerPrintedPage
  320. * m_nRowHeight;
  321. /*
  322. * Orient the viewport so that the first row to be printed
  323. * has a viewport coordinate of (0,0).
  324. */
  325. pDC->SetViewportOrg(0, -yTopOfPage);
  326. /*
  327. * Draw as many rows as will fit on the printed page.
  328. * Clip the printed page so that there is no partially shown
  329. * row at the bottom of the page (the same row which will be fully
  330. * shown at the top of the next page).
  331. */
  332. int nPageWidth = pDC->GetDeviceCaps(HORZRES);
  333. CRect rectClip = CRect(0, yTopOfPage, nPageWidth,
  334. yTopOfPage + m_nRowsPerPrintedPage * m_nRowHeight);
  335. pDC->IntersectClipRect(&rectClip);
  336. OnDraw(pDC);
  337. } // end CRowView::OnPrint
  338. /////////////////////////////////////////////////////////////////////////////
  339. // CRowView operations
  340. /*******************************************************************************
  341. *
  342. * UpdateRow - CRowView member function: operation
  343. *
  344. * Handle scrolling and invalidation of the specified row, in preparation
  345. * for the OnDraw function.
  346. *
  347. * ENTRY:
  348. *
  349. * nInvalidRow (input)
  350. * Row to update.
  351. *
  352. * EXIT:
  353. *
  354. ******************************************************************************/
  355. void
  356. CRowView::UpdateRow( int nInvalidRow )
  357. {
  358. int nRowCount = GetRowCount();
  359. /*
  360. * If the number of rows has changed, then adjust the scrolling range.
  361. */
  362. if (nRowCount != m_nPrevRowCount)
  363. {
  364. UpdateScrollSizes();
  365. m_nPrevRowCount = nRowCount;
  366. }
  367. /*
  368. * When the currently selected row changes:
  369. * scroll the view so that the newly selected row is visible, and
  370. * ask the derived class to repaint the selected and previously
  371. * selected rows.
  372. */
  373. CClientDC dc(this);
  374. OnPrepareDC(&dc);
  375. /*
  376. * Determine the range of the rows that are currently fully visible
  377. * in the window. We want to do discrete scrolling by so that
  378. * the next or previous row is always fully visible.
  379. */
  380. int nFirstRow, nLastRow;
  381. CRect rectClient;
  382. GetClientRect( &rectClient );
  383. dc.DPtoLP( &rectClient );
  384. RectLPtoRowRange( rectClient, nFirstRow, nLastRow, FALSE );
  385. /*
  386. * If necessary, scroll the window so the newly selected row is
  387. * visible. MODIFICATION: set the pt.x to the left visible x point
  388. * in the row (not 0), so that the ScrollToDevicePosition() call won't
  389. * automatically perform a horizontal scroll (very annoying to user).
  390. */
  391. POINT pt;
  392. pt.x = rectClient.left;
  393. BOOL bNeedToScroll = TRUE;
  394. if ( nInvalidRow < nFirstRow ) {
  395. /*
  396. * The newly selected row is above those currently visible
  397. * in the window. Scroll so the newly selected row is at the
  398. * very top of the window. The last row in the window might
  399. * be only partially visible.
  400. */
  401. pt.y = RowToYPos(nInvalidRow);
  402. } else if ( nInvalidRow > nLastRow ) {
  403. /*
  404. * The newly selected row is below those currently visible
  405. * in the window. Scroll so the newly selected row is at the
  406. * very bottom of the window. The first row in the window might
  407. * be only partially visible.
  408. */
  409. pt.y = max( 0, RowToYPos(nInvalidRow+1) - rectClient.Height() );
  410. } else {
  411. bNeedToScroll = FALSE;
  412. }
  413. if ( bNeedToScroll ) {
  414. /*
  415. * Scrolling will cause the newly selected row to be
  416. * redrawn in the invalidated area of the window.
  417. */
  418. ScrollToDevicePosition(pt);
  419. /*
  420. * Need to prepare the DC again because ScrollToDevicePosition()
  421. * will have changed the viewport origin. The DC is used some
  422. * more below.
  423. */
  424. OnPrepareDC(&dc);
  425. }
  426. CRect rectInvalid = RowToWndRect( &dc, nInvalidRow );
  427. InvalidateRect( &rectInvalid );
  428. /*
  429. * Give the derived class an opportunity to repaint the
  430. * previously selected row, perhaps to un-highlight it.
  431. */
  432. int nSelectedRow = GetActiveRow();
  433. if (m_nPrevSelectedRow != nSelectedRow) {
  434. CRect rectOldSelection = RowToWndRect(&dc, m_nPrevSelectedRow);
  435. InvalidateRect(&rectOldSelection);
  436. m_nPrevSelectedRow = nSelectedRow;
  437. }
  438. } // end CRowView::UpdateRow
  439. /*******************************************************************************
  440. *
  441. * IsScrollingNeeded - CRowView member function: operation
  442. *
  443. * Determine if the client window of this view is small enough in a
  444. * HORIZONTAL or VERTICAL direction to require scrolling to see the
  445. * entire view. This function is mainly used to support the operation
  446. * of 'scrolling keys' (non-mouse generated scrolling commands).
  447. *
  448. * ENTRY:
  449. *
  450. * nBar (input)
  451. * SB_HORZ or SB_VERT: to indicate which scrolling direction to check.
  452. *
  453. * EXIT:
  454. *
  455. * TRUE if scrolling is needed in the specified direction.
  456. * FALSE if no scrolling is needed in the specified direction.
  457. *
  458. ******************************************************************************/
  459. BOOL
  460. CRowView::IsScrollingNeeded( int nBar )
  461. {
  462. CRect rectClient;
  463. CSize sizeTotal;
  464. GetClientRect( &rectClient );
  465. sizeTotal = GetTotalSize();
  466. if ( nBar == SB_HORZ ) {
  467. if ( sizeTotal.cx > rectClient.right )
  468. return ( TRUE );
  469. else
  470. return (FALSE );
  471. } else {
  472. if ( sizeTotal.cy > rectClient.bottom )
  473. return ( TRUE );
  474. else
  475. return (FALSE );
  476. }
  477. } // end CRowView::IsScrollingNeeded
  478. #ifndef MFC300
  479. /*******************************************************************************
  480. *
  481. * GetScrollLimit - CRowView member function: operation (MFC 2.x stub)
  482. *
  483. * MFC 3.0 provides a GetScrollLimit() member function that properly
  484. * handles Windows95 scrollbar controls if running on Windows95. This
  485. * stub is provided for
  486. *
  487. * ENTRY:
  488. * nBar (input)
  489. * SB_HORZ or SB_VERT: to indicate which scrolling direction to check.
  490. * EXIT:
  491. * Returns the nMax value from the standard Windows GetScrollLimit() API.
  492. * Also contains an ASSERT to check for nMin != 0.
  493. *
  494. ******************************************************************************/
  495. int
  496. CRowView::GetScrollLimit( int nBar )
  497. {
  498. int nMin, nMax;
  499. GetScrollRange(nBar, &nMin, &nMax);
  500. ASSERT(nMin == 0);
  501. return nMax;
  502. } // end CRowView::GetScrollLimit
  503. #endif
  504. void
  505. CRowView::CalculateRowMetrics( CDC* pDC )
  506. {
  507. GetRowWidthHeight( pDC, m_nRowWidth, m_nRowHeight );
  508. } // end CRowView::CalculateRowMetrics
  509. void
  510. CRowView::UpdateScrollSizes()
  511. {
  512. /*
  513. * UpdateScrollSizes() is called when it is necessary to adjust the
  514. * scrolling range or page/line sizes. There are two occassions
  515. * where this is necessary: (1) when a new row is effected (added,
  516. * deleted, or changed) -- see UpdateRow()-- and (2) when the window size
  517. * changes-- see OnSize().
  518. */
  519. CRect rectClient;
  520. GetClientRect( &rectClient );
  521. CClientDC dc( this );
  522. CalculateRowMetrics( &dc );
  523. /*
  524. * The vert scrolling range is the total display height of all
  525. * of the rows.
  526. */
  527. CSize sizeTotal( m_nRowWidth,
  528. m_nRowHeight * (min( GetRowCount(), LastViewableRow() )) );
  529. /*
  530. * The vertical per-page scrolling distance is equal to the
  531. * how many rows can be displayed in the current window, less
  532. * one row for paging overlap.
  533. */
  534. CSize sizePage( m_nRowWidth/5,
  535. max( m_nRowHeight,
  536. ((rectClient.bottom/m_nRowHeight)-1)*m_nRowHeight ) );
  537. /*
  538. * We'll also calculate the number of rows that the view should be scrolled
  539. * during PageUp / PageDown. This number will always be at least 1.
  540. */
  541. m_nPageScrollRows = (m_nPageScrollRows =
  542. ((rectClient.bottom / m_nRowHeight)-1)) >= 1 ?
  543. m_nPageScrollRows : 1;
  544. /*
  545. * The vertical per-line scrolling distance is equal to the
  546. * height of the row.
  547. */
  548. CSize sizeLine( m_nRowWidth/20, m_nRowHeight );
  549. SetScrollSizes( MM_TEXT, sizeTotal, sizePage, sizeLine );
  550. } // end CRowView::UpdateScrollSizes
  551. int
  552. CRowView::RowToYPos( int nRow )
  553. {
  554. return ( nRow * m_nRowHeight );
  555. } // end CRowView::RowToYPos
  556. CRect
  557. CRowView::RowToWndRect( CDC* pDC,
  558. int nRow )
  559. {
  560. /*
  561. * MODIFICATION: Set right end of returned rectangle to max of end of row,
  562. * or screen width. This will assure full update in case of horizontall
  563. * scrolling on very wide rows (> screen width).
  564. */
  565. int nHorzRes = pDC->GetDeviceCaps(HORZRES);
  566. CRect rect( 0, nRow * m_nRowHeight,
  567. max( m_nRowWidth, nHorzRes ), (nRow + 1) * m_nRowHeight );
  568. pDC->LPtoDP( &rect );
  569. return rect;
  570. } // end CRowView::RowToWndRect
  571. int
  572. CRowView::LastViewableRow()
  573. {
  574. return ( (INT_MAX / m_nRowHeight) - 1 );
  575. } // end CRowView::LastViewableRow
  576. void
  577. CRowView::RectLPtoRowRange( const CRect& rect,
  578. int& nFirstRow,
  579. int& nLastRow,
  580. BOOL bIncludePartiallyShownRows )
  581. {
  582. int nRounding = bIncludePartiallyShownRows? 0 : (m_nRowHeight - 1);
  583. nFirstRow = (rect.top + nRounding) / m_nRowHeight;
  584. nLastRow = min( (rect.bottom - nRounding) / m_nRowHeight,
  585. GetRowCount() - 1 );
  586. } // end CRowView::RectLPtoRowRange
  587. /////////////////////////////////////////////////////////////////////////////
  588. // CRowView message map
  589. BEGIN_MESSAGE_MAP(CRowView, CScrollView)
  590. //{{AFX_MSG_MAP(CRowView)
  591. ON_WM_KEYDOWN()
  592. ON_WM_SIZE()
  593. ON_WM_LBUTTONDOWN()
  594. ON_WM_HSCROLL()
  595. ON_WM_CREATE()
  596. ON_WM_VSCROLL()
  597. //}}AFX_MSG_MAP
  598. END_MESSAGE_MAP()
  599. /////////////////////////////////////////////////////////////////////////////
  600. // CRowView commands
  601. /*******************************************************************************
  602. *
  603. * OnSize - CRowView member function: command (override of CWnd)
  604. *
  605. * Processes size change message.
  606. *
  607. * ENTRY:
  608. *
  609. * (Refer to CWnd::OnSize documentation)
  610. *
  611. * EXIT:
  612. *
  613. ******************************************************************************/
  614. void
  615. CRowView::OnSize( UINT nType,
  616. int cx,
  617. int cy )
  618. {
  619. UpdateScrollSizes();
  620. CScrollView::OnSize(nType, cx, cy);
  621. } // end CRowView::OnSize
  622. /*******************************************************************************
  623. *
  624. * OnKeyDown - CRowView member function: command (override of CWnd)
  625. *
  626. * Processes list scrolling / selection via keyboard input.
  627. *
  628. * ENTRY:
  629. *
  630. * (Refer to CWnd::OnKeyDown documentation)
  631. *
  632. * EXIT:
  633. *
  634. ******************************************************************************/
  635. void
  636. CRowView::OnKeyDown( UINT nChar,
  637. UINT nRepCnt,
  638. UINT nFlags )
  639. {
  640. int nNewRow;
  641. switch ( nChar ) {
  642. case VK_HOME:
  643. ChangeSelectionToRow(0);
  644. break;
  645. case VK_END:
  646. ChangeSelectionToRow(GetRowCount() - 1);
  647. break;
  648. case VK_UP:
  649. ChangeSelectionNextRow(FALSE);
  650. break;
  651. case VK_DOWN:
  652. ChangeSelectionNextRow(TRUE);
  653. break;
  654. case VK_PRIOR:
  655. /*
  656. * Determine a new row that is one 'pageup' above our currently
  657. * active row and make it active.
  658. */
  659. nNewRow = (nNewRow = GetActiveRow() - m_nPageScrollRows) >
  660. 0 ? nNewRow : 0;
  661. ChangeSelectionToRow(nNewRow);
  662. break;
  663. case VK_NEXT:
  664. /*
  665. * Determine a new row that is one 'pagedown' below our currently
  666. * active row and make it active.
  667. */
  668. nNewRow = (nNewRow = GetActiveRow() + m_nPageScrollRows) <
  669. GetRowCount() ? nNewRow : GetRowCount() - 1;
  670. ChangeSelectionToRow(nNewRow);
  671. break;
  672. case VK_LEFT:
  673. /*
  674. * Scroll page-left.
  675. */
  676. if ( IsScrollingNeeded(SB_HORZ) ) {
  677. OnHScroll( SB_PAGELEFT, 0, GetScrollBarCtrl(SB_HORZ) );
  678. return;
  679. }
  680. break;
  681. case VK_RIGHT:
  682. /*
  683. * Scroll page-right.
  684. */
  685. if ( IsScrollingNeeded(SB_HORZ) ) {
  686. OnHScroll(SB_PAGERIGHT, 0, GetScrollBarCtrl(SB_HORZ));
  687. return;
  688. }
  689. break;
  690. default:
  691. /*
  692. * Call the CScrollView OnKeyDown function for keys not
  693. * specifically handled here.
  694. */
  695. CScrollView::OnKeyDown( nChar, nRepCnt, nFlags );
  696. }
  697. } // end CRowView::OnKeyDown
  698. /*******************************************************************************
  699. *
  700. * OnLButtonDown - CRowView member function: command (override of CWnd)
  701. *
  702. * Processes left mouse button for list item selection.
  703. *
  704. * ENTRY:
  705. *
  706. * (Refer to CWnd::OnLButtonDown documentation)
  707. *
  708. * EXIT:
  709. *
  710. ******************************************************************************/
  711. void
  712. CRowView::OnLButtonDown( UINT nFlags,
  713. CPoint point )
  714. {
  715. CClientDC dc(this);
  716. OnPrepareDC(&dc);
  717. dc.DPtoLP(&point);
  718. CRect rect(point, CSize(1,1));
  719. int nFirstRow, nLastRow;
  720. RectLPtoRowRange(rect, nFirstRow, nLastRow, TRUE);
  721. if (nFirstRow <= (GetRowCount() - 1))
  722. ChangeSelectionToRow(nFirstRow);
  723. } // end CRowView::OnLButtonDown
  724. /*******************************************************************************
  725. *
  726. * OnHScroll - CRowView member function: command (override of CScrollView)
  727. *
  728. * Handles horizontal scrolling message. The CScrollView member function
  729. * is overriden to allow us to call the CRowView::OnScroll override during
  730. * a Hscroll message.
  731. *
  732. * ENTRY:
  733. *
  734. * (Refer to CWnd::OnHScroll documentation)
  735. *
  736. * EXIT:
  737. *
  738. ******************************************************************************/
  739. void
  740. CRowView::OnHScroll( UINT nSBCode,
  741. UINT nPos,
  742. CScrollBar* pScrollBar )
  743. {
  744. VERIFY( pScrollBar == GetScrollBarCtrl(SB_HORZ) ); // may be null
  745. OnScroll( SB_HORZ, nSBCode, nPos );
  746. } // end CRowView::OnHScroll
  747. /*******************************************************************************
  748. *
  749. * OnVScroll - CRowView member function: command (override of CScrollView)
  750. *
  751. * Handles vertical scrolling message. The CScrollView member function is
  752. * overriden to allow us to call the CRowView::OnScroll override during a
  753. * Vscroll message.
  754. *
  755. * ENTRY:
  756. *
  757. * (Refer to CWnd::OnVScroll documentation)
  758. *
  759. * EXIT:
  760. *
  761. ******************************************************************************/
  762. void
  763. CRowView::OnVScroll( UINT nSBCode,
  764. UINT nPos,
  765. CScrollBar* pScrollBar )
  766. {
  767. VERIFY( pScrollBar == GetScrollBarCtrl(SB_HORZ) ); // may be null
  768. OnScroll( SB_VERT, nSBCode, nPos );
  769. } // end CRowView::OnVScroll
  770. /*******************************************************************************
  771. *
  772. * OnScroll - CRowView member function: command (override of CScrollView)
  773. *
  774. * Processes horizontal scrolling. The CScrollView member function
  775. * is overriden to properly scroll the header bar (if it is defined) and
  776. * to handle or ignore SB_THUMBTRACK scroll messages.
  777. *
  778. * ENTRY:
  779. * nBar (input)
  780. * SB_HORZ or SB_VERT.
  781. * nSBCode (input)
  782. * Scroll bar code.
  783. * nPos (input)
  784. * Scroll-box position for SB_THUMBTRACK handling.
  785. * EXIT:
  786. *
  787. *
  788. * NOTE: This code is a slight modificaton of the CScrollView::OnScroll code
  789. * found in the VIEWSCRL.CPP MFC 2.5 source. The GetScrollLimit()
  790. * function has been added to handle Windows95 scrollbar controls
  791. * (when built with MFC 3.0 and above - MFC300 defined).
  792. *
  793. ******************************************************************************/
  794. void
  795. CRowView::OnScroll( int nBar,
  796. UINT nSBCode,
  797. UINT nPos )
  798. {
  799. VERIFY(nBar == SB_HORZ || nBar == SB_VERT);
  800. BOOL bHorz = (nBar == SB_HORZ);
  801. int zOrig, z; // z = x or y depending on 'nBar'
  802. int zMax;
  803. zOrig = z = GetScrollPos(nBar);
  804. zMax = GetScrollLimit(nBar);
  805. if (zMax <= 0)
  806. {
  807. TRACE0("Warning: no scroll range - ignoring scroll message\n");
  808. VERIFY(z == 0); // must be at top
  809. return;
  810. }
  811. switch (nSBCode)
  812. {
  813. case SB_TOP:
  814. z = 0;
  815. break;
  816. case SB_BOTTOM:
  817. z = zMax;
  818. break;
  819. case SB_LINEUP:
  820. z -= bHorz ? m_lineDev.cx : m_lineDev.cy;
  821. break;
  822. case SB_LINEDOWN:
  823. z += bHorz ? m_lineDev.cx : m_lineDev.cy;
  824. break;
  825. case SB_PAGEUP:
  826. z -= bHorz ? m_pageDev.cx : m_pageDev.cy;
  827. break;
  828. case SB_PAGEDOWN:
  829. z += bHorz ? m_pageDev.cx : m_pageDev.cy;
  830. break;
  831. case SB_THUMBTRACK:
  832. /*
  833. * If we're not handling the SB_THUMBTRACK messages, return.
  834. */
  835. if ( !m_bThumbTrack )
  836. return;
  837. z = nPos;
  838. break;
  839. case SB_THUMBPOSITION:
  840. z = nPos;
  841. break;
  842. default: // ignore other notifications
  843. return;
  844. }
  845. if (z < 0)
  846. z = 0;
  847. else if (z > zMax)
  848. z = zMax;
  849. if (z != zOrig)
  850. {
  851. if (bHorz) {
  852. ScrollWindow(-(z-zOrig), 0);
  853. /*
  854. * If this view has a header bar, scroll it to match the view.
  855. */
  856. if ( m_pHeaderBar )
  857. m_pHeaderBar->ScrollWindow( -(z-zOrig), 0 );
  858. } else
  859. ScrollWindow(0, -(z-zOrig));
  860. SetScrollPos(nBar, z);
  861. UpdateWindow();
  862. /*
  863. * If this view has a header bar, update it now.
  864. */
  865. if ( m_pHeaderBar )
  866. m_pHeaderBar->UpdateWindow();
  867. }
  868. } // end CRowView::OnScroll
  869. #if _MFC_VER >= 0x400
  870. void CRowViewHeaderBar::OnPaint()
  871. {
  872. CPaintDC dc(this); // device context for painting
  873. // TODO: Add your message handler code here
  874. // Do not call CStatusBar::OnPaint() for painting messages
  875. DoPaint(&dc);
  876. }
  877. #endif