Windows Shell扩展系列文章 2 - .NET 4为扩展的Windows Shell上下文菜单项添加位图图标

<p>在“<a href="http://blog.csdn.net/MSCodeSample/archive/2011/03/23/6270073.aspx">Windows Shell扩展系列文章 1 - .NET 4 编写Windows Shell上下文菜单扩展</a>”一文中,我们介绍了如何使用.NET 4编写VC#或VB.NET代码创建Windows Shell上下文菜单扩展。</p>
<p><img src="http://hi.csdn.net/attachment/201103/27/0_1301244965K5dN.gif" alt="" width="459" height="217"></p>
<p>很多开发人员想进一步知道:<strong>如何为扩展的菜单项加上位图图标</strong>。本文便通过一个来自于<a href="1code.codeplex.com">微软一站式示例代码库</a>的示例代码为你演示如何为扩展的菜单项加上位图图标。</p>
<p><strong>示例代码下载</strong>:<a href="http://1code.codeplex.com/releases/view/62253#DownloadId=215068"><strong><span style="color: #ca491d;">C#</span></strong></a><strong>, </strong><a href="http://1code.codeplex.com/releases/view/62253#DownloadId=215141"><strong><span style="color: #ca491d;">VB.NET</span></strong></a></p>
<p><img src="http://hi.csdn.net/attachment/201103/27/0_1301245218jTJZ.gif" alt="" width="508" height="255"></p>
<p><span style="font-size: medium;"><strong>实现细节</strong></span></p>
<p>Windows Shell上下文菜单中的菜单项是通过实现IContextMenu.QueryContextMenu添加上去的。</p>
<p>public int QueryContextMenu( <br> IntPtr hMenu, <br> uint iMenu, <br> uint idCmdFirst, <br> uint idCmdLast, <br> uint uFlags) <br>{ <br> ...... <br> // Use either InsertMenu or InsertMenuItem to add menu items. <br> MENUITEMINFO mii = new MENUITEMINFO(); <br> mii.cbSize = (uint)Marshal.SizeOf(mii); <br> mii.fMask = MIIM.MIIM_STRING | MIIM.MIIM_FTYPE | MIIM.MIIM_ID | MIIM.MIIM_STATE; <br> mii.wID = idCmdFirst + IDM_DISPLAY; <br> mii.fType = MFT.MFT_STRING; <br> mii.dwTypeData = this.menuText; <br> mii.fState = MFS.MFS_ENABLED; <br> if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref mii)) <br> { <br> return Marshal.GetHRForLastWin32Error(); <br> } <br> ...... <br>}</p>
<p>其中<a href="http://msdn.microsoft.com/en-us/library/ms647578.aspx">MENUITEMINFO</a>结构可支持在菜单项文字旁添加位图图标。你只需要为MENUITEMINFO.fMask添加上MIIM_BITMAP,并将MSENUITEMINFO.hbmpItem指向一16x16的位图句柄。修改后的代码示例如下:</p>
<p>public int QueryContextMenu( <br> IntPtr hMenu, <br> uint iMenu, <br> uint idCmdFirst, <br> uint idCmdLast, <br> uint uFlags) <br>{ <br> ...... <br> // Use either InsertMenu or InsertMenuItem to add menu items. <br> MENUITEMINFO mii = new MENUITEMINFO(); <br> mii.cbSize = (uint)Marshal.SizeOf(mii); <br> mii.fMask = <span style="background-color: #ffff00;">MIIM.MIIM_BITMAP</span> | MIIM.MIIM_STRING | MIIM.MIIM_FTYPE | <br> MIIM.MIIM_ID | MIIM.MIIM_STATE; <br> mii.wID = idCmdFirst + IDM_DISPLAY; <br> mii.fType = MFT.MFT_STRING; <br> mii.dwTypeData = this.menuText; <br> mii.fState = MFS.MFS_ENABLED; <br><span style="background-color: #ffff00;">mii.hbmpItem = this.menuBmp;</span> <br> if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref mii)) <br> { <br> return Marshal.GetHRForLastWin32Error(); <br> } <br> ...... <br>}</p>
<p>"this.menuBmp" 在该上下文菜单扩展类的构造函数内被初始化:</p>
<p>public FileContextMenuExt() <br>{<br> // Load the bitmap for the menu item. <br> Bitmap bmp = Resources.OK; // A 16x16 bmp added to the Resources of the project. <br> bmp.MakeTransparent(bmp.GetPixel(0, 0)); <br> this.menuBmp = bmp.GetHbitmap(); <br>}</p>
<p>然后在析构函数内释放该句柄:</p>
<p>~FileContextMenuExt() <br>{ <br> if (this.menuBmp != IntPtr.Zero) <br> { <br> NativeMethods.DeleteObject(this.menuBmp); <br> this.menuBmp = IntPtr.Zero; <br> } <br>}</p>
<p>有了这些修改,上下文菜单项就会显示你所指定的位图图标。</p>
<p><img src="http://hi.csdn.net/attachment/201103/27/0_1301244965K5dN.gif" alt="" width="459" height="217"></p>
<p></p>
<p><strong>注意</strong></p>
<p>1. 务必将Bitmap.GetHbitmap返回的位图在该类对象被析构的时候释放掉,否则将造成句柄溢出。</p>
<p>下述示例代码演示了一个开发人员常犯的错误:</p>
<p> // Use either InsertMenu or InsertMenuItem to add menu items. <br> MENUITEMINFO mii = new MENUITEMINFO(); <br> mii.cbSize = (uint)Marshal.SizeOf(mii); <br> mii.fMask = MIIM.MIIM_BITMAP | MIIM.MIIM_STRING | MIIM.MIIM_FTYPE | <br> MIIM.MIIM_ID | MIIM.MIIM_STATE; <br> mii.wID = idCmdFirst + IDM_DISPLAY; <br> mii.fType = MFT.MFT_STRING; <br> mii.dwTypeData = this.menuText; <br> mii.fState = MFS.MFS_ENABLED; <br> mii.hbmpItem = Resources.OK.GetHbitmap(); // This will leak the bitmap handle! <br> if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref mii)) <br> { <br> return Marshal.GetHRForLastWin32Error(); <br> }</p>
<p>2. 务必不要将MENUITEMINFO.fType 设置为MFT_BITMAP。 MFT_BITMAP 是为另一个目的而设计的。如果你想把menu item直接做成一张图片,那就设置MFT_BITMAP。效果如下:</p>
<p><img src="http://hi.csdn.net/attachment/201103/28/0_13013045228N26.gif" alt="" width="289" height="235"></p>

你可能感兴趣的:(windows)