Jun 152011
Here is a handy function I use to convert an icon to a HBITMAP. It’s not something you need to do very often, but very useful on the odd time when you need this functionality.
HBITMAP CMyDialog::ConvertIconToBitmap(HICON hIcon, int nWidth, int nHeight, COLORREF clrBackground)
{
if(hIcon == NULL)
return NULL;
HDC hDC = NULL;
HDC hMemDC = NULL;
HBITMAP hBitmap = NULL;
HBITMAP hOldBitmap = NULL;
HBRUSH hBrush = NULL;
HBRUSH hOldBrush = NULL;
BOOL bGotBitmap = false;
try {
hDC = ::GetDC(NULL);
if (hDC != NULL) {
hBitmap = CreateCompatibleBitmap(hDC, nWidth, nHeight);
if (hBitmap != NULL) {
hMemDC = CreateCompatibleDC(hDC);
if (hMemDC != NULL) {
// Select the bitmap into the memory device context
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
hBrush = CreateSolidBrush(clrBackground);
if (hBrush != NULL) {
// Fill the bitmap with the background color
hOldBrush = (HBRUSH)SelectObject(hMemDC, hBrush);
PatBlt(hMemDC, 0, 0, nWidth, nHeight, PATCOPY);
// Draw the icon
DrawIconEx(hMemDC, 0, 0, hIcon, nWidth, nHeight, 0, NULL, DI_NORMAL);
bGotBitmap = true;
}
}
}
}
// Cleanup
if (hOldBrush != NULL)
SelectObject(hMemDC, hOldBrush);
if (hOldBitmap != NULL)
SelectObject(hMemDC, hOldBitmap);
if (hBrush != NULL)
DeleteObject(hBrush);
if (hMemDC != NULL)
DeleteDC(hMemDC);
if (hDC != NULL)
::ReleaseDC(NULL, hDC);
if (!bGotBitmap && hBitmap != NULL) {
DeleteObject(hBitmap);
hBitmap = NULL;
}
}
catch(...) {
}
return hBitmap;
}
{
if(hIcon == NULL)
return NULL;
HDC hDC = NULL;
HDC hMemDC = NULL;
HBITMAP hBitmap = NULL;
HBITMAP hOldBitmap = NULL;
HBRUSH hBrush = NULL;
HBRUSH hOldBrush = NULL;
BOOL bGotBitmap = false;
try {
hDC = ::GetDC(NULL);
if (hDC != NULL) {
hBitmap = CreateCompatibleBitmap(hDC, nWidth, nHeight);
if (hBitmap != NULL) {
hMemDC = CreateCompatibleDC(hDC);
if (hMemDC != NULL) {
// Select the bitmap into the memory device context
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
hBrush = CreateSolidBrush(clrBackground);
if (hBrush != NULL) {
// Fill the bitmap with the background color
hOldBrush = (HBRUSH)SelectObject(hMemDC, hBrush);
PatBlt(hMemDC, 0, 0, nWidth, nHeight, PATCOPY);
// Draw the icon
DrawIconEx(hMemDC, 0, 0, hIcon, nWidth, nHeight, 0, NULL, DI_NORMAL);
bGotBitmap = true;
}
}
}
}
// Cleanup
if (hOldBrush != NULL)
SelectObject(hMemDC, hOldBrush);
if (hOldBitmap != NULL)
SelectObject(hMemDC, hOldBitmap);
if (hBrush != NULL)
DeleteObject(hBrush);
if (hMemDC != NULL)
DeleteDC(hMemDC);
if (hDC != NULL)
::ReleaseDC(NULL, hDC);
if (!bGotBitmap && hBitmap != NULL) {
DeleteObject(hBitmap);
hBitmap = NULL;
}
}
catch(...) {
}
return hBitmap;
}
To use this function simply pass in an icon.
HICON hIcon = ::LoadIcon(NULL, IDI_ERROR);
if(hIcon != NULL) {
hBmp = ConvertIconToBitmap(hIcon, 48, 48, RGB(255,255,255));
if(hBmp != NULL) {
CBitmap *cBmp = CBitmap::FromHandle(hBmp);
// Do whatever you need with the CBitmap
// ...
// Remember to clean up the hBmp
DeleteObject(hBmp);
// Note: in this case you don't have to destroy the icon since it's a system icon
}
}
if(hIcon != NULL) {
hBmp = ConvertIconToBitmap(hIcon, 48, 48, RGB(255,255,255));
if(hBmp != NULL) {
CBitmap *cBmp = CBitmap::FromHandle(hBmp);
// Do whatever you need with the CBitmap
// ...
// Remember to clean up the hBmp
DeleteObject(hBmp);
// Note: in this case you don't have to destroy the icon since it's a system icon
}
}
An example of a use for this function is converting an icon returned from a call to SHGetFileInfo to retrieve an icon for a file.
SHFILEINFO sfi;
SHGetFileInfo(
(LPCTSTR)strFileName,
FILE_ATTRIBUTE_NORMAL,
&sfi,
sizeof(SHFILEINFO),
SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES);
}
HBITMAP hBmp = ConvertIconToBitmap(sfi.hIcon, 48, 48, RGB(255,255,255));
SHGetFileInfo(
(LPCTSTR)strFileName,
FILE_ATTRIBUTE_NORMAL,
&sfi,
sizeof(SHFILEINFO),
SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES);
}
HBITMAP hBmp = ConvertIconToBitmap(sfi.hIcon, 48, 48, RGB(255,255,255));
Then you could use that bitmap to add to a CImageList just as if it were a bitmap you’d read from a file or resource:
if(hBmp != NULL) {
CBitmap *cBmp = CBitmap::FromHandle(hBmp);
if(cBmp != NULL)
m_imageList.Replace(0,cBmp,NULL);
}
CBitmap *cBmp = CBitmap::FromHandle(hBmp);
if(cBmp != NULL)
m_imageList.Replace(0,cBmp,NULL);
}