Shell Context Menus and Custom Buttons
It is not easy to get icons working on shell context menus. Each version of Windows has its own way of putting icons on context menus. I came across this great article about the proper way of setting an icon on a shell context menu.
nanoant: Themed menu’s icons, a complete Vista and XP solution (updated)
The code is based off TortoiseSVN’s context menu. The only problem with it is the fact that it causes Windows to display two icon columns on the menu in the Classic theme. This occurs because legacy context menu extensions will use the MENUITEMINFO’s hbmpChecked and hbmpUnchecked properties to set the bitmap icon. TortoiseSVN uses the hbmpItem property which is a newer way of setting the bitmap. The way to get around having to icons is to set the style of the menu via SetMenuInfo so that the menu has the MNS_CHECKORBMP style flag set. The Aero theme actually sets this style on all menus automatically which is why the issue can’t be seen in Aero.
Below is are screenshots of the context menu with two icon columns (left) and one icon column (right).
![]() Two icon columns |
![]() One icon column |
I submitted a patch to TortoiseSVN to fix it today.
One issue I came across while superclassing a button in Windows has to do with the fact that when the button processes the BM_SETSTATE message it does internal painting without calling WM_PAINT. This caused problems for me because I was doing custom painting and in certain cases, the button would paint its default look. I tried just returning true during the BM_SETSTATE message, instead of letting it go to the original procedure, but that caused the button clicks not to work. So I found this Dr. Dobbs article that shows that you have to set some flags (BST_PUSHED, ..) in the window’s extra memory.
Dr. Dobbs – Writing Windows Custom Controls
Update 9/5/2009:
The issue with BM_SETSTATE doing internal drawing without calling WM_PAINT is only present in older versions of the commons control library. If you attempt to set the button window’s extra memory values like that with a newer version of the common controls library, then it will crash your application. So if it does crash, check to see that you aren’t including a manifest which specifies a higher version of the common controls library.









