【IT168 技术文档】
上一节说到如何弹出 IShellFolder 的上下文菜单,也就是 IContextMenu。有时候我们需要在这个菜单上面,加入一些属于自己的菜单项。举个例子,你打开资源管理器,查看左边目录树的右键菜单,会发现顶层多了一个折叠/展开的菜单项。好,我们也动手来加入这个菜单项。
修改例子3,我们找到 QueryContextMenu 处,这时候提供了一个菜单句柄:
然后增加以下代码://提供一个弹出式菜单的句柄
IntPtr contextMenu = API.CreatePopupMenu();
iContextMenu.QueryContextMenu(contextMenu, 0,
API.CMD_FIRST, API.CMD_LAST, CMF.NORMAL | CMF.EXPLORE);
这里我们用到了 InsertMenu 这个 API:/**//**//**//////////////////////////增加一个自定义菜单
string topInvoke = Tree1.SelectedNode.IsExpanded ? "折叠(&A)" : "展开(&A)";
MFT extraFlag = (Tree1.SelectedNode.Nodes.Count > 0) ? 0 : MFT.GRAYED;
API.InsertMenu(contextMenu, 0, MFT.BYPOSITION | extraFlag,
(int)(API.CMD_LAST+1), topInvoke);
//增加分隔线
API.InsertMenu(contextMenu, 1, MFT.BYPOSITION | MFT.SEPARATOR, 0, "-");
//把第一项菜单设置为默认菜单,也就是加粗
API.SetMenuDefaultItem(contextMenu, 0, true);
参数2表示增加菜单项的位置,从0开始。[DllImport("user32",
SetLastError = true,
CharSet = CharSet.Auto)]
public static extern bool InsertMenu(
IntPtr hmenu,
uint uPosition,
MFT uflags,
uint uIDNewItem,
[MarshalAs(UnmanagedType.LPTStr)]
string lpNewItem);
参数3表示flag,这里提供了菜单状态,以及位置的计算方法,它是一个枚举:
MF_BYPOSITION 表示位置的计算方法是使用索引项,第一个菜单就是0,第二个菜单就是1,如此类推...public enum MFT
参数4表示命令值。我们可以根据这个命令值来执行对应的功能。
然后就可以弹出菜单了:
可以看到弹出菜单的效果。当然,我们还必须做点事情来响应这个菜单的执行://弹出菜单
uint cmd = API.TrackPopupMenuEx(contextMenu,TPM.RETURNCMD,
MousePosition.X, MousePosition.Y, this.Handle, IntPtr.Zero);
如图://获取命令序号,执行菜单命令
if (cmd >= API.CMD_FIRST)
...{
![]()
//自定义菜单命令
if (cmd == API.CMD_LAST + 1)
...{
if (Tree1.SelectedNode.IsExpanded)
Tree1.SelectedNode.Collapse();
else
Tree1.SelectedNode.Expand();
}
}