Home > Mobile >  glfwSetWindowIcon from an embedded resource with transparency
glfwSetWindowIcon from an embedded resource with transparency

Time:06-16

I'm trying to achieve what almost every application does, and that's to have an embedded icon which I can show in the title bar and taskbar.

The requirements are:

  • The icon must support transparency
  • The icon must be embedded, not a separate file on the disk
  • The icon file format doesn't matter; can be ico, bmp or anything else that works.

I tried to create a bmp in paint.net, but LoadImage kept returning NULL. I recreated it as a 32-bit png, then used this tool to convert it to a 32-bit bmp, my reasoning for which being to get LoadImage working again, and this time with transparency. I'm using LoadImage because apparently LoadBitmap isn't so well-supported.

resources.rc:

100 BITMAP "icons\\icon.bmp"

code:

HBITMAP h_bmp = (HBITMAP)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(100), IMAGE_BITMAP, 0, 0, 0);

HDC dc = CreateCompatibleDC(NULL);
HBITMAP bmp_old = (HBITMAP)SelectObject(dc, h_bmp);
BITMAP bmp = {};
GetObject(h_bmp, sizeof(bmp), &bmp);

BITMAPINFO info;
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biWidth = bmp.bmWidth;
info.bmiHeader.biHeight = -bmp.bmHeight;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = bmp.bmBitsPixel;
info.bmiHeader.biCompression = BI_RGB;
info.bmiHeader.biSizeImage = ((bmp.bmWidth * bmp.bmBitsPixel   31) / 32) * 4 * bmp.bmHeight;

std::vector<unsigned char> pixels;
pixels.resize(info.bmiHeader.biSizeImage);
GetDIBits(dc, h_bmp, 0, bmp.bmHeight, &pixels[0], &info, DIB_RGB_COLORS);
SelectObject(dc, bmp_old);

DeleteDC(dc);

GLFWimage image = { bmp.bmWidth, bmp.bmHeight, &pixels[0] };
glfwSetWindowIcon(window, 1, &image);

There were two issues with the image; firstly it was displaying upside-down, hence the negation of the height above. Secondly, the RGB channels are flipped and I have no idea how to fix it.

So, is there a simpler way to do this, perhaps without having to suffer bmp formats and needing 3rd-party tools, and if not, how can I get the colours displaying properly?

CodePudding user response:

Windows (HWNDs) uses HICONs. A HICON is a handle to an icon loaded from a .ico file or an icon resource. A .ico file consists of one or more bmp and/or png files in various sizes. You should use a real icon editor to create your icon. You can find several free editors if you look around.

Once you have the ico file in your resources, load it with LoadImage(hInst, ..., IMAGE_ICON, ..., LR_SHARED) and apply it with SetClassLongPtr or WM_SETICON.

CodePudding user response:

Solved as per @user253751's comment;

SetClassLongPtr(glfwGetWin32Window(window), GCLP_HICON, (LONG_PTR)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(100)));

Much simpler than I expected!

  • Related