Drawing horizontal and vertical gridlines | CodeGuru

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() […]

Written By
CodeGuru Staff
CodeGuru Staff
Aug 6, 1998
1 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

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 ))
			return;

		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

 

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.