(C#)Windows Shell 编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令

原文(C#)Windows Shell 编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令

(本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢~)

接上一节:(C#)Windows Shell 编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单


一节说到如何弹出 IShellFolder 的上下文菜单,也就是
IContextMenu。有时候我们需要在这个菜单上面,加入一些属于自己的菜单项。举个例子,你打开资源管理器,查看左边目录树的右键菜单,会发现顶
层多了一个折叠/展开的菜单项。好,我们也动手来加入这个菜单项。

修改例子3,我们找到 QueryContextMenu 处,这时候提供了一个菜单句柄:

//提供一个弹出式菜单的句柄
IntPtr contextMenu = API.CreatePopupMenu();
iContextMenu.QueryContextMenu(contextMenu, 0,
    API.CMD_FIRST, API.CMD_LAST, CMF.NORMAL | CMF.EXPLORE);

然后增加以下代码:

/////////////////////////增加一个自定义菜单
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);
/////////////////////////
这里我们用到了 InsertMenu 这个 API:

[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);

参数2表示增加菜单项的位置,从0开始。
参数3表示flag,这里提供了菜单状态,以及位置的计算方法,它是一个枚举:


public enum MFT : uint
{
    GRAYED = 0x00000003,
    DISABLED = 0x00000003,
    CHECKED = 0x00000008,
    SEPARATOR = 0x00000800,
    RADIOCHECK = 0x00000200,
    BITMAP = 0x00000004,
    OWNERDRAW = 0x00000100,
    MENUBARBREAK = 0x00000020,
    MENUBREAK = 0x00000040,
    RIGHTORDER = 0x00002000,
    BYCOMMAND = 0x00000000,
    BYPOSITION = 0x00000400,
    POPUP = 0x00000010
}

MF_BYPOSITION 表示位置的计算方法是使用索引项,第一个菜单就是0,第二个菜单就是1,如此类推...

参数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();
    }
}

如图:

执行菜单命令

能不能不弹出菜单直接调用菜单项相应的命令?答案是肯定的。

大家还记得怎么显示一个文件或文件夹的属性对话框吗?

Yes,用ShellExecuteEx并指定SHELLEXECUTEINFO的lpVerb域为properties就可,但是这种方法只能查看一个文件的属性,怎么同时查看多个的?

要知道ShellExecuteEx查看文件属性最终也是靠IContextMenu帮忙的,所以答案还是在IContextMenu上,我们只要
在调用GetUIObjectOf时把想查看的文件或文件件的PIDL做为参数传进去,然后直接调用InvokeCommand方法就OK啦。

当然,我们做的例子,还是弹出一个对象的属性,靠你自己修改了。

我们必须先得到 IContextMenu 接口:

//得到 IContextMenu 接口
IntPtr iContextMenuPtr = IntPtr.Zero;
iContextMenuPtr = IParent.GetUIObjectOf(IntPtr.Zero, (uint)pidls.Length,
    pidls, ref Guids.IID_IContextMenu, out iContextMenuPtr);
IContextMenu iContextMenu = (IContextMenu)Marshal.GetObjectForIUnknown(iContextMenuPtr);

但我们不弹出这个菜单,仅仅是调用 InvokeCommand 来执行命令而已:

//直接执行命令
CMINVOKECOMMANDINFOEX invoke = new CMINVOKECOMMANDINFOEX();
invoke.cbSize = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX));
invoke.lpVerb = Marshal.StringToHGlobalAnsi("properties");
invoke.lpDirectory = string.Empty;
invoke.fMask = 0;
invoke.nShow = 1;
iContextMenu.InvokeCommand(ref invoke);

关于verb的更多信息请参考MSDN。我这里做的是执行“属性”,如果你要执行其他命令,或者按照索引来执行,也是可以的。这里不做深入研究。

源代码:/Files/lemony/WinShell4.rar

我正在考虑下一节是讲图标,还是继续讲iContextMenu。大家也知道,某个文件的右键菜单里面,往往会有几个 winrar 的选项,还带着可爱的图标。

很有可能下一节就讲述如何在C#中也实现这样的效果哦。希望大家多多支持^_^。 

时间: 2024-08-17 16:19:28

