在应用程序中集成外壳的上下文菜单(上)

原创 2004年05月12日 18:30:00

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

在应用程序中集成外壳的上下文菜单

作者:_foo (2004.5.11

关键字:Shell, Namespace, IContextMenu, 外壳, 名字空间, 上下文菜单

文章难度:初级

 

介绍(What is the shell contextmenu)

随着越来越多的软件对外壳的扩展,资源管理器变得是越来越强大和易用,以前要压缩一个或多个文件,你得老老实实找到压缩软件的快捷方式并打开他,接着进行一系列的选择操作,这对我这种懒人来说绝对是很烦的一件事,而有了外壳的菜单扩展机制,你只需在资源管理器中选好你要操作的文件然后弹出右键菜单选择相应的项就搞定了,多方便啊。

呃,打住,本文并不是要介绍怎么给资源管理器加入一个菜单扩展项(1),而是介绍怎么在自己的程序中调用那个有着丰富功能的上下文菜单。例如FlashFXP中左边的本地文件窗口(1)

(1:假设你在打开FTP软件想把一些文件上传时才发现这些文件尚未打包,怎么办?切换到资源管理器把他们打包再回到FlashFXP吗?No no no,别做这么没效率的事,在FlashFXP左窗口中把相应文件选中后按住shift键后弹出右键菜单看看,简直太美妙了,以后在FTPdown到什么好音乐我直接就可以用喜欢的播放器来欣赏了。)

(注1:基本上认为写一个上下文菜单扩展项是比较容易实现的,有大量的文章和示例代码可从http://www.codeproject.com/shell得到)

 

原理(How to implement)

我们知道,在win32中是以外壳名字空间(2)的形式来组织文件系统的,在外壳名字空间里的每一个文件夹都实现了一个IShellFolder的接口,通过这个接口我们可以直接查询或间接得到其他相关的接口。

跟对象(3)的上下文菜单相关的接口是IContextMenu,通过对象的父文件夹的IShellFolder::GetUIObjectOf方法可得到该接口。得到该接口后,可以用IContextMenu::QueryContextMenu方法来生成上下文菜单的菜单项,用IContextMenu::InvokeCommand调用相应的命令。看起来很简单不是吗?下面就以一个实例来说明具体的实现,包括怎么得到一个对象的父文件夹IShellFolder接口,怎么得到IContextMenu,及怎么调用IContextMenu的各个方法。

(注2:关于外壳名字空间的概念,推荐大家看看姜伟华Windows壳名字空间的浏览一文,更多资料可从MSDN中得到)

(注3:这里的对象指的是外壳名字空间中的一个节点,对象有可能是一个文件夹,有可能是一个文件,也有可能是一个虚拟文件夹,例如:我的电脑,网上邻居,控制面板等)

 

具体实现和示例

为了简单起见,本例以MFC中的基于对话框工程为基础,在一个ListBox控件中列出C盘下的子文件夹和文件,右键单击ListBox中的每一项会弹出对应的外壳上下文菜单。

(一)  枚举C驱动器下的文件夹和文件并添加到ListBox中:
步骤如下:

a)         SHGetDesktopFolder得到桌面的IShellFolder接口指针,这是我们取得其他对象IShellFolder的一个途径。

b)        IShellFolder::ParseDisplayName得到驱动器CPIDL,接着把得到的PIDL做为参数传给IShellFolder::BindToObject便可得到驱动器CIShellFolder接口指针了。

c)        用刚才得到C盘的IShellFolder::EnumObjects方法可得到一个枚举器,通过该枚举器可以枚举出C盘下的子文件夹和文件的PIDL。通过GetDisplayNameOf可得到一个PIDL所代表的对象的显示名,于是我们把该名字加到ListBox中,同时用CListBox::SetItemData把相应的PIDL保存起来,以后用得着J

示例代码:

        

