Last week I needed to load a bitmap transparently. It contained the icons I wanted to use in a tree control. That's when I detected the bug.
LoadImage() work? Well, of course you can find that in MSDN. But there's one thing I'd like to quote. When you use the function with the parameter
LR_LOADTRANSPARENT, MSDN says:
Retrieves the color value of the first pixel in the image and replaces the corresponding entry in the color table with the default window color (
COLOR_WINDOW). All pixels in the image that use that entry become the default window color. This value applies only to images that have corresponding color tables. Do not use this option if you are loading a bitmap with a color depth greater than 8bpp.
Well, my experience is that "retrieves the color of the first pixel in the image" should be replaced by "retrieves the first 8 bits in the image".
What do I mean?
I made a bitmap with a color depth of 4 bits per pixel. (see the base bitmap Bitmap01 in the figure).
Now, I expected the red square in the middle of the icon to become transparent, if I made the lower left pixel in the bitmap red.
That doesn't seem to work. (see the second tree item icon). If I make two pixels red, it works. (see the third tree item icon)
For a 8bpp bitmap it does work as expected as you can see in the figure.
I made a small application demonstrating the bug.
LoadImage() doesn't take at the color of the first pixel to determine the color that must be replaced by the default window color, it takes at the first 8 bits. (being two pixels in a 4bpp bitmap)
- Don't use 4bpp bitmaps
- If you like to use 4bpp bitmaps then make sure the two lower left pixels are of the same color. The color you want to be replaced by the window's color.
- Don't trust the transparently loading of the bitmap to LoadImage() and do it yourself: Use
LoadImage() to load the bitmap as it is. Then replace the color of your choice with the window's color.
If you're really interested in this solution take a look at the available code of the demo project.
- I am not able to test this out for VC7.
- If someone would be so kind as to compile my little app in VC7 and let me know?
- "the first pixel" of a bitmap is de the lower left pixel of the bitmap and not the upper left as you would expect. For the explanation see some remarks posted beneath this article.
Thanks to Davide Calabro for his article "CreateGrayScaleIcon" [^] where I got the inspiration for my function to change icon colors.