分享

Vertical lines for column borders

 louisasea 2007-10-11
http://www./Cpp/controls/listview/gridlines/article.php/c999/

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

// Do not call CListCtrl::OnPaint() for painting messages
}
To draw the vertical lines, we use the header control to determine the column dimensions and also the effective client area after taking into account the header control itself. Finally, we draw a line to the right of each column.

Note that the horizontal scrollbars position is taken into account when determining the border. If we dont do this, we might end up with a line right in the middle of a column when the list has been horizontally scrolled. The GetScrollPos() function returns 0 if there is no scrollbar so we dont need to make a prior check on whether the list view control does have a horizontal scrollbar. We could also have used GetItemRect() function, but it works only if the list has atleast one item.

The 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.

Tools:


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多