UAC Shield in menus?
Thankfully there's an easy way to add the UAC shield to buttons by using BCM_SETSHIELD. I wonder though - is there a similar option for menus somewhere? The docs say that context menus are supported via DefCM but I'm really looking to add the shield icon to a generic popup menu. Can I do this without ownerdrawing it?
-Marton
[341 byte] By [
martona] at [2007-12-27]
MIIM_BITMAP has been around since 2000.
Yes it has, thank you for the elaborate answer.
Now I can choose between the following:
1) LoadIcon SIID_SHIELD, convert the icon to a HBITMAP using one of the many (not so) elegant solutions, specify MIIM_BITMAP and the HBITMAP, and watch the transparency information disappear - not so great when you also want the icon to look in the highlighted state.
2) Specify MIIM_BITMAP and HBMMENU_CALLBACK, handle WM_MEASUREITEM and WM_DRAWITEM, and LoadIcon and DrawIconEx SIID_SHIELD when needed.
I didn't really say it was impossible to do... I was just asking if there was a shortcut to do this. SendMessage is pretty elegant for buttons, and I thought there was a similarly succint counterpart for menus.
-Marton
Method 1 is what the shell uses. Of course your bitmap needs to have an alpha channel for the transparency to work.
'98 or 2000 is not really the issue here. You still need to ownerdraw your bitmaps if you want the icons to look good. Contrary to what's been suggested here, transparency does not really work. (Try saving a bitmap with alpha channel and the LoadBitmap-ing it, then setting it as the hbmpItem.) Unless I am missing something and you need to use some extra-special bitmap format here.
Even if this were solved: If we want to stick with my original question, you still have the problem of extracting such a 32bpp bitmap from an HICON, which is a whole other can of worms.
From what I can gather, it's plain old ARGB format but if you say that doesn't work then I'll have to take your word for it.
martona, instead of using LoadBitmap (which is obsolete, as is LoadIcon, LoadCursor, etc), use LoadImage with LR_CREATEDIBSECTION
Woohoo!
This works as Raymond said it would. Pretty neat.
Still, I have to copy the a 16x16 version of the shield icon amongst my resources as a bitmap.
Would anyone have any idea on how to programmatically extract the 32bpp HBITMAP from a HICON? GetIconInfo strips the transparency info.
I've tried to get the UAC icon to appear in a menu with true transparency, but I am experiencing a strange problem with the alpha channel. It is not working properly, it appears as if the alpha channel were getting converted into a 1-bit alpha channel.
I have extracted the 16x16, 32-bit version of the UAC icon from USER32.DLL and saved it as a 32-bit BMP file using GIF Movie Gear. I have included the BMP in my module's resources. I am using LoadImage with LR_CREATEDIBSECTION to load the image, and I am using MIIM_BITMAP in MENUITEMINFO.
The image appears in the menu but the borders of the image do not look perfect. There are white pixels there. That is, the image is not blending to the menu background as it should.
The strangest thing is that I can get perfect results with another 32-bit BMP file. I don't have any clue why the alpha channel is not working properly for me with the UAC bitmap even though it is working fine when I use the other BMP file. Everything else is the same, I just use a different BMP file for the second menu item.
The BMP files and a screenshot are available in the following location:
http://motivesys02.motivesys.com/download/UAC/UACShield.bmp
http://motivesys02.motivesys.com/download/UAC/Test.bmp
http://motivesys02.motivesys.com/download/UAC/Screenshot.bmp
NOTE: Zoom in on Screenshot.bmp and observe how the red cross symbol (Test.bmp) blends perfectly with the menu background while the UAC shield icon (UACShield.bmp) does not blend properly. Any ideas why?
Antti
@Ted Re:quote "martona, instead of using LoadBitmap (which is obsolete, as is LoadIcon, LoadCursor, etc), use LoadImage with LR_CREATEDIBSECTION"
thankyou greatly for the very much needed information.
--Chemace
The MSDN help for MENUITEMINFO suggests that you can do this to use an icon:
MENUITEMINFO minfo;
memset( &minfo, 0, sizeof(minfo) );
minfo.cbSize = sizeof(minfo);
minfo.fMask = MIIM_BITMAP|MIIM_DATA;
minfo.hbmpItem = HBMMENU_SYSTEM;
minfo.dwItemData = (ULONG_PTR)IDI_SHIELD;
I've tried setting dwItemData to IDI_SHIELD, I've tried setting it to LoadIcon(NULL,IDI_SHIELD) and I've tried setting it to an invisible HWND that has IDI_SHIELD as it's icon. All of these cases make an icon show up, but none of them make the shield icon show up. It just shows the icon associated with my main window. Does anyone interpret the help to mean something that I have not tried? (see help for HBMMENU_SYSTEM)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/resources/menus/menureference/menustructures/menuiteminfo.asp
Regarding Antti's problem:
The image appears in the menu but the borders of the image do not look perfect. There are white pixels there. That is, the image is not blending to the menu background as it should.
If I were to guess, perhaps the bitmap expects the RGB values to be premultiplied by the A values and perhaps they were not generated that way. That would cause a problem at the edges like you describe. The reverse situation is also a possibility.
Mike
Michael,
You are most likely right about the premultiplying requirement. Thanks!
And the blog entry Ted referred to is now a very good and thorough resource for anybody needing to add icons to menus in Vista.
Antti