Geeks With Blogs
Geekswithblogs

In "Writing Windows Shell Extension with .NET Framework 4 (C#, VB.NET) - Part 1: Context Menu Handler", we introduced how to write Windows shell context menu handler using .NET 4:

Lots of developers have this follow-up question: how can I add bitmap icons to those context menu items?

Here you are the directly working code samples from Microsoft All-In-One Code Framework!

Sample download: C#, VB.NET

Implementation Details

The menu items in the context menu were added in the implementation of IContextMenu.QueryContextMenu:

        public int QueryContextMenu(
            IntPtr hMenu,
            uint iMenu,
            uint idCmdFirst,
            uint idCmdLast,
            uint uFlags)
        {
            ......
            // Use either InsertMenu or InsertMenuItem to add menu items.
            MENUITEMINFO mii = new MENUITEMINFO();
            mii.cbSize = (uint)Marshal.SizeOf(mii);
            mii.fMask = MIIM.MIIM_STRING | MIIM.MIIM_FTYPE | MIIM.MIIM_ID | MIIM.MIIM_STATE;
            mii.wID = idCmdFirst + IDM_DISPLAY;
            mii.fType = MFT.MFT_STRING;
            mii.dwTypeData = this.menuText;
            mii.fState = MFS.MFS_ENABLED;
            if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref mii))
            {
                return Marshal.GetHRForLastWin32Error();
            }
            ......
       }

The MENUITEMINFO structure supports displaying a bitmap next to the menu item text.  You just need to add the MIIM_BITMAP mask in MENUITEMINFO.fMask, and point MSENUITEMINFO.hbmpItem to the HBITMAP handle of a 16x16 bitmap. The modified code is as follows.

        public int QueryContextMenu(
            IntPtr hMenu,
            uint iMenu,
            uint idCmdFirst,
            uint idCmdLast,
            uint uFlags)
        {
            ......
            // Use either InsertMenu or InsertMenuItem to add menu items.
            MENUITEMINFO mii = new MENUITEMINFO();
            mii.cbSize = (uint)Marshal.SizeOf(mii);
            mii.fMask = MIIM.MIIM_BITMAP | MIIM.MIIM_STRING | MIIM.MIIM_FTYPE |
                MIIM.MIIM_ID | MIIM.MIIM_STATE;
            mii.wID = idCmdFirst + IDM_DISPLAY;
            mii.fType = MFT.MFT_STRING;
            mii.dwTypeData = this.menuText;
            mii.fState = MFS.MFS_ENABLED;
mii.hbmpItem = this.menuBmp;
            if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref mii))
            {
                return Marshal.GetHRForLastWin32Error();
            }
            ......
        }

The "this.menuBmp" is initialized in the constructor of the context menu extension class:

        public FileContextMenuExt()
        {
            // Load the bitmap for the menu item.
            Bitmap bmp = Resources.OK;  // A 16x16 bmp added to the Resources of the project.
            bmp.MakeTransparent(bmp.GetPixel(0, 0));
            this.menuBmp = bmp.GetHbitmap();
        }

And the handle is released in the destructor of the class:

        ~FileContextMenuExt()
        {
            if (this.menuBmp != IntPtr.Zero)
            {
                NativeMethods.DeleteObject(this.menuBmp);
                this.menuBmp = IntPtr.Zero;
            }
        }

With these modifications, the context menu extension will display menu items with bitmap icons.

NOTE:

1. Do release the HBITMAP handle created by Bitmap.GetHbitmap. 
A common mistake is as follows.  It will leak the bitmap handle.

            // Use either InsertMenu or InsertMenuItem to add menu items.
            MENUITEMINFO mii = new MENUITEMINFO();
            mii.cbSize = (uint)Marshal.SizeOf(mii);
            mii.fMask = MIIM.MIIM_BITMAP | MIIM.MIIM_STRING | MIIM.MIIM_FTYPE |
                MIIM.MIIM_ID | MIIM.MIIM_STATE;
            mii.wID = idCmdFirst + IDM_DISPLAY;
            mii.fType = MFT.MFT_STRING;
            mii.dwTypeData = this.menuText;
            mii.fState = MFS.MFS_ENABLED;
            mii.hbmpItem = Resources.OK.GetHbitmap();  // This will leak the bitmap handle!
            if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref mii))
            {
                return Marshal.GetHRForLastWin32Error();
            }

2. Do not set MFT_BITMAP in MENUITEMINFO.fType. 
The MFT_BITMAP type is for a different bitmap purpose.  It displays the menu item using a bitmap. The low-order word of the dwTypeData member is the bitmap handle. For example,

Posted on Sunday, March 27, 2011 7:58 PM | Back to top


Comments on this post: Writing Windows Shell Extension with .NET 4 - Part 4: Context Menu Handler with Menu-item Bitmaps

# re: Writing Windows Shell Extension with .NET 4 - Part 4: Context Menu Handler with Menu-item Bitmaps
Requesting Gravatar...
Can i register Windows Shell Extension by programming, not by the set up project as your article ?



for ex. i have a add context menu button, when user clicked it the menu will show in windows context menu.
Left by P' Ping on Jul 16, 2011 11:59 AM

# re: Writing Windows Shell Extension with .NET 4 - Part 4: Context Menu Handler with Menu-item Bitmaps
Requesting Gravatar...
Thanks for posting this article. I am definitely tired of struggling to find relevant and intelligent commentary on this subject. countertop water cooler
Left by leah on Dec 30, 2011 4:44 PM

# re: Writing Windows Shell Extension with .NET 4 - Part 4: Context Menu Handler with Menu-item Bitmaps
Requesting Gravatar...
Great, I've been looking for this information for a couple of an hour, thanks for sharing it here. pmp training course
Left by alex on Dec 30, 2011 4:45 PM

# re: Writing Windows Shell Extension with .NET 4 - Part 4: Context Menu Handler with Menu-item Bitmaps
Requesting Gravatar...
Good post, I like it very much! I would like to leave a comment, because it gives more bloggers who participate and the opportunity to perhaps learn from each other. learning english | teaching job in shanghai
Left by lance on Jan 09, 2012 6:54 AM

# re: Writing Windows Shell Extension with .NET 4 - Part 4: Context Menu Handler with Menu-item Bitmaps
Requesting Gravatar...
I am really impressed by reading this article. In future, you should be giving information about it more. I must have to praise you for this extra ordinary piece of work.
Left by kingston office space on Feb 03, 2012 6:13 PM

# re: Writing Windows Shell Extension with .NET 4 - Part 4: Context Menu Handler with Menu-item Bitmaps
Requesting Gravatar...
Hi Scott,
You do a really good job, but the download link of source is dead. Would hv you another link?
Left by marcelo on Oct 05, 2015 4:35 AM

# re: Writing Windows Shell Extension with .NET 4 - Part 4: Context Menu Handler with Menu-item Bitmaps
Requesting Gravatar...
Thanks. I came across this and it was what I was looking for
pmp training course
Left by Mary Louis on Oct 18, 2016 12:56 AM

Your comment:
 (will show your gravatar)


Copyright © Geekswithblogs | Powered by: GeeksWithBlogs.net