ListList上的ImageList透明度?

编辑:我提供了一个赏金,因为我怀疑我会得到任何答案,否则。

最近我一直在使用列表视图,我决定为每个项目添加一个图标 ,指明它是input还是输出。 图标添加好,但它们不透明:

图标不透明的例子

可以看出,图标显然不透明。 我目前正在做这样的负载图标:

hImageList = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 2, 2); if (hImageList != NULL) { iIN = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(101))); iOUT = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(102))); } 

我试图搞乱ImageList_CreateLoadImage / LoadImage的标志,但没有运气,说实话,我已经用完了想法。

任何帮助将非常感激。

Solutions Collecting From Web of "ListList上的ImageList透明度?"

首先,ImageList_ReplaceIcon在将图标数据添加到图像列表中时复制图标数据。 所以HICON需要在之后发布。

接下来,图像列表本地位图,而不是图标。 而你正在创建你的图像列表的方式使图标转换为位图非常模糊。 ILC_COLOR32意味着图像列表应该被创建为一个32位二进制部分,通常通过一个嵌入的alpha通道包含透明度信息。 ILC_MASK意味着内部位图是DDB位图,透明度信息存储为1bpp掩码位图。

解决您的问题的最快捷方式 – 带上您的两个图标:

  • 把它们合并成一个32位宽16位的单个位图资源。 用蒙版颜色填充背景: – 紫色或其他东西。
  • 使用ILC_COLOR | ILC_MASK创建位图
  • 加载位图,确保不要使用LR_TRANSPARENT。
  • 使用ImageList_AddMasked添加在表示遮罩颜色的COLORREF中传递的位图。

或者,为了更好的视觉效果…

  • 将您的PNG数据导出为包含预乘alpha通道数据的32×16 32bpp位图文件。
  • 使用ILC_COLOR32值创建图像列表。
  • LoadImage()与LR_CREATEDIBSECTION加载位图作为一个32bpp dib部分。
  • 使用ImageList_Add()添加图像

(最后一个选项是有点棘手的,因为支持写入32位bmp文件的工具的数量相当低)。


编辑添加下面的代码示例。 使用在开发环境中创建的一个4bpp位图,这个工作很好:

 HWND hwndCtl = CreateWindowEx(0,WC_LISTVIEW,TEXT("ListView1"),WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL,0,0,cx,cy,hWnd,(HMENU)101,hmodulee,NULL); HBITMAP hbm = (HBITMAP)LoadImage(hmodulee,MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP,0,0,0); COLORREF crMask=RGB(255,0,255); HIMAGELIST himl = ImageList_Create(16,16,ILC_COLOR|ILC_MASK,2,0); ImageList_AddMasked(himl,hbm,crMask); ListView_SetImageList(hwndCtl,himl,LVSIL_NORMAL); 

你想让你的图标有一个背景颜色,而不是在图标的其他地方使用,就像一个非常难看的紫色,然后使用LoadImage(…,LR_LOADTRANSPARENT); 该标志说在0,0看第一个像素,并使所有的颜色透明。

你的代码对我来说看起来很好,我总是使用LoadImage而不是LoadIcon,但我怀疑这并不重要。 你有没有检查图标确实有透明领域,并没有一个坚实的背景?

我的LoadImage调用如下所示:

 HICON hIcon = (HICON)LoadImage(hinstResources,MAKEINTRESOURCE(IDI_ICON),IMAGE_ICON,16,16,LR_DEFAULTCOLOR); 

这里…按照建议创建一个ImageList,使你的图标变成一个16像素高的位图,长16 * n,其中n =图标的数量…

设置背景颜色为255,0,255,就像你所做的一样。

然后,加载它,并像我这样在图像列表中添加它:

  m_ImageList.Create(16, 16, ILC_COLOR16 | ILC_MASK, 7, 1); CBitmap bm; bm.LoadBitmap(IDB_SUPERTREEICONS); m_ImageList.Add(&bm, RGB(255, 0, 255)); GetTreeCtrl().SetImageList(&m_ImageList, TVSIL_NORMAL); 

当然,这是用MFC编写的,但是如你所知,它只是Win32的一个包装。

除此之外,你将不得不去一个自定义的绘制控制,在这个控制中,你可以在图标碰巧坐在的任何背景上绘制图标。 我知道,在这些控制中,没有任何魔术“透明”的颜色。

在自定义绘制的情况下,您需要使用如下所示的代码:

 #define TRANSPARENT_COLOR (255,0,255) UINT iBitmap = IDB_ICON_UP CDC *dc = GetDC(); int x = 0, y = 0; CDC *pDisplayMemDC = new CDC; CDC *pMaskDC = new CDC; CDC *pMemDC = new CDC; CBitmap *pBitmap = new CBitmap; CBitmap *pMaskBitmap = new CBitmap; CBitmap *pMemBitmap = new CBitmap; int cxLogo, cyLogo; BITMAP bm; pBitmap->LoadBitmap(iBitmap); pDisplayMemDC->CreateCompatibleDC(dc); CBitmap *pOldBitmap = (CBitmap *)pDisplayMemDC->SelectObject(pBitmap); pBitmap->GetObject(sizeof(bm), &bm); cxLogo = bm.bmWidth; cyLogo = bm.bmHeight; pMaskBitmap->CreateBitmap(cxLogo, cyLogo, 1, 1, NULL); pMaskDC->CreateCompatibleDC(dc); CBitmap *pOldMask = (CBitmap *)pMaskDC->SelectObject(pMaskBitmap); COLORREF oldBkColor = pDisplayMemDC->SetBkColor(TRANSPARENT_COLOR); pMaskDC->BitBlt(0, 0, cxLogo, cyLogo, pDisplayMemDC, 0, 0, SRCCOPY); pMemBitmap->CreateCompatibleBitmap(dc, cxLogo, cyLogo); pMemDC->CreateCompatibleDC(dc); CBitmap *pOldMem = (CBitmap *)pMemDC->SelectObject(pMemBitmap); pMemDC->BitBlt(0, 0, cxLogo, cyLogo, dc, x, y, SRCCOPY); pMemDC->BitBlt(0, 0, cxLogo, cyLogo, pDisplayMemDC, 0, 0, SRCINVERT); pMemDC->BitBlt(0, 0, cxLogo, cyLogo, pMaskDC, 0, 0, SRCAND); pMemDC->BitBlt(0, 0, cxLogo, cyLogo, pDisplayMemDC, 0, 0, SRCINVERT); dc->BitBlt(x, y, cxLogo, cyLogo, pMemDC, 0, 0, SRCCOPY); delete pMemDC->SelectObject(pOldMem); delete pMemDC; delete pMaskDC->SelectObject(pOldMask); delete pMaskDC; delete pDisplayMemDC->SelectObject(pOldBitmap); delete pDisplayMemDC; 

此代码决定在哪里绘制图标,并为背景拍摄快照,为图标创建一个遮罩,然后在背景上绘制遮罩,为其提供完全透明的背景。

希望有所帮助。 如果没有,请更详细地解释你正在试图发生的事情,你看到什么,或者你没有看到什么…