(C#)Windows Shell 编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令的相关文章

(C#)Windows Shell 编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单

原文 (C#)Windows Shell 编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单 接上一节:(C#)Windows Shell 编程系列2 - 解释,从"桌面"开始展开这里解释上一节中获取名称的方法 GetDisplayNameOf 定义: void GetDisplayNameOf(             IntPtr pidl,             SHGNO uFlags,             IntPtr lpName); 该方法是用来转

(C#)Windows Shell 编程系列2 - 解释,从“桌面”开始展开

 原文   (C#)Windows Shell 编程系列2 - 解释,从"桌面"开始展开   (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) 接上一篇:(C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹 让我们详细解释一下 Shell 编程中最基本的一些函数.结构体和枚举. SHGetDesktopFolder  获取桌面的 IShellFolder 接口 [DllImport("shell32.dll")]        

(C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹

原文 (C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹  (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) Windows Shell 编程,即 Windows 外壳编程.我们所看到的资源管理器以及整个桌面,都是一个 Shell. 关于 Windows 外壳的基本概念,我这里不做详细介绍,不了解的朋友,可以看看 姜伟华 的 Windows外壳名字空间的浏览. 好,现在让我们从基础学起,早日做出一个强大的资源管理器软件.(偶也是初学者,多多指教) 1 -

c++-关于注册表添加右键菜单的测试。涉及Windows shell编程

问题描述 关于注册表添加右键菜单的测试.涉及Windows shell编程 关于注册表添加右键菜单的测试. 我在win7 64位 日语系统里面发现很奇怪的结论. 不知道是不是我弄错了. 1: [HKEY_CLASSES_ROOTDirectoryBackgroundshelltest] 1)右键桌面空白区域 有效果 2)右键文件夹 无效果 2 [HKEY_CLASSES_ROOTDirectoryBackgroundshellexTest] 1)右键桌面空白区域 无效果 2)右键文件夹 无效果

《windows核心编程系列》二谈谈ANSI和Unicode字符集 .

http://blog.csdn.net/ithzhang/article/details/7916732转载请注明出处!! 第二章:字符和字符串处理     使用vc编程时项目-->属性-->常规栏下我们可以设置项目字符集合,它可以是ANSI(多字节)字符集,也可以是unicode字符集.一般情况下说Unicode都是指UTF-16.也就是说每个字符编码为两个字节.65535个字符可以表示世界上大部分的语言.为了软件使国际化大家再编程时应该使用unicode字符集.由于原来学过c语言,不习惯

windows api编程-在别的地方弹出的系统菜单点击菜单项没有反应?

问题描述 在别的地方弹出的系统菜单点击菜单项没有反应? 去掉了标题栏,然后通过WM_HITTEST模拟标题栏,可是右键弹不出菜单,于是自己在WM_NCRBUTTONDOWN中弹出,代码如下case WM_NCRBUTTONDOWN: hMenu = GetSystemMenu(hWndFALSE); //AppendMenu(hMenuMF_SEPARATOR00); GetCursorPos(&pos); TrackPopupMenu(hMenuTPM_LEFTALIGN | TPM_LEFT

【转】Windows Shell扩展编程傻瓜手册大全:上下文菜单扩展

引用自:http://blog.163.com/yesaidu@126/blog/static/51819307200861853827582/ Part I: A step-by-step tutorial on writing shell extensions 第一节:Windows shell扩展初步:上下文菜单扩展   作者:Michael Dunn 译者:yesaidu   源代码下载:1       2   目录 ● README ● 系列绪言 ● 第一部分绪言 ● 从AppWiza

Windows界面编程第七篇 文件拖拽(文件拖放)

本文配套程序下载地址为:http://download.csdn.net/detail/morewindows/5128654 转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/8634451 欢迎关注微博:http://weibo.com/MoreWindows   前面已经有六篇文章介绍了Windows界面编程,目录如下: 1. <Windows界面编程第一篇位图背景与位图画刷> 2. <Windows界面编程

(C#)Windows Shell 外壳编程系列7 - ContextMenu 注册文件右键菜单

原文 (C#)Windows Shell 外壳编程系列7 - ContextMenu 注册文件右键菜单   (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-)   接上一节:(C#)Windows Shell 外壳编程系列6 - 执行   从本节起,我所要讲述的是对 Windows 系统的"Shell 扩展"."Shell 扩展"从字面上分两个部分:Shell 与 Extension.Shell 指 Windows Explorer,而Extensi