我想在ListView中为完整行创建一个彩色进度条。我从here获取了这个想法:
在上图中,我们有彩色进度条,但只有单个细胞。我想要的是同样的想法,但是对于完整的行 这就是我所做的:
不像我预期的那样:)我试图在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;
}
}
}
期望结果,例如在行Item 8
,percent = 0.5
,是从行的开头到第三列之间的填充矩形,行的其余部分是其他颜色。
我怎么能做到这一点?我知道我必须为选定/聚焦/初始行绘制不同的颜色,但我没关系。
修改
上面的图像(第二个)就是我在上面的代码中得到的结果
演示我想要的东西:
答案 0 :(得分: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));
使用CDDS_POSTPAINT
,您必须自己在项目中绘制文本,因为您使用矩形将其销毁,或者尝试通过使用SetROP2()更改前景混合模式将矩形与文本混合。
这大致是您需要的代码(没有文字绘图):
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;
}
}
}