Win32 ListView:为整行制作彩色进度条

Win32 ListView:为整行制作彩色进度条,listview,winapi,colors,progress-bar,custom-draw,Listview,Winapi,Colors,Progress Bar,Custom Draw,我想为ListView中的整行创建一个彩色进度条。我的想法来自: 在上图中,我们有彩色进度条,但只有一个单元格。我想做的是做同样的思考,只是为了整排。 以下是我所做的: 并非如我所料:)我试图在CDDS_项目| CDDS_POSTPAINT案例中画图。守则: static LRESULT HandleCustomDraw(NMLVCUSTOMDRAW* pcd) { TCHAR buffer[16]; LVITEM item; switch (pcd->nmc

我想为ListView中的整行创建一个彩色进度条。我的想法来自:

在上图中,我们有彩色进度条,但只有一个单元格。我想做的是做同样的思考,只是为了整排。
以下是我所做的:

并非如我所料:)我试图在
CDDS_项目| 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;
        }
    }
}
预期结果,例如,在第8项第8行,百分比为0.5的预期结果是一个从行开始到第三列之间的填充矩形,行的其余部分为其他颜色。
我怎样才能做到这一点?我知道我必须为选定的/聚焦的/非聚焦的行绘制不同的颜色,但我同意

编辑:
上图(第二幅)是我通过上述代码得到的。
演示我想要的:


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

rectr=pcd->nmcd.rcHandleCustomDraw()
中的code>提供列表视图客户端区域内当前绘制项目的矩形。 现在需要做的就是用从列表视图的客户端矩形中获得的值替换
r.left
r.right

r.left = list_view_rc.left;
r.right = list_view_rc.right;
这将为您提供一个矩形,供整行绘制。 如果使用的是
CDDS\u POSTPAINT
,则只能在最后绘制的项目上执行此操作。这就是为什么需要另一个全局变量
list\u view\u column\u count
,该变量包含列表视图列的数量:

int list_view_column_count;   // Global.
list_view_column_count = Header_GetItemCount(ListView_GetHeader(list_view_hwnd));
使用
CDDS\u POSTPAINT
时,您必须自己在项目内绘制文本,因为您使用矩形将其破坏,或者尝试通过更改前景混合模式将矩形与文本混合。 这大致就是您需要的代码(不带文本图形):


:“CDRF_DODEFAULT:控件将自行绘制。它不会为此绘制周期发送额外的NM_CUSTOMDRAW通知代码。此标志不能与任何其他标志一起使用。”@IInspectable,如果正确,
CDRF_DODEFAULT
的值是
0
,所以我认为这不是问题所在。@Sakura我很难确定您发布的屏幕截图是否是您实际看到的,或者它是否是显示您想要实现的目标的模型。如果是前者,请您提供后者(反之亦然)。@JonathanPotter当然可以,请查看我的编辑。您已请求子项通知,但您没有处理它。我认为您需要在
CDDS\u itemppostaint | CDDS\u子项
上进行绘图。此外,您正在泄漏
hProgressBrush
。为了防止标题控件被覆盖,您需要检查通知消息来自的窗口实际上是listview。
int list_view_column_count;   // Global.
list_view_column_count = Header_GetItemCount(ListView_GetHeader(list_view_hwnd));
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;
        }
    }
}