如何修改 ListView 子项中单个字符的字体颜色? [英] How can I modify the font colors of individual characters in a ListView subitem?

查看:32
本文介绍了如何修改 ListView 子项中单个字符的字体颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Windows API 编写一个应用程序,我想知道如何使用包含多色文本的子项制作列表视图.

I was writing an app using the Windows API, and I wanted to know how to make a listview with subitems that contain multi-colored text.

为了澄清,以下是它如何在 API Monitor 中实现的图片:

To clarify, here is a picture of how it is implemented in API Monitor:

请注意,在API"列中,文本具有多种颜色,例如富文本或其他内容.我想知道我将如何做到这一点.

Notice that in the "API" column, the text has multiple colors, like it is rich text or something. I was wondering how I would do this.

有人告诉我用自定义绘图做一些事情,但他不确定.我查看了它,并处理了 NM_CUSTOMDRAW.这是我的测试结果:

Someone told me to do something with custom-drawing, but he wasn't sure. I looked into it, and I handled NM_CUSTOMDRAW. Here is the result of my test:

这是代码:

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方法,无法修改单个字符的字体颜色;我只能修改subitem中所有东西的字体颜色,这不是我想要的.

Using the NM_CUSTOMDRAW method, I can't modify the font colors of individual characters; I can only modify the font color of everything in the subitem, which is not what I want.

如何实现 API 监视器的功能?我觉得这将非常困难,但欢迎提出任何建议.

How can I achieve what API monitor does? I have a feeling this is going to be very difficult, but any suggestions are welcome.

推荐答案

NM_CUSTOMDRAW 是解决方案.很抱歉,这里没有简单的解决方案.您只需要按顺序而不是集体使用不同颜色的所有者绘制您想要的文本,使用 GetTextExtentPoint32 API 来协助绘制文本.您返回 CDRF_SKIPDEFAULT 以告诉列表视图不要呈现文本,您已经处理好了.

NM_CUSTOMDRAW is the solution. Sorry to say there's no easy solution here. You simply need to ownerdraw the text you want in different colours sequentially rather than collectively, use the GetTextExtentPoint32 API to assist in the text drawing. You return CDRF_SKIPDEFAULT to tell the listview not to render the text, you took care of it.

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;
        }
    }

这篇关于如何修改 ListView 子项中单个字符的字体颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