简体   繁体   中英

Creating an HICON from an existing HICON by painting it to an HBITMAP

As part of a bigger project, I'm trying to create an HICON from an existing HICON by first painting that icon to an HBITMAP, then converting it back to an HICON. (This will allow me to modify the icon, for example, by drawing text on it.)

Unfortunately, the icon is showing up as a black square. Here is my code:

bool createIcon()
{
  bool ret = false;

  // get context of window
  HDC context = GetDC(window_);
  if (context != NULL)
  {
    // create a buffer context
    HDC buffer = CreateCompatibleDC(context);
    if (buffer != NULL)
    {
      PatBlt(buffer, 0, 0, iconSize_, iconSize_, WHITENESS);

      // create a bitmap for our use
      HBITMAP bitmap = CreateCompatibleBitmap(context, iconSize_, iconSize_);
      if (bitmap != NULL)
      {
        HBITMAP oldBitmap;

        // select the bitmap with the buffer
        oldBitmap = reinterpret_cast<HBITMAP>(SelectObject(buffer, bitmap));
        if (oldBitmap != NULL)
        {          
          // draw the icon
          if (DrawIcon(buffer, 0, 0, icon_))
          {
            if (icon_ != NULL)
              DestroyIcon(icon_);

            ImageList_RemoveAll(imageList_);
            if (ImageList_Add(imageList_, bitmap, NULL) != -1)
            {
              icon_ = ImageList_GetIcon(imageList_, 0, ILD_NORMAL);
              if (icon_ != NULL)
                ret = true;
            }
          }          
          SelectObject(buffer, oldBitmap);
        }
        DeleteObject(bitmap);
      }
      DeleteDC(buffer);
    }
    DeleteDC(context);
  }
  return ret;
}

Any ideas?

Perhaps you would want to check if the bitmap itself it black, or it is good and it is only the icon is black. From my experience (I don't have reasonable explanation of this though), the problem is around CreateCompatibleBitmap and I would expect the bitmap itself be already black. Try CreateDIBSection instead. This used to work for me:

//HBITMAP hBitmap = CreateCompatibleBitmap(hDc, ResourceIconColorBitmap.bmWidth, ResourceIconColorBitmap.bmHeight);
BITMAPINFO BitmapInformation;
ZeroMemory(&BitmapInformation, sizeof BitmapInformation);
BitmapInformation.bmiHeader.biSize = sizeof BitmapInformation.bmiHeader;
BitmapInformation.bmiHeader.biWidth = ResourceIconColorBitmap.bmWidth;
BitmapInformation.bmiHeader.biHeight = ResourceIconColorBitmap.bmHeight;
BitmapInformation.bmiHeader.biPlanes = 1;
BitmapInformation.bmiHeader.biBitCount = 24;
VOID* pvBits;
HBITMAP hBitmap = CreateDIBSection(hDc, &BitmapInformation, DIB_RGB_COLORS, &pvBits, NULL, 0);
ICONINFO nfo;
GetIconInfo(icon_, &nfo);
MyDrawSomethingOnIcon(nfo.hbmColor);
HICON new_icon = CreateIconIndirect(&nfo);

All you need to do is to implement MyDrawSomethingOnIcon . And of course you must free all used icons and bitmaps when they aren't used anymore. MSDN will help you to handle that =)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM