2011年3月28日

在“Windows Shell扩展系列文章 1 - .NET 4 编写Windows Shell上下文菜单扩展”一文中,我们介绍了如何使用.NET 4编写VC#或VB.NET代码创建Windows Shell上下文菜单扩展。
 


很多开发人员想进一步知道:如何为扩展的菜单项加上位图图标。本文便通过一个来自于微软一站式示例代码库的示例代码为你演示如何为扩展的菜单项加上位图图标。
 
示例代码下载:C#, VB.NET
 


实现细节
 
Windows Shell上下文菜单中的菜单项是通过实现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();
    }
    ......
}
 
其中MENUITEMINFO结构可支持在菜单项文字旁添加位图图标。你只需要为MENUITEMINFO.fMask添加上MIIM_BITMAP,并将MSENUITEMINFO.hbmpItem指向一16x16的位图句柄。修改后的代码示例如下:
 
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();
    }
    ......
}
 
"this.menuBmp" 在该上下文菜单扩展类的构造函数内被初始化:
 
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();
}
 
然后在析构函数内释放该句柄:
 
~FileContextMenuExt()
{
    if (this.menuBmp != IntPtr.Zero)
    {
        NativeMethods.DeleteObject(this.menuBmp);
        this.menuBmp = IntPtr.Zero;
    }
}
 
有了这些修改,上下文菜单项就会显示你所指定的位图图标。
 


注意
 
1. 务必将Bitmap.GetHbitmap返回的位图在该类对象被析构的时候释放掉,否则将造成句柄溢出。
 
下述示例代码演示了一个开发人员常犯的错误:
 
    // 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. 务必将MENUITEMINFO.fType 指向上述bmp的句柄。比如,
 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/MSCodeSample/archive/2011/03/28/6282554.aspx

posted @ 2011-03-28 13:52 王琳 阅读(53) 评论(0) 编辑


2009年4月10日

windows网络与通信设计  85。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

posted @ 2009-04-10 09:04 王琳 阅读(66) 评论(0) 编辑


2009年4月8日

人生要懂的历史潜规则  69(第 83/211 页)。。。。。。。。。。。。。。。。。。。。。。。

posted @ 2009-04-08 09:22 王琳 阅读(41) 评论(0) 编辑


2008年5月30日

http://www.programsalon.com/sourcecode/hack/sniffer/download61.html

posted @ 2008-05-30 18:01 王琳 阅读(34) 评论(0) 编辑


2008年5月29日

http://blog.csdn.net/piggyxp/archive/2004/05/31/19609.aspx

posted @ 2008-05-29 21:20 王琳 阅读(10) 评论(0) 编辑

http://www.it55.com/html/xueyuan/chengxukaifa/c_jiaocheng/20071015/250903_7.html

posted @ 2008-05-29 21:04 王琳 阅读(15) 评论(0) 编辑

http://www.taiwanren.com/blog/article.asp?id=8678

posted @ 2008-05-29 21:03 王琳 阅读(15) 评论(0) 编辑

http://blog.programfan.com/article.asp?id=25228
http://www.leftworld.net/wenzhang/show/1816.html
http://blog.csdn.net/johnny_83/archive/2007/10/13/1822923.aspx

posted @ 2008-05-29 17:37 王琳 阅读(11) 评论(0) 编辑


2008年5月18日

摘要: 有一天,寒山问拾得说:"如果世间有人无端地诽谤我、欺负我、侮辱我、耻笑我、轻视我、鄙贱我、恶厌我、欺骗我,我要怎么做才好呢?" 拾得回答道:"你不妨忍着他、谦让他、任由他、避开他、耐烦他、尊敬他、不要理会他.再过几年,你且看他如何."阅读全文

posted @ 2008-05-18 21:39 王琳 阅读(355) 评论(1) 编辑


2008年5月16日

摘要: debugview和commview阅读全文

posted @ 2008-05-16 00:07 王琳 阅读(40) 评论(0) 编辑


posts - 102, comments - 2, trackbacks - 0, articles - 3

Copyright © 王琳