2017-01-08 68 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