ListView 的 ImageList 中的透明图像

发布于 2024-11-27 14:34:44 字数 2106 浏览 2 评论 0原文

这是我的程序的图片:

WhiteFlag

如您所见,图标不是透明,简单的白色。这是有问题的,因为我已经将列表视图编码为交替颜色,并且白色在灰色上看起来非常难看。

现在,我使用 带有粉红色背景的位图作为图标,并使用粉红色作为面具。这是我的 HIMAGELIST 的代码:

hImageList = ImageList_Create(16, 16,  ILC_COLOR32 | ILC_MASK, ICON_COUNT, 0);
if (hImageList != NULL)
{
  HBITMAP hBitmap = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_ICONS));
  if (hBitmap != NULL)
  {
    ImageList_AddMasked(hImageList, hBitmap, RGB(0xFF, 0, 0xFF)); // pink mask
    DeleteObject(hBitmap);
  }

  ImageList_SetBkColor(hImageList, CLR_NONE);
}
ListView_SetImageList(hWnd, hImageList, LVSIL_SMALL);

这是列表视图的自定义绘制(交替颜色)的代码

LRESULT WhiteFlagUI::PaintListView(__in HWND hwndListView, __in LPARAM lParam)
{
  LPNMLVCUSTOMDRAW lpListDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(lParam);

  switch (lpListDraw->nmcd.dwDrawStage)
  {
    case CDDS_PREPAINT:
      return (CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYSUBITEMDRAW);
      break;

    case (CDDS_PREPAINT | CDDS_ITEM):
      {
        RECT rect;

        if (ListView_GetSubItemRect(hwndListView, lpListDraw->nmcd.dwItemSpec, lpListDraw->iSubItem, LVIR_BOUNDS, &rect))
        {
          COLORREF color;

          // determine color
          if (lpListDraw->nmcd.uItemState & CDIS_SELECTED)
            color = RGB(157, 173, 215);
          else if (lpListDraw->nmcd.dwItemSpec % 2)
            color = RGB(240, 240, 240);
          else
            color = RGB(255, 255, 255);

          // paint
          HBRUSH hBrush = CreateSolidBrush(color);
          if (hBrush != NULL)
          {
            FillRect(lpListDraw->nmcd.hdc, &rect, hBrush);
            DeleteObject(hBrush);
          }

          // return color info
          lpListDraw->clrTextBk = color;
          return CDRF_NEWFONT;
        }
      }
      break;
  }
  return CDRF_DODEFAULT;
}

坦率地说,我完全不知道如何处理这个问题。有人有什么想法吗?

Here is a picture of my program:

WhiteFlag

As you can see, the icons aren't transparent, simply white. This is problematic, because I've coded the list-view to alternate colors and the white looks very ugly on grey.

Right now, I'm using a bitmap with a pink background for the icons, and using the pink color as a mask. Here's the code for my HIMAGELIST:

hImageList = ImageList_Create(16, 16,  ILC_COLOR32 | ILC_MASK, ICON_COUNT, 0);
if (hImageList != NULL)
{
  HBITMAP hBitmap = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_ICONS));
  if (hBitmap != NULL)
  {
    ImageList_AddMasked(hImageList, hBitmap, RGB(0xFF, 0, 0xFF)); // pink mask
    DeleteObject(hBitmap);
  }

  ImageList_SetBkColor(hImageList, CLR_NONE);
}
ListView_SetImageList(hWnd, hImageList, LVSIL_SMALL);

Here is the code for the list-view's Custom Draw (the alternating colors)

LRESULT WhiteFlagUI::PaintListView(__in HWND hwndListView, __in LPARAM lParam)
{
  LPNMLVCUSTOMDRAW lpListDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(lParam);

  switch (lpListDraw->nmcd.dwDrawStage)
  {
    case CDDS_PREPAINT:
      return (CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYSUBITEMDRAW);
      break;

    case (CDDS_PREPAINT | CDDS_ITEM):
      {
        RECT rect;

        if (ListView_GetSubItemRect(hwndListView, lpListDraw->nmcd.dwItemSpec, lpListDraw->iSubItem, LVIR_BOUNDS, &rect))
        {
          COLORREF color;

          // determine color
          if (lpListDraw->nmcd.uItemState & CDIS_SELECTED)
            color = RGB(157, 173, 215);
          else if (lpListDraw->nmcd.dwItemSpec % 2)
            color = RGB(240, 240, 240);
          else
            color = RGB(255, 255, 255);

          // paint
          HBRUSH hBrush = CreateSolidBrush(color);
          if (hBrush != NULL)
          {
            FillRect(lpListDraw->nmcd.hdc, &rect, hBrush);
            DeleteObject(hBrush);
          }

          // return color info
          lpListDraw->clrTextBk = color;
          return CDRF_NEWFONT;
        }
      }
      break;
  }
  return CDRF_DODEFAULT;
}

Quite frankly, I'm completely lost as to how to approach this. Does anyone have any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雪化雨蝶 2024-12-04 14:34:45

我发现了一些解决这个问题的办法。如果使用 ListView_SetBkImage 将背景图像设置为空白的白色位图,它将强制图标透明绘制。不幸的是,这样做会导致 NM_CUSTOMDRAW 忽略使用 CDRF_NEWFONT 设置的背景颜色。要解决这个问题,请调用 FillRect 来填充 CDDS_ITEMPREPAINT 中项目的背景,如果您还要更改前景色,则返回 CDRF_DODEFAULT 或 CDRF_NEWFONT。

I found a bit of a hack around this problem. If you set the background image to a blank white bitmap using ListView_SetBkImage it will force the icons to draw transparently. Unfortunately, doing this causes NM_CUSTOMDRAW to ignore the background color set with CDRF_NEWFONT. To get around it, call FillRect to fill background of the item in CDDS_ITEMPREPAINT and return CDRF_DODEFAULT or CDRF_NEWFONT if you are changing the foreground color as well.

拔了角的鹿 2024-12-04 14:34:45

我也面临着这个问题。
我通过添加 SetBkColor(RGB(...)) 解决了这个问题,其中 RGB(...) 在自定义绘制过程中从前景色交替到背景色。我使用白色背景的 16x16 4b BMP。我也设置了 clrTextBk,而不是使用 FillRect()。最后一个适用于文本。
正如我从 CListCtrl 的实验中看到的,函数 SetBkColor() 仅设置图标的背景颜色,而不设置文本的背景颜色(我在文档中没有找到任何相关内容)。

所有这些仅适用于非空项目。为了使用这种样式绘制空行,我重写了 OnEraseBkgnd() 通知函数。对于完全空的列表,绘制简单的矩形。

我希望这会帮助

奥莱克西

I was faced with this problem as well.
I've solved it by adding SetBkColor(RGB(...)) where RGB(...) alternates from foreground color to background one in the custom draw procedure. I use 16x16 4b BMP with white background. Instead of using FillRect(), I set clrTextBk too. The last works for texts.
As I see from my experiments with CListCtrl, function SetBkColor() sets background color for icons only and does not for text (I found nothing about this in docs).

All this works only for non-empty items. To draw empty rows with this style, I override OnEraseBkgnd() notification function. For fully empty list, simple rectangles are drawn.

I hope this will help

Olexiy

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文