Link to home
Start Free TrialLog in
Avatar of jmayfield
jmayfield

asked on

How do you convert a HICON to HBITMAP

I need the following function:

HBITMAP IconToBitmap(HICON hIcon);
Avatar of chensu
chensu
Flag of Canada image

1. Create a memory DC (CreateCompatibleDC).
2. Create a bitmap (CreateCompatibleBitmap).
3. Select the bitmap into the memory DC.
4. Draw the icon (DrawIcon).
5. Deselect the bitmap.
6. Delete the DC.
7. Return the bitmap handle.
This technical article may help.

Icons in Win32
http://msdn.microsoft.com/library/techart/msdn_icons.htm
Avatar of jmayfield
jmayfield

ASKER

Out of curiosity, GetObject returns the size of a bitmap. Does GetObject also return the size of an icon?

Also, how do you deselect an object after using SelectObject?
I'm going to give you the points, but I'm just coding it up now in case I have any problems.

Thanks for the prompt answer and excellent info.
I'm going to give you the points, but I'm just coding it up now in case I have any problems.

Thanks for the prompt answer and excellent info.
I'm going to give you the points, but I'm just coding it up now in case I have any problems.

Thanks for the prompt answer and excellent info.
I'm going to give you the points, but I'm just coding it up now in case I have any problems.

Thanks for the prompt answer and excellent info.
I'm going to give you the points, but I'm just coding it up now in case I have any problems.

Thanks for the prompt answer and excellent info.
>Does GetObject also return the size of an icon?

No, it doesn't. But, there is a way to get the size of an icon. Use GetIconInfo, which returns HBITMAP hbmMask. Then use GetObject on the hbmMask.

>how do you deselect an object after using SelectObject?

HBITMAP hOldBmp = SelectObject(hdc, hBmp);

//...

SelectObject(hdc, hOldBmp);
Nice steps above, but what is wrong with the following code?

HBITMAP IconToBitmap(HICON hIcon,int Width,int Height)
{
  if(!hIcon) return NULL;

  HBITMAP hBitmap = NULL;
  HBITMAP hOldBitmap = NULL;
  HDC hDC = NULL;
  HDC ScreenDC = GetDC(NULL);

  hDC = CreateCompatibleDC(ScreenDC);
  ReleaseDC(NULL,ScreenDC);
  if(!hDC)
  {
    MessageBoxDebug("Failed on CreateCompatibleDC");
    return NULL;
  }

  hBitmap = CreateCompatibleBitmap(hDC,
                                   Width,
                                   Height);
  if(!hBitmap)
  {
    MessageBoxDebug("Failed on CreateCompatibleBitmap");
    ReleaseDC(NULL,hDC);
    return NULL;
  }

  hOldBitmap = (HBITMAP)SelectObject(hDC,hBitmap);
  if(!DrawIcon(hDC,0,0,hIcon))
  {
    MessageBoxDebug("Failed on DrawIcon");
    ReleaseDC(NULL,hDC);
    return NULL;
  }

  SelectObject(hDC,hOldBitmap);

  ReleaseDC(NULL,hDC);

  return hBitmap;
}

Nice steps above, but what is wrong with the following code?

HBITMAP IconToBitmap(HICON hIcon,int Width,int Height)
{
  if(!hIcon) return NULL;

  HBITMAP hBitmap = NULL;
  HBITMAP hOldBitmap = NULL;
  HDC hDC = NULL;
  HDC ScreenDC = GetDC(NULL);

  hDC = CreateCompatibleDC(ScreenDC);
  ReleaseDC(NULL,ScreenDC);
  if(!hDC)
  {
    MessageBoxDebug("Failed on CreateCompatibleDC");
    return NULL;
  }

  hBitmap = CreateCompatibleBitmap(hDC,
                                   Width,
                                   Height);
  if(!hBitmap)
  {
    MessageBoxDebug("Failed on CreateCompatibleBitmap");
    ReleaseDC(NULL,hDC);
    return NULL;
  }

  hOldBitmap = (HBITMAP)SelectObject(hDC,hBitmap);
  if(!DrawIcon(hDC,0,0,hIcon))
  {
    MessageBoxDebug("Failed on DrawIcon");
    ReleaseDC(NULL,hDC);
    return NULL;
  }

  SelectObject(hDC,hOldBitmap);

  ReleaseDC(NULL,hDC);

  return hBitmap;
}

 //...

  hDC = CreateCompatibleDC(ScreenDC);
   
  if(!hDC)
  {
    MessageBoxDebug("Failed on CreateCompatibleDC");
    return NULL;
  }

  hBitmap = CreateCompatibleBitmap(ScreenDC,
                                   Width,
                                   Height);

  ReleaseDC(NULL,ScreenDC);

  //...

  DeleteDC(hDC);

  //...
Still no go. I get a black bitmap with a few white dots. I have also tried DrawIconEx. It draws a little different black square with different white dots. CreateCompatibleBitmap from the ScreenDC did not change anything. Any other ideas?
That function should work, as long as the icon handle is ok.  How are you getting the icon handle?

When you create a new bitmap, it will initially be filled with random bits.  If your icon has any transparent parts, you will want to set the background color to the color of your choice.  If white or black, you could do something similar to the following:  PatBlt (hDC, 0, 0, Width, Height, WHITENESS);

You may also want to provide your own DC to the function to make sure the icon is ok.  You could do something like this in a test window's WM_PAINT message:

case WM_PAINT:
   PAINTSTRUCT ps;
   HDC hDC = BeginPaint (hWnd, &ps);
   HBITMAP hBmp = IconToBmp (hDC, hIcon, cxIcon, cyIcon);
   HDC hMemDC = CreateCompatibleDC (hDC);
   HBITMAP hOldMemBmp = SelectObject (hMemDC, hBmp);
   
   BitBlt (hDC, 10, 10, cxIcon, cyIcon, hMemDC, 0, 0, SRCCOPY);

   SelectObject (hMemDC, hOldMemBmp);
   DeleteDC (hMemDC);
   DeleteObject (hBmp);

   DrawIcon (hDC, 50, 10, hIcon);

   EndPaint (hWnd, &ps);
   break;
I got it to work. Two things must be added.

1. FillRect(hDC,&Rect,GetSysColorBrush(COLOR_WINDOW));
2. Must use DrawIconEx.

chensu, if you propose an answer again, I will give you the points.

Thank you very much for the steps.

1. CreateCompatibleBitmap must use ScreenDC.

2. Is the icon 256-color or 16-color?

3. Try DrawIcon to the screen.
ASKER CERTIFIED SOLUTION
Avatar of chensu
chensu
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
There is also a second way of doing this.

1. GetIconInfo
2. Use the ICONINFO hbmMask and hbmColor to copy it onto a DC.