我正在使用Windows API编写应用程序,我想知道如何使用包含多色文本的子项目创建列表视图。
为了澄清,这里是一张如何在API Monitor中实现它的图片:
请注意,在“API”列中,文本有多种颜色,例如富文本或其他内容。我想知道我会怎么做。
有人告诉我用自定义绘图做点什么,但他不确定。我调查了一下,然后处理了NM_CUSTOMDRAW
。这是我测试的结果:
以下是代码:
inline LRESULT HandleWM_NOTIFY(LPARAM lParam)
{
switch (((LPNMHDR)lParam)->code)
{
case NM_CUSTOMDRAW:
{
switch (((LPNMHDR)lParam)->idFrom)
{
case ID_LISTVIEW1:
{
LPNMLVCUSTOMDRAW lpNMLVCD = (LPNMLVCUSTOMDRAW)lParam;
if (lpNMLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
{
return CDRF_NOTIFYITEMDRAW;
}
else if (lpNMLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
{
COLORREF crText;
switch (lpNMLVCD->nmcd.dwItemSpec % 3)
{
case 0:
crText = RGB(255, 0, 0);
break;
case 1:
crText = RGB(0, 255, 0);
break;
case 2:
crText = RGB(0, 0, 255);
break;
}
lpNMLVCD->clrText = crText;
lpNMLVCD->
}
return CDRF_DODEFAULT;
}
default: break;
}
break;
}
default: break;
}
return 0;
}
使用NM_CUSTOMDRAW
方法,我无法修改单个字符的字体颜色;我只能修改子项中所有内容的字体颜色,这不是我想要的。
如何实现API监视器的功能?我有一种感觉,这将是非常困难的,但欢迎提出任何建议。
答案 0 :(得分:7)
NM_CUSTOMDRAW是解决方案。很抱歉,这里没有 easy 解决方案。您只需要以不同的颜色顺序绘制所需的文本,而不是集体绘制,使用GetTextExtentPoint32 API来协助文本绘制。你返回CDRF_SKIPDEFAULT告诉列表视图不要呈现文本,你负责处理它。
if (lpNMHdr->code == NM_CUSTOMDRAW)
{
LPNMLVCUSTOMDRAW lpCD = (LPNMLVCUSTOMDRAW)lpNMHdr;
if (lpCD->nmcd.dwDrawStage == CDDS_PREPAINT)
{
return CDRF_NOTIFYITEMDRAW;
}
if (lpCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
{
return CDRF_NOTIFYSUBITEMDRAW;
}
if (lpCD->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT|CDDS_SUBITEM))
{
if (lpCD->iSubItem == 0) //detect which subitem is being drawn
{
LPCTSTR lpcszBuf1 = _T("example");
LPCTSTR lpcszBuf2 = _T("text");
RECT iR = { 0 };
ListView_GetSubItemRect(lpCD->nmcd.hdr.hwndFrom, lpCD->nmcd.dwItemSpec, lpCD->iSubItem, LVIR_BOUNDS, &iR);
SetBkMode(lpCD->nmcd.hdc, TRANSPARENT);
SIZE sz = { 0 };
GetTextExtentPoint32(lpCD->nmcd.hdc, lpcszBuf1, 7, &sz);
SetTextColor(lpCD->nmcd.hdc, RGB(255, 0, 0));
DrawText(lpCD->nmcd.hdc, lpcszBuf1, -1, &iR, DT_LEFT);
iR.left += sz.cx;
SetTextColor(lpCD->nmcd.hdc, RGB(0, 255, 0));
DrawText(lpCD->nmcd.hdc, lpcszBuf2, -1, &iR, DT_LEFT);
return CDRF_SKIPDEFAULT;
}
}