/******************************************************************************* * * rowview.cpp * * implementation of the CRowView class and CRowViewHeaderBar class * * Modified from the Microsoft Foundation Classes C++ library. * Copyright (C) 1992 Microsoft Corporation * All rights reserved. * * additional copyright notice: Copyright 1995, Citrix Systems Inc. * * $Author: butchd $ Butch Davis * * $Log: N:\NT\PRIVATE\UTILS\CITRIX\WINUTILS\COMMON\VCS\ROWVIEW.CPP $ * * Rev 1.1 18 Jul 1995 06:50:06 butchd * Scrolling fix for Windows95 / MFC 3.0 * * Rev 1.0 01 Mar 1995 10:54:46 butchd * Initial revision. * * Rev 1.0 02 Aug 1994 18:18:30 butchd * (Initial revision: was duplicated in each app directory). * *******************************************************************************/ /* * include files */ #include "stdafx.h" #include // MFC core and standard components #include // MFC extensions #include "rowview.h" #include "resource.h" #include #include // for INT_MAX #ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #endif //////////////////////////////////////////////////////////////////////////////// // CRowViewHeaderBar class implementation / construction, destruction IMPLEMENT_DYNAMIC(CRowViewHeaderBar, CStatusBar) CRowViewHeaderBar::CRowViewHeaderBar() { } CRowViewHeaderBar::~CRowViewHeaderBar() { } /******************************************************************************* * * DoPaint - CRowViewHeaderBar member function: CStatusBar class override * * Draw the view's header bar. * * ENTRY: * * pDC (input) * Points to the current CDC device-context object for drawing * the header bar. * * NOTE: The view's * DoPaint function. * ******************************************************************************/ void CRowViewHeaderBar::DoPaint( CDC* pDC ) { /* * Perform the CControlBar base class' DoPaint first. */ CControlBar::DoPaint(pDC); /* * Default the y position for drawing the header bar to the m_cyTopBorder * member variable setting and call the view's OnDrawHeaderBar() member * function to perform the desired header bar drawing. */ int y = m_cyTopBorder; ((CRowView *)m_pView)->OnDrawHeaderBar( pDC, y ); } // end CRowViewHeaderBar::DoPaint //////////////////////////////////////////////////////////////////////////////// // CRowViewHeaderBar message map BEGIN_MESSAGE_MAP(CRowViewHeaderBar, CStatusBar) //{{AFX_MSG_MAP(CRowViewHeaderBar) #if _MFC_VER >= 0x400 ON_WM_PAINT() #endif //}}AFX_MSG_MAP END_MESSAGE_MAP() //////////////////////////////////////////////////////////////////////////////// // CRowViewHeaderBar commands //////////////////////////////////////////////////////////////////////////////// // CRowView implementation / construction, destruction IMPLEMENT_DYNAMIC(CRowView, CScrollView) CRowView::CRowView() { m_nPrevSelectedRow = 0; m_bThumbTrack = TRUE; // default to handle SB_THUMBTRACK messages. m_pHeaderBar = NULL; // default to no header bar } CRowView::~CRowView() { } int CRowView::OnCreate( LPCREATESTRUCT lpCreateStruct ) { if ( CScrollView::OnCreate(lpCreateStruct) == -1 ) return -1; /* * If the derived class has constructed a header bar, call CreateHeaderBar * to create the header-bar window and initialize. */ if ( m_pHeaderBar ) if ( !CreateHeaderBar() ) return( -1 ); return( 0 ); } // end CRowView::OnCreate BOOL CRowView::CreateHeaderBar() { /* * Invoke the CRowViewHeaderBar's Create member function (CStatusBar defined) * to create the header bar, which will be hooked to this document/view's * parent window. Set the header bar's m_pView pointer to this view. */ if ( !m_pHeaderBar->Create( GetParent(), WS_CHILD | WS_VISIBLE | CBRS_TOP, IDW_HEADER_BAR ) ) { return ( FALSE ); } else { m_pHeaderBar->m_pView = this; return ( TRUE ); } } // end CRowView::CreateHeaderBar //////////////////////////////////////////////////////////////////////////////// // CRowView class optional derived class override /******************************************************************************* * * ResetHeaderBar - CRowView member function: optional derived class override * * Reset the header bar width and height based on the view's total width * and view's row height. Will also instruct the parent frame to * recalculate it's layout based on the new header bar metrics. * * NOTE: A derived class will typically override this member function to * set the desired header bar font, then call this function. * ******************************************************************************/ void CRowView::ResetHeaderBar() { /* * If no header bar was created, return. */ if ( !m_pHeaderBar ) return; /* * Set the header bar's width and height. */ m_pHeaderBar->SendMessage( WM_SIZE, 0, MAKELONG(m_nRowWidth, m_nRowHeight) ); /* * Recalculate parent frame's layout with new header bar. */ ((CFrameWnd *)m_pHeaderBar->GetParent())->RecalcLayout(); } // end CRowView::ResetHeaderBar //////////////////////////////////////////////////////////////////////////////// // CRowView class override member functions /******************************************************************************* * * OnInitialUpdate - CRowView member function: CView class override * * Called before the view is initially displayed. * * (Refer to the MFC CView::OnInitialUpdate documentation) * ******************************************************************************/ void CRowView::OnInitialUpdate() { m_nPrevRowCount = GetRowCount(); m_nPrevSelectedRow = GetActiveRow(); } // end CRowView::OnInitialUpdate /******************************************************************************* * * OnPrepareDC - CRowView member function: CView class override * * Prepare the DC for screen or printer output. * * (Refer to the MFC CView::OnPrepareDC documentation) * ******************************************************************************/ void CRowView::OnPrepareDC( CDC* pDC, CPrintInfo* pInfo ) { /* * The size of text that is displayed, printed or previewed changes * depending on the DC. We explicitly call OnPrepareDC() to prepare * CClientDC objects used for calculating text positions and to * prepare the text metric member variables of the CRowView object. * The framework also calls OnPrepareDC() before passing the DC to * OnDraw(). */ CScrollView::OnPrepareDC( pDC, pInfo ); CalculateRowMetrics( pDC ); } // end CRowView::OnPrepareDC /******************************************************************************* * * OnDraw - CRowView member function: CView class override * * Draw on the view as needed. * * (Refer to the MFC CView::OnDraw documentation) * ******************************************************************************/ void CRowView::OnDraw( CDC* pDC ) { /* * If there are no rows to draw, don't do anything. */ if ( GetRowCount() == 0 ) return; /* * The window has been invalidated and needs to be repainted; * or a page needs to be printed (or previewed). * First, determine the range of rows that need to be displayed or * printed by fetching the invalidated region. */ int nFirstRow, nLastRow; CRect rectClip; pDC->GetClipBox( &rectClip ); RectLPtoRowRange( rectClip, nFirstRow, nLastRow, TRUE ); /* * Draw each row in the invalidated region of the window, * or on the printed (previewed) page. */ int nActiveRow = GetActiveRow(); int nRow, y; int nLastViewableRow = LastViewableRow(); for ( nRow = nFirstRow, y = m_nRowHeight * nFirstRow; nRow <= nLastRow; nRow++, y += m_nRowHeight ) { if ( nRow > nLastViewableRow ) { CString strWarning; strWarning.LoadString( IDS_TOO_MANY_ROWS ); pDC->TextOut( 0, y, strWarning ); break; } OnDrawRow( pDC, nRow, y, nRow == nActiveRow ); } } // end CRowView::OnDraw /******************************************************************************* * * OnPreparePrinting - CRowView member function: CView class override * * Prepare the view for printing or print preview. * * (Refer to the MFC CView::OnPreparePrinting documentation) * ******************************************************************************/ BOOL CRowView::OnPreparePrinting( CPrintInfo* pInfo ) { return ( DoPreparePrinting( pInfo ) ); } // end CRowView::OnPreparePrinting /******************************************************************************* * * OnBeginPrinting - CRowView member function: CView class override * * Setup before beginning to print. * * (Refer to the MFC CView::OnBeginPrinting documentation) * ******************************************************************************/ void CRowView::OnBeginPrinting( CDC* pDC, CPrintInfo* pInfo ) { /* * OnBeginPrinting() is called after the user has committed to * printing by OK'ing the Print dialog, and after the framework * has created a CDC object for the printer or the preview view. */ /* * This is the right opportunity to set up the page range. * Given the CDC object, we can determine how many rows will * fit on a page, so we can in turn determine how many printed * pages represent the entire document. */ int nPageHeight = pDC->GetDeviceCaps(VERTRES); CalculateRowMetrics(pDC); m_nRowsPerPrintedPage = nPageHeight / m_nRowHeight; int nPrintableRowCount = LastViewableRow() + 1; if ( GetRowCount() < nPrintableRowCount ) nPrintableRowCount = GetRowCount(); pInfo->SetMaxPage( (nPrintableRowCount + m_nRowsPerPrintedPage - 1) / m_nRowsPerPrintedPage ); /* * Start previewing at page #1. */ pInfo->m_nCurPage = 1; } // end CRowView::OnBeginPrinting /******************************************************************************* * * OnPrint - CRowView member function: CView class override * * Print or preview a page of the view's document. * * (Refer to the MFC CView::OnPrint documentation) * ******************************************************************************/ void CRowView::OnPrint( CDC* pDC, CPrintInfo* pInfo ) { /* * Print the rows for the current page. */ int yTopOfPage = (pInfo->m_nCurPage -1) * m_nRowsPerPrintedPage * m_nRowHeight; /* * Orient the viewport so that the first row to be printed * has a viewport coordinate of (0,0). */ pDC->SetViewportOrg(0, -yTopOfPage); /* * Draw as many rows as will fit on the printed page. * Clip the printed page so that there is no partially shown * row at the bottom of the page (the same row which will be fully * shown at the top of the next page). */ int nPageWidth = pDC->GetDeviceCaps(HORZRES); CRect rectClip = CRect(0, yTopOfPage, nPageWidth, yTopOfPage + m_nRowsPerPrintedPage * m_nRowHeight); pDC->IntersectClipRect(&rectClip); OnDraw(pDC); } // end CRowView::OnPrint ///////////////////////////////////////////////////////////////////////////// // CRowView operations /******************************************************************************* * * UpdateRow - CRowView member function: operation * * Handle scrolling and invalidation of the specified row, in preparation * for the OnDraw function. * * ENTRY: * * nInvalidRow (input) * Row to update. * * EXIT: * ******************************************************************************/ void CRowView::UpdateRow( int nInvalidRow ) { int nRowCount = GetRowCount(); /* * If the number of rows has changed, then adjust the scrolling range. */ if (nRowCount != m_nPrevRowCount) { UpdateScrollSizes(); m_nPrevRowCount = nRowCount; } /* * When the currently selected row changes: * scroll the view so that the newly selected row is visible, and * ask the derived class to repaint the selected and previously * selected rows. */ CClientDC dc(this); OnPrepareDC(&dc); /* * Determine the range of the rows that are currently fully visible * in the window. We want to do discrete scrolling by so that * the next or previous row is always fully visible. */ int nFirstRow, nLastRow; CRect rectClient; GetClientRect( &rectClient ); dc.DPtoLP( &rectClient ); RectLPtoRowRange( rectClient, nFirstRow, nLastRow, FALSE ); /* * If necessary, scroll the window so the newly selected row is * visible. MODIFICATION: set the pt.x to the left visible x point * in the row (not 0), so that the ScrollToDevicePosition() call won't * automatically perform a horizontal scroll (very annoying to user). */ POINT pt; pt.x = rectClient.left; BOOL bNeedToScroll = TRUE; if ( nInvalidRow < nFirstRow ) { /* * The newly selected row is above those currently visible * in the window. Scroll so the newly selected row is at the * very top of the window. The last row in the window might * be only partially visible. */ pt.y = RowToYPos(nInvalidRow); } else if ( nInvalidRow > nLastRow ) { /* * The newly selected row is below those currently visible * in the window. Scroll so the newly selected row is at the * very bottom of the window. The first row in the window might * be only partially visible. */ pt.y = max( 0, RowToYPos(nInvalidRow+1) - rectClient.Height() ); } else { bNeedToScroll = FALSE; } if ( bNeedToScroll ) { /* * Scrolling will cause the newly selected row to be * redrawn in the invalidated area of the window. */ ScrollToDevicePosition(pt); /* * Need to prepare the DC again because ScrollToDevicePosition() * will have changed the viewport origin. The DC is used some * more below. */ OnPrepareDC(&dc); } CRect rectInvalid = RowToWndRect( &dc, nInvalidRow ); InvalidateRect( &rectInvalid ); /* * Give the derived class an opportunity to repaint the * previously selected row, perhaps to un-highlight it. */ int nSelectedRow = GetActiveRow(); if (m_nPrevSelectedRow != nSelectedRow) { CRect rectOldSelection = RowToWndRect(&dc, m_nPrevSelectedRow); InvalidateRect(&rectOldSelection); m_nPrevSelectedRow = nSelectedRow; } } // end CRowView::UpdateRow /******************************************************************************* * * IsScrollingNeeded - CRowView member function: operation * * Determine if the client window of this view is small enough in a * HORIZONTAL or VERTICAL direction to require scrolling to see the * entire view. This function is mainly used to support the operation * of 'scrolling keys' (non-mouse generated scrolling commands). * * ENTRY: * * nBar (input) * SB_HORZ or SB_VERT: to indicate which scrolling direction to check. * * EXIT: * * TRUE if scrolling is needed in the specified direction. * FALSE if no scrolling is needed in the specified direction. * ******************************************************************************/ BOOL CRowView::IsScrollingNeeded( int nBar ) { CRect rectClient; CSize sizeTotal; GetClientRect( &rectClient ); sizeTotal = GetTotalSize(); if ( nBar == SB_HORZ ) { if ( sizeTotal.cx > rectClient.right ) return ( TRUE ); else return (FALSE ); } else { if ( sizeTotal.cy > rectClient.bottom ) return ( TRUE ); else return (FALSE ); } } // end CRowView::IsScrollingNeeded #ifndef MFC300 /******************************************************************************* * * GetScrollLimit - CRowView member function: operation (MFC 2.x stub) * * MFC 3.0 provides a GetScrollLimit() member function that properly * handles Windows95 scrollbar controls if running on Windows95. This * stub is provided for * * ENTRY: * nBar (input) * SB_HORZ or SB_VERT: to indicate which scrolling direction to check. * EXIT: * Returns the nMax value from the standard Windows GetScrollLimit() API. * Also contains an ASSERT to check for nMin != 0. * ******************************************************************************/ int CRowView::GetScrollLimit( int nBar ) { int nMin, nMax; GetScrollRange(nBar, &nMin, &nMax); ASSERT(nMin == 0); return nMax; } // end CRowView::GetScrollLimit #endif void CRowView::CalculateRowMetrics( CDC* pDC ) { GetRowWidthHeight( pDC, m_nRowWidth, m_nRowHeight ); } // end CRowView::CalculateRowMetrics void CRowView::UpdateScrollSizes() { /* * UpdateScrollSizes() is called when it is necessary to adjust the * scrolling range or page/line sizes. There are two occassions * where this is necessary: (1) when a new row is effected (added, * deleted, or changed) -- see UpdateRow()-- and (2) when the window size * changes-- see OnSize(). */ CRect rectClient; GetClientRect( &rectClient ); CClientDC dc( this ); CalculateRowMetrics( &dc ); /* * The vert scrolling range is the total display height of all * of the rows. */ CSize sizeTotal( m_nRowWidth, m_nRowHeight * (min( GetRowCount(), LastViewableRow() )) ); /* * The vertical per-page scrolling distance is equal to the * how many rows can be displayed in the current window, less * one row for paging overlap. */ CSize sizePage( m_nRowWidth/5, max( m_nRowHeight, ((rectClient.bottom/m_nRowHeight)-1)*m_nRowHeight ) ); /* * We'll also calculate the number of rows that the view should be scrolled * during PageUp / PageDown. This number will always be at least 1. */ m_nPageScrollRows = (m_nPageScrollRows = ((rectClient.bottom / m_nRowHeight)-1)) >= 1 ? m_nPageScrollRows : 1; /* * The vertical per-line scrolling distance is equal to the * height of the row. */ CSize sizeLine( m_nRowWidth/20, m_nRowHeight ); SetScrollSizes( MM_TEXT, sizeTotal, sizePage, sizeLine ); } // end CRowView::UpdateScrollSizes int CRowView::RowToYPos( int nRow ) { return ( nRow * m_nRowHeight ); } // end CRowView::RowToYPos CRect CRowView::RowToWndRect( CDC* pDC, int nRow ) { /* * MODIFICATION: Set right end of returned rectangle to max of end of row, * or screen width. This will assure full update in case of horizontall * scrolling on very wide rows (> screen width). */ int nHorzRes = pDC->GetDeviceCaps(HORZRES); CRect rect( 0, nRow * m_nRowHeight, max( m_nRowWidth, nHorzRes ), (nRow + 1) * m_nRowHeight ); pDC->LPtoDP( &rect ); return rect; } // end CRowView::RowToWndRect int CRowView::LastViewableRow() { return ( (INT_MAX / m_nRowHeight) - 1 ); } // end CRowView::LastViewableRow void CRowView::RectLPtoRowRange( const CRect& rect, int& nFirstRow, int& nLastRow, BOOL bIncludePartiallyShownRows ) { int nRounding = bIncludePartiallyShownRows? 0 : (m_nRowHeight - 1); nFirstRow = (rect.top + nRounding) / m_nRowHeight; nLastRow = min( (rect.bottom - nRounding) / m_nRowHeight, GetRowCount() - 1 ); } // end CRowView::RectLPtoRowRange ///////////////////////////////////////////////////////////////////////////// // CRowView message map BEGIN_MESSAGE_MAP(CRowView, CScrollView) //{{AFX_MSG_MAP(CRowView) ON_WM_KEYDOWN() ON_WM_SIZE() ON_WM_LBUTTONDOWN() ON_WM_HSCROLL() ON_WM_CREATE() ON_WM_VSCROLL() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CRowView commands /******************************************************************************* * * OnSize - CRowView member function: command (override of CWnd) * * Processes size change message. * * ENTRY: * * (Refer to CWnd::OnSize documentation) * * EXIT: * ******************************************************************************/ void CRowView::OnSize( UINT nType, int cx, int cy ) { UpdateScrollSizes(); CScrollView::OnSize(nType, cx, cy); } // end CRowView::OnSize /******************************************************************************* * * OnKeyDown - CRowView member function: command (override of CWnd) * * Processes list scrolling / selection via keyboard input. * * ENTRY: * * (Refer to CWnd::OnKeyDown documentation) * * EXIT: * ******************************************************************************/ void CRowView::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags ) { int nNewRow; switch ( nChar ) { case VK_HOME: ChangeSelectionToRow(0); break; case VK_END: ChangeSelectionToRow(GetRowCount() - 1); break; case VK_UP: ChangeSelectionNextRow(FALSE); break; case VK_DOWN: ChangeSelectionNextRow(TRUE); break; case VK_PRIOR: /* * Determine a new row that is one 'pageup' above our currently * active row and make it active. */ nNewRow = (nNewRow = GetActiveRow() - m_nPageScrollRows) > 0 ? nNewRow : 0; ChangeSelectionToRow(nNewRow); break; case VK_NEXT: /* * Determine a new row that is one 'pagedown' below our currently * active row and make it active. */ nNewRow = (nNewRow = GetActiveRow() + m_nPageScrollRows) < GetRowCount() ? nNewRow : GetRowCount() - 1; ChangeSelectionToRow(nNewRow); break; case VK_LEFT: /* * Scroll page-left. */ if ( IsScrollingNeeded(SB_HORZ) ) { OnHScroll( SB_PAGELEFT, 0, GetScrollBarCtrl(SB_HORZ) ); return; } break; case VK_RIGHT: /* * Scroll page-right. */ if ( IsScrollingNeeded(SB_HORZ) ) { OnHScroll(SB_PAGERIGHT, 0, GetScrollBarCtrl(SB_HORZ)); return; } break; default: /* * Call the CScrollView OnKeyDown function for keys not * specifically handled here. */ CScrollView::OnKeyDown( nChar, nRepCnt, nFlags ); } } // end CRowView::OnKeyDown /******************************************************************************* * * OnLButtonDown - CRowView member function: command (override of CWnd) * * Processes left mouse button for list item selection. * * ENTRY: * * (Refer to CWnd::OnLButtonDown documentation) * * EXIT: * ******************************************************************************/ void CRowView::OnLButtonDown( UINT nFlags, CPoint point ) { CClientDC dc(this); OnPrepareDC(&dc); dc.DPtoLP(&point); CRect rect(point, CSize(1,1)); int nFirstRow, nLastRow; RectLPtoRowRange(rect, nFirstRow, nLastRow, TRUE); if (nFirstRow <= (GetRowCount() - 1)) ChangeSelectionToRow(nFirstRow); } // end CRowView::OnLButtonDown /******************************************************************************* * * OnHScroll - CRowView member function: command (override of CScrollView) * * Handles horizontal scrolling message. The CScrollView member function * is overriden to allow us to call the CRowView::OnScroll override during * a Hscroll message. * * ENTRY: * * (Refer to CWnd::OnHScroll documentation) * * EXIT: * ******************************************************************************/ void CRowView::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ) { VERIFY( pScrollBar == GetScrollBarCtrl(SB_HORZ) ); // may be null OnScroll( SB_HORZ, nSBCode, nPos ); } // end CRowView::OnHScroll /******************************************************************************* * * OnVScroll - CRowView member function: command (override of CScrollView) * * Handles vertical scrolling message. The CScrollView member function is * overriden to allow us to call the CRowView::OnScroll override during a * Vscroll message. * * ENTRY: * * (Refer to CWnd::OnVScroll documentation) * * EXIT: * ******************************************************************************/ void CRowView::OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ) { VERIFY( pScrollBar == GetScrollBarCtrl(SB_HORZ) ); // may be null OnScroll( SB_VERT, nSBCode, nPos ); } // end CRowView::OnVScroll /******************************************************************************* * * OnScroll - CRowView member function: command (override of CScrollView) * * Processes horizontal scrolling. The CScrollView member function * is overriden to properly scroll the header bar (if it is defined) and * to handle or ignore SB_THUMBTRACK scroll messages. * * ENTRY: * nBar (input) * SB_HORZ or SB_VERT. * nSBCode (input) * Scroll bar code. * nPos (input) * Scroll-box position for SB_THUMBTRACK handling. * EXIT: * * * NOTE: This code is a slight modificaton of the CScrollView::OnScroll code * found in the VIEWSCRL.CPP MFC 2.5 source. The GetScrollLimit() * function has been added to handle Windows95 scrollbar controls * (when built with MFC 3.0 and above - MFC300 defined). * ******************************************************************************/ void CRowView::OnScroll( int nBar, UINT nSBCode, UINT nPos ) { VERIFY(nBar == SB_HORZ || nBar == SB_VERT); BOOL bHorz = (nBar == SB_HORZ); int zOrig, z; // z = x or y depending on 'nBar' int zMax; zOrig = z = GetScrollPos(nBar); zMax = GetScrollLimit(nBar); if (zMax <= 0) { TRACE0("Warning: no scroll range - ignoring scroll message\n"); VERIFY(z == 0); // must be at top return; } switch (nSBCode) { case SB_TOP: z = 0; break; case SB_BOTTOM: z = zMax; break; case SB_LINEUP: z -= bHorz ? m_lineDev.cx : m_lineDev.cy; break; case SB_LINEDOWN: z += bHorz ? m_lineDev.cx : m_lineDev.cy; break; case SB_PAGEUP: z -= bHorz ? m_pageDev.cx : m_pageDev.cy; break; case SB_PAGEDOWN: z += bHorz ? m_pageDev.cx : m_pageDev.cy; break; case SB_THUMBTRACK: /* * If we're not handling the SB_THUMBTRACK messages, return. */ if ( !m_bThumbTrack ) return; z = nPos; break; case SB_THUMBPOSITION: z = nPos; break; default: // ignore other notifications return; } if (z < 0) z = 0; else if (z > zMax) z = zMax; if (z != zOrig) { if (bHorz) { ScrollWindow(-(z-zOrig), 0); /* * If this view has a header bar, scroll it to match the view. */ if ( m_pHeaderBar ) m_pHeaderBar->ScrollWindow( -(z-zOrig), 0 ); } else ScrollWindow(0, -(z-zOrig)); SetScrollPos(nBar, z); UpdateWindow(); /* * If this view has a header bar, update it now. */ if ( m_pHeaderBar ) m_pHeaderBar->UpdateWindow(); } } // end CRowView::OnScroll #if _MFC_VER >= 0x400 void CRowViewHeaderBar::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here // Do not call CStatusBar::OnPaint() for painting messages DoPaint(&dc); } #endif