2017-01-08 44 views
1

我想使用C++和Win API以编程方式创建32位颜色图标。为此我使用以下代码,我发现here以编程方式创建32位颜色图标

HICON CreateSolidColorIcon(COLORREF iconColor, int width, int height) 
{ 
    // Obtain a handle to the screen device context. 
    HDC hdcScreen = GetDC(NULL); 

    // Create a memory device context, which we will draw into. 
    HDC hdcMem = CreateCompatibleDC(hdcScreen); 

    // Create the bitmap, and select it into the device context for drawing. 
    HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, width, height); 
    HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcMem, hbmp); 

    // Draw your icon. 
    // 
    // For this simple example, we're just drawing a solid color rectangle 
    // in the specified color with the specified dimensions. 
    HPEN hpen = CreatePen(PS_SOLID, 1, iconColor); 
    HPEN hpenOld = (HPEN)SelectObject(hdcMem, hpen); 
    HBRUSH hbrush = CreateSolidBrush(iconColor); 
    HBRUSH hbrushOld = (HBRUSH)SelectObject(hdcMem, hbrush); 
    Rectangle(hdcMem, 0, 0, width, height); 
    SelectObject(hdcMem, hbrushOld); 
    SelectObject(hdcMem, hpenOld); 
    DeleteObject(hbrush); 
    DeleteObject(hpen); 

    // Create an icon from the bitmap. 
    // 
    // Icons require masks to indicate transparent and opaque areas. Since this 
    // simple example has no transparent areas, we use a fully opaque mask. 
    HBITMAP hbmpMask = CreateCompatibleBitmap(hdcScreen, width, height); 
    ICONINFO ii; 
    ii.fIcon = TRUE; 
    ii.hbmMask = hbmpMask; 
    ii.hbmColor = hbmp; 
    HICON hIcon = CreateIconIndirect(&ii); 
    DeleteObject(hbmpMask); 

    // Clean-up. 
    SelectObject(hdcMem, hbmpOld); 
    DeleteObject(hbmp); 
    DeleteDC(hdcMem); 
    ReleaseDC(NULL, hdcScreen); 

    // Return the icon. 
    return hIcon; 
} 

原则上,代码工作,我可以使用它在运行时使用Win API创建彩色图标。不过,我想讨论一些有关该代码的问题和疑问(以及通常创建的图标)。

  • 使用此功能创建的图标似乎不是32位颜色深度。如果我使用像RGB这样的颜色(218,112,214),我会期望它是一些浅紫色。但是,实际显示的颜色是灰色的。我怎样才能改变代码的颜色是真正的32位RGB?
  • 创建的图标完全充满了颜色,我想在它周围有一个薄薄的黑色边框......这怎么能实现?
  • 在MSDN documentation(有点向下)中提到,“之前关闭,您的应用程序必须使用DestroyIcon摧毁它通过使用CreateIconIndirect创建的图标。这是没有必要破坏其他功能创建的图标。”但是,在例如文档中CreateIcon在MSDN中,据说“当您完成使用图标后,使用DestroyIcon函数销毁它。”这几乎是一个矛盾。我什么时候需要销毁图标?
  • 当我将图标添加到图像列表并将此列表添加到组合框时,这些规则是否也适用?即我必须清理图像列表和每个关联的图标吗?

任何帮助,高度赞赏。

+0

嗯,这面具看起来并不像一个适当的口罩。它在AND操作中使用,因此您可以简单地使用hbmp。 –

+0

是,对于面膜需要使用'CreateBitmap'用'cBitsPerPel == 1'改为'CreateCompatibleBitmap',颜色也与'cBitsPerPel == 32'与''CreateBitmap' RGB'你不使用阿尔法 – RbMm

+0

嗯,但在MSDN文档的CreateBitmap它说,对于彩色位图,出于性能原因,应该使用CreateCompatibleBitmap而不是CreateBitmap,所以不应该同时工作?我试图为位图和hbmpMask = CreateBitmap(宽度,高度,1,1,0)的CreateBitmap(宽度,高度,1,32,0),但没有改变(但我不知道其余的参数像例如lpvBits) – SampleTime

回答

3

我什么时候需要销毁图标?

了解DestroyIcon

它是只需要调用DestroyIcon为具有以下功能创建的图标和光标 :CreateIconFromResourceEx(如果 称为无LR_SHARED标志),CreateIconIndirectCopyIcon。请勿使用此功能销毁共享图标。 A 共享图标是有效的,只要加载它的模块 保留在内存中。以下功能获取共享图标。

  • LoadIcon
  • ​​(如果使用LR_SHARED标志)
  • CopyImage(如果使用LR_COPYRETURNORG标志和hImage参数是共享图标)
  • CreateIconFromResource
  • CreateIconFromResourceEx(如果使用LR_SHARED标志)

所以你需要调用DestroyIcon不共享图标,当你使用它

ComboBoxEx不会破坏你分配给它CBEM_SETIMAGELIST图像列表完成 - 所以这个图像列表必须是有效的,直到ComboBoxEx有效你以后必须自己摧毁它。

ImageList_AddIcon

由于系统不保存惠康,你可以在 宏返回

换句话说 ImageList_AddIcon使 复制你的图标

后销毁它,你可以摧毁你原来的图标,宏观回报

后创建32位彩色图标尝试这样的代码:

HICON CreateGradientColorIcon(COLORREF iconColor, int width, int height) 
{ 
    HICON hIcon = 0; 

    ICONINFO ii = { TRUE }; 

    ULONG n = width * height; 

    if (PULONG lpBits = new ULONG[n]) 
    { 
     PULONG p = lpBits; 

     ULONG x, y = height, t; 
     do 
     { 
      x = width, t = --y << 8; 
      do 
      { 
       *p++ = iconColor | ((t * --x)/n << 24); 
      } while (x); 

     } while (y); 

     if (ii.hbmColor = CreateBitmap(width, height, 1, 32, lpBits)) 
     { 
      if (ii.hbmMask = CreateBitmap(width, height, 1, 1, 0)) 
      { 
       hIcon = CreateIconIndirect(&ii); 

       DeleteObject(ii.hbmMask); 
      } 

      DeleteObject(ii.hbmColor); 
     } 

     delete [] lpBits; 
    } 

    return hIcon; 
} 

当我画(DrawIconEx(, DI_IMAGE|DI_MASK))该图标在绿色网格我认为未来:

enter image description here

+0

谢谢你,只是一句话:功能预计BGR格式的颜色,没有RGB(我花了相当多的去弄清楚:d) – SampleTime

+1

@SampleTime - 是的,我混淆了颜色顺序。真的在'COLORREF iconColor'中最低字节必须是蓝色。当'RGB'使用红色作为最低字节时。因为在RGB(218,112,214)中'红色和蓝色几乎相等 - 我没有注意到这一点 – RbMm