2011-09-10 65 views
4

如何將HICON轉換爲VC++中的HBITMAP?如何將HICON轉換爲VC++中的HBITMAP?

我知道這是一個常見問題解答,但我在Google上找到的所有解決方案都不起作用。我需要的是一個函數,它需要一個參數HICON並返回HBITMAP。

即使圖標是24位,16位或8位,如果可能轉換爲32位位圖,也是最大的。

這是代碼,我不知道哪裏出了問題:

HBITMAP icon_to_bitmap(HICON Icon_Handle) { 
    HDC Screen_Handle = GetDC(NULL); 
    HDC Device_Handle = CreateCompatibleDC(Screen_Handle); 

    HBITMAP Bitmap_Handle = 
    CreateCompatibleBitmap(Device_Handle,GetSystemMetrics(SM_CXICON), 
    GetSystemMetrics(SM_CYICON)); 

    HBITMAP Old_Bitmap = (HBITMAP)SelectObject(Device_Handle,Bitmap_Handle); 
    DrawIcon(Device_Handle, 0,0, Icon_Handle); 
    SelectObject(Device_Handle,Old_Bitmap); 

    DeleteDC(Device_Handle); 
    ReleaseDC(NULL,Screen_Handle); 
    return Bitmap_Handle; 
} 

回答

4

我沒有代碼,隨時可以分享,但我認爲這是很容易的。您必須創建HBITMAP,創建設備上下文,選擇位圖到DC中(這將使位圖成爲此DC的繪圖區域)。最後調用DrawIcon()函數在此DC上繪製圖標。之後,從DC中分離位圖並銷燬DC。你的位圖現在應該準備好了。看你的代碼後,

更新:

我相信這個問題是在createCompatibleBitmap通話。您要求與內存DC兼容的位圖,但內存DC以1比特/像素位圖爲起點。試着要求與屏幕DC兼容的位圖。

更新2:你可能想看看this question,因爲它似乎與你的問題有關。

+0

我正在做同樣的事情,但得到的位圖總是1bit /像素。很奇怪....... – jondinham

+1

請用示例代碼展開您的問題。聽起來像你的位圖不是用正確的比特/像素創建的,但不能肯定地說不看代碼。 – Miguel

+0

添加了代碼,從屏幕創建的DC,因此它應該是32位/像素,請看看.... – jondinham

6
HDC hDC = GetDC(NULL); 
HDC hMemDC = CreateCompatibleDC(hDC); 
HBITMAP hMemBmp = CreateCompatibleBitmap(hDC, x, y); 
HBITMAP hResultBmp = NULL; 
HGDIOBJ hOrgBMP = SelectObject(hMemDC, hMemBmp); 

DrawIconEx(hMemDC, 0, 0, hIcon, x, y, 0, NULL, DI_NORMAL); 

hResultBmp = hMemBmp; 
hMemBmp = NULL; 

SelectObject(hMemDC, hOrgBMP); 
DeleteDC(hMemDC); 
ReleaseDC(NULL, hDC); 
DestroyIcon(hIcon); 
return hResultBmp; 
4

這段代碼做到這一點:

HICON hIcon = (HICON)LoadImage(instance, MAKEINTRESOURCEW(IDI_ICON), IMAGE_ICON, width, height, 0); 
ICONINFO iconinfo; 
GetIconInfo(hIcon, &iconinfo); 
HBITMAP hBitmap = iconinfo.hbmColor; 

,這是在* .rc文件中的代碼:

IDI_ICON ICON "example.ico" 

,這是在* .h文件中的代碼:

#define IDI_ICON 4000 
+0

你能詳細說明這個解決方案嗎? 'hbmColor'是否足以代表HBITMAP中的圖標?那麼'hbmMask'呢? – hackjutsu

2

我發現這個(類似的代碼適用於我 - 帶有或wi的32x32圖標thout阿爾法數據):
   使用CopyImage (msdn link)

HICON hICON = /*your code here*/ 
HBITMAP hBITMAPcopy; 
ICONINFOEX IconInfo; 
BITMAP BM_32_bit_color; 
BITMAP BM_1_bit_mask; 

// 1. From HICON to HBITMAP for color and mask separately 
//.cbSize required 
//memset((void*)&IconInfo, 0, sizeof(ICONINFOEX)); 
IconInfo.cbSize = sizeof(ICONINFOEX); 
GetIconInfoEx(hICON , &IconInfo); 


//HBITMAP IconInfo.hbmColor is 32bit per pxl, however alpha bytes can be zeroed or can be not. 
//HBITMAP IconInfo.hbmMask is 1bit per pxl 

// 2. From HBITMAP to BITMAP for color 
// (HBITMAP without raw data -> HBITMAP with raw data) 
//   LR_CREATEDIBSECTION - DIB section will be created, 
//   so .bmBits pointer will not be null 
hBITMAPcopy = (HBITMAP)CopyImage(IconInfo.hbmColor, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); 
// (HBITMAP to BITMAP) 
GetObject(hBITMAPcopy, sizeof(BITMAP), &BM_32_bit_color); 
//Now: BM_32_bit_color.bmBits pointing to BGRA data.(.bmWidth * .bmHeight * (.bmBitsPixel/8)) 

// 3. From HBITMAP to BITMAP for mask 
hBITMAPcopy = (HBITMAP)CopyImage(IconInfo.hbmMask, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); 
GetObject(hBITMAPcopy, sizeof(BITMAP), &BM_1_bit_mask); 
//Now: BM_1_bit_mask.bmBits pointing to mask data (.bmWidth * .bmHeight Bits!) 

BM_32_bit_color位圖可以具有阿爾法*通道*(各4字節)已經設置!所以 - 在你將掩碼位添加到顏色數據之前檢查它。