ListViews的ImageLists中的透明图像

时间:2011-08-01 00:55:03

标签: c++ winapi listview transparency imagelist

以下是我的节目图片:

WhiteFlag

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

现在,我正在使用bitmap with a pink background作为图标,并使用粉红色作为蒙版。这是我的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;
}

坦率地说,我完全迷失了如何处理这个问题。有没有人有任何想法?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

所有这些仅适用于非空物品。要使用此样式绘制空行,我会覆盖OnEraseBkgnd()通知函数。对于完全空列表,绘制简单的矩形。

我希望这会有所帮助

Olexiy