Win32 ListView:为整行制作彩色进度条
我想为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
以下是我所做的: 并非如我所料:)我试图在
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;
}
}
}