2

我想在 ListView 中为整行制作一个彩色进度条。我从这里得到这个想法:

自定义绘图

在上图中,我们有彩色进度条,但只有单个单元格。我想要的是做出同样的想法,但要整排。
这是我所做的:

制作进度条

不像我预期的那样:) 我试图画出这个CDDS_ITEM | CDDS_POSTPAINT案子。编码:

static LRESULT
HandleCustomDraw(NMLVCUSTOMDRAW* pcd)
{
    TCHAR buffer[16];
    LVITEM item;

    switch (pcd->nmcd.dwDrawStage)
    {
        case CDDS_PREPAINT:
            /* Tell the control we are interested in per-item notifications.
            * (We need it just to tell the control we want per-subitem
            * notifications.) */
            return CDRF_DODEFAULT | CDRF_NOTIFYITEMDRAW;

        case (CDDS_ITEM | CDDS_PREPAINT) :
            /* Tell the control we are interested in per-subitem notifications. */
            return CDRF_DODEFAULT | CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYSUBITEMDRAW;
        case (CDDS_ITEM | CDDS_POSTPAINT) :
        {
            // Test: assume the progress value is 50%
            float percent = 0.5;
            RECT r = pcd->nmcd.rc;
            r.right = r.left + percent * (r.right - r.left);
            HBRUSH hProgressBrush = CreateSolidBrush(RGB(255, 255, 0));
            FillRect(pcd->nmcd.hdc, &r, hProgressBrush);
            return CDRF_SKIPDEFAULT;
        }
    }
}

预期结果,例如在 row Item 8,带有percent = 0.5,是从行开始到第三列之间的填充矩形,并且该行的其余部分是其他颜色。
我怎样才能做到这一点?我知道我必须为选定/聚焦/原始行绘制不同的颜色,但我可以接受。

编辑:
上面的图片(第二张)是我用上面的代码得到的。
演示我想要的:

在此处输入图像描述

4

1 回答 1

0

WM_SIZE窗口的处理程序中检索并保存列表视图的客户端RECT(例如在全局变量中)GetClientRect()

RECT list_view_rc;  // Global.
GetClientRect(list_view_hwnd, &list_view_rc);

RECT r = pcd->nmcd.rc;在您HandleCustomDraw()的列表视图的客户区内为您提供当前绘制的项目的矩形。您现在所要做的就是用从列表视图的客户矩形中获取的值替换r.left和:r.right

r.left = list_view_rc.left;
r.right = list_view_rc.right;

这将为您提供一个矩形供整行绘制。如果您使用CDDS_POSTPAINT. 这就是为什么您需要另一个list_view_column_count包含列表视图列数的全局变量:

int list_view_column_count;   // Global.
list_view_column_count = Header_GetItemCount(ListView_GetHeader(list_view_hwnd));

您必须自己在项目内绘制文本,因为您用矩形破坏了它,或者尝试通过使用SetROP2()CDDS_POSTPAINT更改前景混合模式来将矩形与文本混合。这大致是您需要的代码(没有文字绘制):

static LRESULT
HandleCustomDraw(NMLVCUSTOMDRAW* pcd)
{
    TCHAR buffer[16];
    LVITEM item;
    // This static variable works only if you're always calling
    // HandleCustomDraw() only for one specific list view.
    static int current_item_count;

    switch (pcd->nmcd.dwDrawStage)
    {
        case CDDS_PREPAINT:
            /* Tell the control we are interested in per-item notifications.
            * (We need it just to tell the control we want per-subitem
            * notifications.) */
            current_item_count=0;
            return CDRF_DODEFAULT | CDRF_NOTIFYITEMDRAW;

        case (CDDS_ITEM | CDDS_PREPAINT) :
            /* Tell the control we are interested in per-subitem notifications. */
            return CDRF_DODEFAULT | CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYSUBITEMDRAW;
        case (CDDS_ITEM | CDDS_POSTPAINT) :
        if (++current_item_count == list_view_column_count)
        {
            // Test: assume the progress value is 50%
            float percent = 0.5;
            RECT r = pcd->nmcd.rc;
            r.left=list_view_rc.left;
            r.right=list_view_rc.right;
            r.right = r.left + percent * (r.right - r.left);
            HBRUSH hProgressBrush = CreateSolidBrush(RGB(255, 255, 0));
            FillRect(pcd->nmcd.hdc, &r, hProgressBrush);
            return CDRF_SKIPDEFAULT;
        }
    }
}
于 2017-07-18T19:47:12.253 回答