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



Comments

  • 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

    Empty!!

    Reply
  • Moving (drag) columns

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

    Originally posted by: Sander

    Hi,


    I think the line:

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

    ...should be:

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

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

    Greetings,


    Sander.

    Reply
  • 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().

    Reply
  • 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.
    Thanks
    -Harish

    Reply
  • 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.

    Reply
  • 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"

    Example:
    m_list.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_CHECKBOXES);

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

    Reply
  • Inserting of Text

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

    Originally posted by: Girish

    Hi,

    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,
    Girish

    Reply
  • 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.

    Reply
  • 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:
    
    

    ListView_SetExtendedListViewStyleEx(m_hWnd,LVS_EX_GRIDLINES,LVS_EX_GRIDLINES);

    Reply
  • 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?

    Thanks,

    David Carroll

    Reply
  • Loading, Please Wait ...

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

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Packaged application development teams frequently operate with limited testing environments due to time and labor constraints. By virtualizing the entire application stack, packaged application development teams can deliver business results faster, at higher quality, and with lower risk.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds