如何在VC ++中将HICON转换为HBITMAP?

时间:2011-09-10 22:07:29

标签: c++ winapi visual-c++ bitmap icons

如何在VC ++中将HICON转换为HBITMAP?

我知道这是一个常见问题,但我在Google上找到的所有解决方案都不起作用。我需要的是一个带参数HICON并返回HBITMAP的函数。

如果可能的话,最好转换为32位位图,即使图标是24位,16位或8位。

这是代码,我不知道它出错的地方:

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 个答案:

答案 0 :(得分:7)

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;

答案 1 :(得分:4)

我没有可供分享的代码,但我认为这很容易。您必须创建HBITMAP,创建设备上下文,在DC中选择位图(这将使位图成为此DC的绘图区域)。最后调用DrawIcon()函数在此DC上绘制图标。之后,从DC分离位图并销毁DC。你的位图现在应该准备好了。

查看代码后更新:

我认为问题出在createCompatibleBitmap调用中。您要求与内存DC兼容的位图,但内存DC以选择的1位/像素位图开始。请尝试寻求与屏幕DC兼容的位图。

更新2:您可能希望查看this question,因为它似乎与您的问题有关。

答案 2 :(得分: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

答案 3 :(得分:2)

我发现了这个(类似的代码适用于我 - 带或不带alpha数据的32x32图标):
使用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 位图可能已经设置了Alpha *通道*(每个第4个字节)!所以 - 在将掩码位添加到颜色数据之前检查它。