Drawing horizontal and vertical gridlines

To draw horizontal and vertical gridlines we essentially use the same method used for the vertical gridline or column border used in the previous section. After drawing the vertical lines, we use GetItemRect() to get the item height and then we draw the horizontal grid lines based on this height. One implication of using GetItemRect() is that it fails when the list does not have any items in it and no horizontal line is drawn. Here is the complete code of the overridden OnPaint() function. Also note that the next version of the list view control will support the LVS_EX_GRIDLINES style and should make our code redundant.

void CMyListCtrl::OnPaint() 
	// First let the control do its default drawing.
	const MSG *msg = GetCurrentMessage();
	DefWindowProc( msg->message, msg->wParam, msg->lParam );

	// Draw the lines only for LVS_REPORT mode
	if( (GetStyle() & LVS_TYPEMASK) == LVS_REPORT )
		// Get the number of columns
		CClientDC dc(this );
		CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
		int nColumnCount = pHeader->GetItemCount();

		// The bottom of the header corresponds to the top of the line 
		RECT rect;
		pHeader->GetClientRect( &rect );
		int top = rect.bottom;

		// Now get the client rect so we know the line length and
		// when to stop
		GetClientRect( &rect );

		// The border of the column is offset by the horz scroll
		int borderx = 0 - GetScrollPos( SB_HORZ );
		for( int i = 0; i < nColumnCount; i++ )
			// Get the next border
			borderx += GetColumnWidth( i );

			// if next border is outside client area, break out
			if( borderx >= rect.right ) break;

			// Draw the line.
			dc.MoveTo( borderx-1, top);
			dc.LineTo( borderx-1, rect.bottom );

		// Draw the horizontal grid lines

		// First get the height
		if( !GetItemRect( 0, &rect, LVIR_BOUNDS ))

		int height = rect.bottom - rect.top;

		GetClientRect( &rect );
		int width = rect.right;

		for( i = 1; i <= GetCountPerPage(); i++ )
			dc.MoveTo( 0, top + height*i);
			dc.LineTo( width, top + height*i );
	// Do not call CListCtrl::OnPaint() for painting messages

The vertical grid line is actually drawn one pixel left of the column border. This aligns it better with the column header. It also introduces a bug. When you increase a column width, the column area below the last visible item is not updated, thus leaving traces of the previous line. There are two approaches you can take to resolve this. First, draw the line exactly on the column border (e.i. do not subtract 1 from borderx). The second approach is to handle the HDN_TRACK notification from the header control and invalidate the exposed area so that it gets redrawn.

BTW, Paul Gerhart has also implemented this using an owner-drawn CListCtrl. He has made the source code available with a sample app. You can find it at http://www.voicenet.com/~pgerhart/_shware.html


  • FILE NOT FOUND!! http://www.users.voicenet.com/~pgerhart/_shware.html

    Posted by Legacy on 12/26/2003 12:00am

    Originally posted by: Yj, Lee


  • Moving (drag) columns

    Posted by Legacy on 08/14/2003 12:00am

    Originally posted by: Sander


    I think the line:

    // Get the next border
    borderx += GetColumnWidth( i );

    ...should be:

    // Get the next border
    borderx += GetColumnWidth( pHeader->OrderToIndex( i ) );

    ...in order to allow columns to be moved (dragged) around.



  • Column resizing fix

    Posted by Legacy on 01/24/2003 12:00am

    Originally posted by: Gianluca Nastasi

    When you try to resize a column old lines are not deleted.
    To solve the problem simply add an Invalidate() at the beginning of the OnPaint().

  • Can u provide complete source code

    Posted by Legacy on 12/29/2002 12:00am

    Originally posted by: harish

    I have tried out the same logic, but i am having problems while inserting...the grids dont get drawn.
    so, can u provide complete source code, for the same.

  • What shall I do, If I want to change the gridlines' color?

    Posted by Legacy on 09/21/2001 12:00am

    Originally posted by: Max

    Using CListCtrl's extention style can not change the gridlines' color.

  • List Control / List View Extended Styles

    Posted by Legacy on 09/13/2001 12:00am

    Originally posted by: Khurram Aziz

    Thanks Mr. Zafir Anjum, you made my life a lot easier.

    List Control supports numerous extended styles which are not exposed in it's properties dialog. Although if you use the newer Microsoft ListView Control 6.0 (from Registered ActiveX components), you can set these styles at design time, but the older List Control you find in the Control Toolbox doesn't allow these extended styles to be set at design time.

    To add these extended styles at runtime, use the function:

    CListCtrl::SetExtendedStyle(DWORD dwNewStyle)

    where dwNewStyle can be a combination of several styles.

    For complete details, please see MSDN help topic "Extended List-View Styles"


    This will add the Grid Lines and Checkboxes in the List Control.

  • Inserting of Text

    Posted by Legacy on 06/30/2001 12:00am

    Originally posted by: Girish


    I have a application in which the number of rows and columns are fixed and I need to add the horizontal and vertical girds. Where should I add the data to the rows and column position ???

    If I add it in the InitDialog function of the Dialog box then the contents is getting lost ??? where should this be added ??? should I add the part of the OnPaint function into the OnInitdialog box function itself ???

    Best Regards,

  • Kevin Stilwell's solution is good

    Posted by Legacy on 08/11/2000 12:00am

    Originally posted by: Michael Pu

    Not only LVS_EX_GRIDLINES but other cool extended styles such LVS_EX_FULLROWSELECT can be applied this way too.

    These extended styles are not available in the design property of listviewctrl and when I try to modify project's .rc file and add the extended styles, they cause compile errors.

  • One Line Method for List Views

    Posted by Legacy on 10/29/1999 12:00am

    Originally posted by: Kevin Stilwell

    In the OnInitUpdate handler, after I populate my listviews items, I add the following:


  • Source link is bad - anyone have the example source?

    Posted by Legacy on 08/25/1999 12:00am

    Originally posted by: David Carroll

    The source link given in the article is bad - does anyone have the example source code available for this?


    David Carroll

  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Enterprises are increasingly looking to platform as a service (PaaS) to lower their costs and speed their time to market for new applications. Developing, deploying, and managing applications in the cloud eliminates the time and expense of managing a physical infrastructure to support them. PaaS offerings must deliver additional long-term benefits, such as a lower total cost of ownership (TCO), rapid scalability, and ease of integration, all while providing robust security and availability. This report …

  • Moving from an on-premises environment to Office 365 does not remove the need to plan for disruptions or reduce the business risk requirements for protecting email services. If anything, some risks increase with a move to the cloud. Read how to ease the transition every business faces if considering or already migrating to cloud email. This white paper discusses: Setting expectations when migrating to Office 365 Understanding the implications of relying solely on Exchange Online security Necessary archiving …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date