LPMALLOC pMalloc;

    LPITEMIDLIST pidlC = NULL;

    LPITEMIDLIST pidlItems = NULL;

    IShellFolder *psfDeskTop = NULL;

    IShellFolder *psfFolderC = NULL;

    LPENUMIDLIST ppenum = NULL;

    ULONG celtFetched;

    HRESULT hr;

    STRRET strDispName;

    TCHAR pszDisplayName[MAX_PATH];

         ULONG uAttr;

 

         hr = SHGetMalloc(&pMalloc);

         hr = SHGetDesktopFolder(&psfDeskTop);

         hr = psfDeskTop->ParseDisplayName(GetSafeHwnd(), NULL, L"C://", NULL, &pidlC, NULL);

         hr = psfDeskTop->BindToObject(pidlC, NULL, IID_IShellFolder, (void**)&psfFolderC);

         psfDeskTop->Release();

         hr = psfFolderC->EnumObjects(GetSafeHwnd(), SHCONTF_FOLDERS | SHCONTF_NONFOLDERS , &ppenum);

 

         while (hr = ppenum->Next(1, &pidlItems, &celtFetched) == S_OK && (celtFetched) == 1)

    {

        psfFolderC->GetDisplayNameOf(pidlItems, SHGDN_INFOLDER, &strDispName);

 

                   uAttr = SFGAO_FOLDER;

        psfFolderC->GetAttributesOf(1, (LPCITEMIDLIST *) &pidlItems, &uAttr);

                   StrRetToBuf(&strDispName, pidlItems, pszDisplayName, MAX_PATH);

                   CString strDisplayName;

 

                   if(uAttr & SFGAO_FOLDER)

        {

            strDisplayName.Format("%s%s%s","[",pszDisplayName,"]");

        }

                   else

                   {

                            strDisplayName = pszDisplayName;

                   }

                   m_listBox.SetItemData(m_listBox.InsertString(-1, strDisplayName), (DWORD)pidlItems);

    }

        

         ppenum->Release();

         pMalloc->Free(pidlC);

         pMalloc->Release();

         m_psfFolderC = psfFolderC;

    ...

 faint,超出64K,待续...

在应用程序中集成外壳的上下文菜单(下)

在应用程序中集成外壳的上下文菜单

关键字:Shell, Namespace, IContextMenu, 外壳, 名字空间, 上下文菜单文章难度:初级 介绍(What is the shell contextmenu) 随着越来越多的...
  • _foo
  • _foo
  • 2004年08月08日 18:59
  • 3914

在应用程序中集成外壳的上下文菜单(下)

(二)  响应鼠标单击消息,获取IContextMenu接口并弹出菜单;通过C盘的IShellFolder接口的GetUIObjectOf方法我们可以得到该节点的一个或多个指定子节点的IContext...
  • IFoo
  • IFoo
  • 2004年05月12日 18:25
  • 1223

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

接上一节:(C#)Windows Shell 外壳编程系列2 - 解释,从“桌面”开始展开 这里解释上一节中获取名称的方法  GetDisplayNameOf 定义: voi...
  • znb769525443
  • znb769525443
  • 2014年08月15日 19:08
  • 1128

android菜单详解三:上下文菜单

创建一个上下文菜单 一个上下文菜单跟PC上的右键菜单类似.你应使用上下文菜单为用户界面上的某个部分提供动作选择功能.在Android中,一个上下文菜单会在用户长按一个界面条目时出现. 你可以为任何V...
  • u012721933
  • u012721933
  • 2016年04月01日 09:45
  • 418

Fragment上下文菜单示例

本文中所讲的技术项目源码下载地址:http://download.csdn.net/detail/far_sight/7930799
  • far_sight
  • far_sight
  • 2014年09月17日 14:24
  • 1245

android开发之使用上下文菜单

android中的上下文菜单类似于PC上的鼠标右键单击,不同的是android上没有鼠标这一概念,更谈不上右键单击,在android中,一般是长按某个View,调出上下文菜单。与OptionsMenu...
  • u012702547
  • u012702547
  • 2015年10月27日 16:10
  • 7556

操作系统外壳(shell)

1.通用的操作系统都要提供一个称为shell(外壳)的程序,用户(操作人员)使用这个程序来操作计算机系统进行工作。 2.DOS中有一个程序command.com,这个程序在DOS中称为命令解释器...
  • qq_35212671
  • qq_35212671
  • 2016年10月14日 17:20
  • 635

Android 上下文菜单(长摁弹出)

长摁弹出
  • little_shengsheng
  • little_shengsheng
  • 2016年05月17日 09:42
  • 260

在fragment中添加上下文菜单

在fragment中添加上下文菜单,和在mainactivity中有一些不同,两者都需要在menu目录下创建一个菜单xml(如main.xml)文件,在mainactivity下我们在onCreate...
  • u013270383
  • u013270383
  • 2015年09月29日 18:16
  • 842

为程序添加系统上下文菜单

using System; using System.Diagnostics; using Microsoft.Win32; namespace SimpleContextMenu { //...
  • a497785609
  • a497785609
  • 2012年07月24日 20:12
  • 1022
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在应用程序中集成外壳的上下文菜单(上)
举报原因:
原因补充:

(最多只允许输入30个字)