C# Windows 7任务栏开发之跳转列表(Jump Lists)

Jump Lists可以使用户方便快捷的找到想要浏览的文件(文档、图片、音频或视频等)以及应用程序的链接或快捷方式。以IE 浏览器为例看看Jump Lists 都具备哪些功能:

“Taskbar Tasks” 放置了应用程序的一些默认任务:“打开IE 浏览器”、“从任务栏取消固定”、“关闭程序”。无论是否对Jump Lists 做过开发,“Taskbar Tasks” 列表都会出现在所有的应用程序中。

“User Tasks” 包含了应用程序本身提供的一些功能,通过这些链接可以直接对应用程序进行操作。例如,打开一个新IE 标签。

“Known Category” 这个列表是Windows 7 默认类别,其中包含三种模式:“Recent”(近期浏览)、“Frequent”(经常浏览)、“Neither”。它的功能是将经常浏览的网页内容记录下来以便日后再次浏览,随着时间的流逝该列表中的网页链接会随之变化或消失。除了“Known Category” 列表外同样也以创建“Custom Category”(下文将会慢慢讲到)。

“Pinned Category” 正如上面所讲“Frequent Category” 列表中的网页会经常变化,通过右键将网页“钉”在列表中可使其永久保存。

创建User Tasks 列表

现在是不是也想为自己的程序添加一个JL,下面先来介绍如何创建User Tasks 列表。

1. 通过JumpList
类创建一个JL 实例。

2. 使用JumpListLink(string pathValue, string titleValue) 方法(pathValue:应用程序路径,titleValue:链接名称),可以将“记事本”、“画板”这样的Windows 应用程序,以及“网站地址”创建为User Tasks 链接。

3. 再使用AddUserTasks(params IJumpListTask[] tasks) 方法将这些链接添加到JL 中。如下代码所示:

private JumpList    _jumpList;
_jumpList = JumpList.CreateJumpListForIndividualWindow("Windows.TaskBar.WinFormJumpList", this.Handle);
/// <summary>
        /// 添加User Tasks
        /// </summary>
        private void AddUserTasks()
        {
            string systemPath = Environment.GetFolderPath(Environment.SpecialFolder.System);

            // 程序链接
            JumpListTask notepadTask = new JumpListLink(Path.Combine(systemPath, "notepad.exe"), "Notepad")
            {
                IconReference = new IconReference(Path.Combine(systemPath, "notepad.exe"), 0)
            };
            JumpListTask paintTask = new JumpListLink(Path.Combine(systemPath, "mspaint.exe"), "Paint")
            {
                IconReference = new IconReference(Path.Combine(systemPath, "mspaint.exe"), 0)
            };

            // 分割线
            JumpListTask jlSeparator = new JumpListSeparator();

            JumpListTask linkTask = new JumpListLink("http://blog.csdn.net/aoshilang2249", "langya's Blog")
            {
                IconReference = new IconReference("C:\\Program Files\\Internet Explorer\\iexplore.exe", 0)
            };

            // 添加 User Tasks
            _jumpList.AddUserTasks(notepadTask, paintTask, jlSeparator, linkTask);

            // 对JumpList 进行刷新
            _jumpList.Refresh();
        }

在上面程序中,通过JumpListTask 接口创建了“程序链接”(JumpListLink,其中IconReference 为链接图标)和“分割线”(JumpListSeparator);使用AddUserTasks 方法时注意每个链接的位置关系;最后必须使用Refresh
方法对JL 进行刷新才能显示出最新的JL 内容。

创建Known Category 列表

在使用Known Category 功能前,需要先为程序注册文件类型,随后可通过KnownCategoryToDisplay 属性将Known Category 预设为“Recent”、“Frequent”、“Neither” 中的任意一种类型,当测试程序打开某个的文件时,相应的文件链接就会显示在Known
Category 列表中。如下代码所示:

文件关联注册辅助类:

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using System.ComponentModel;
using Microsoft.Win32;

namespace LangYa.Net.Utils.File
{
    /// <summary>
    /// 注册文件关联的应用程序的辅助类
    /// </summary>
    public class FileAssociationsHelper
    {
        private static RegistryKey classesRoot;  // 注册表的根目录

        private static void Process(string[] args)
        {
            if (args.Length < 6)
            {
                string error = ("Usage: <ProgId> <Register in HKCU: true|false> <AppId> <OpenWithSwitch> <Unregister: true|false> <Ext1> [Ext2 [Ext3] ...]");
                throw new ArgumentException(error);
            }

            try
            {
                string  progId         = args[0];
                bool    registerInHKCU = bool.Parse(args[1]);
                string  appId          = args[2];
                string  openWith       = args[3];
                bool    unregister     = bool.Parse(args[4]);

                List<string> argList = new List<string>();
                for (int i = 5; i < args.Length; i++)
                {
                    argList.Add(args[i]);
                }
                string[] associationsToRegister = argList.ToArray(); // 文件列表

                if (registerInHKCU)
                {
                    classesRoot = Registry.CurrentUser.OpenSubKey(@"Software\Classes");
                }
                else
                {
                    classesRoot = Registry.ClassesRoot;
                }

                // 注销
                Array.ForEach(associationsToRegister, assoc => UnregisterFileAssociation(progId, assoc));
                UnregisterProgId(progId);

                // 注册
                if (!unregister)
                {
                    RegisterProgId(progId, appId, openWith);
                    Array.ForEach(associationsToRegister, assoc => RegisterFileAssociation(progId, assoc));
                }
            }
            catch (Exception e)
            {

            }
        }

        /// <summary>
        /// 注册类标识符
        /// </summary>
        /// <param name="progId">类标识符</param>
        /// <param name="appId">应用程序Id</param>
        /// <param name="openWith">打开文件的进程全路径</param>
        private static void RegisterProgId(string progId, string appId, string openWith)
        {
            RegistryKey progIdKey = classesRoot.CreateSubKey(progId);
            progIdKey.SetValue("FriendlyTypeName", "@shell32.dll,-8975");
            progIdKey.SetValue("DefaultIcon", "@shell32.dll,-47");
            progIdKey.SetValue("CurVer", progId);
            progIdKey.SetValue("AppUserModelID", appId);

            RegistryKey shell = progIdKey.CreateSubKey("shell");
            shell.SetValue(String.Empty, "Open");
            shell = shell.CreateSubKey("Open");
            shell = shell.CreateSubKey("Command");
            shell.SetValue(String.Empty, openWith + " %1"); // " %1"表示将被双击的文件的路径传给目标应用程序 

            shell.Close();
            progIdKey.Close();
        }

        /// <summary>
        /// 注销类标识符
        /// </summary>
        /// <param name="progId">类标识符</param>
        private static void UnregisterProgId(string progId)
        {
            try
            {
                classesRoot.DeleteSubKeyTree(progId);
            }
            catch { }
        }

        /// <summary>
        /// 注册文件关联
        /// </summary>
        private static void RegisterFileAssociation(string progId, string extension)
        {
            RegistryKey openWithKey = classesRoot.CreateSubKey(Path.Combine(extension, "OpenWithProgIds"));
            openWithKey.SetValue(progId, String.Empty);
            openWithKey.Close();
        }

        /// <summary>
        /// 注销文件关联
        /// </summary>
        private static void UnregisterFileAssociation(string progId, string extension)
        {
            try
            {
                RegistryKey openWithKey = classesRoot.CreateSubKey(Path.Combine(extension, "OpenWithProgIds"));
                openWithKey.DeleteValue(progId);
                openWithKey.Close();
            }
            catch (Exception e)
            {

            }
        }

        /// <summary>
        /// 类标识符注册操作
        /// </summary>
        /// <param name="unregister">注册或注销</param>
        /// <param name="progId">类标识符</param>
        /// <param name="registerInHKCU">是否在HKCU中注册文件关联 -- false</param>
        /// <param name="appId">应用程序Id</param>
        /// <param name="openWith">打开文件的进程全路径</param>
        /// <param name="extensions">文件关联列表</param>
        private static void InternalRegisterFileAssociations(bool unregister,
                                                             string progId, bool registerInHKCU,string appId, string openWith,
                                                             string[] extensions)
        {
            string Arguments = string.Format("{0} {1} {2} \"{3}\" {4} {5}",
                                              progId, // 0
                                              registerInHKCU, // 1
                                              appId, // 2
                                              openWith,
                                              unregister,
                                              string.Join(" ", extensions));
            try
            {
                Process(Arguments.Split(' '));
            }
            catch (Win32Exception e)
            {
                if (e.NativeErrorCode == 1223) // 1223:用户操作被取消。
                {
                    // 该操作已经被用户取消
                }
            }
        }

        /// <summary>
        /// 判断类标识符是否注册
        /// </summary>
        /// <param name="progId">类标识符</param>
        /// <returns>注册了返回true</returns>
        public static bool IsApplicationRegistered(string progId)
        {
            return (Registry.ClassesRoot.OpenSubKey(progId) != null);
        }

        /// <summary>
        /// 注册类标识符的文件关联
        /// </summary>
        /// <param name="progId">类标识符</param>
        /// <param name="registerInHKCU">是否在HKCU中注册文件关联 -- false
        /// <param name="appId">应用程序Id</param>
        /// <param name="openWith">打开文件的进程全路径</param>
        /// <param name="extensions">文件关联列表</param>
        public static void RegisterFileAssociations(string progId,bool registerInHKCU, string appId, string openWith,
                                                    params string[] extensions)
        {
            InternalRegisterFileAssociations(false, progId, registerInHKCU, appId, openWith, extensions);
        }

        /// <summary>
        /// 注销类标识符的文件关联
        /// </summary>
        /// <param name="progId">类标识符</param>
        /// <param name="registerInHKCU">是否在HKCU中注册文件关联 -- false
        /// <param name="appId">应用程序Id</param>
        /// <param name="openWith">打开文件的进程全路径</param>
        /// <param name="extensions">文件关联列表</param>
        public static void UnregisterFileAssociations(string progId, bool registerInHKCU, string appId, string openWith,
                                                      params string[] extensions)
        {
            InternalRegisterFileAssociations(true, progId, registerInHKCU, appId, openWith, extensions);
        }
    }
}
/// <summary>
/// 添加Known Tasks
/// </summary>
private void AddKnownTasks(JumpListKnownCategoryType knowsType, int knownCategoryOrdinalPosition)
{
    _jumpList.KnownCategoryToDisplay        = knowsType;
    _jumpList.KnownCategoryOrdinalPosition  = knownCategoryOrdinalPosition; // 相对于Custom的位置

    if (!FileAssociationsHelper.IsApplicationRegistered(TaskbarManager.Instance.ApplicationId))
    {
        FileAssociationsHelper.RegisterFileAssociations(TaskbarManager.Instance.ApplicationId,
                                                    false,
                                                    TaskbarManager.Instance.ApplicationId,
                                                    Assembly.GetExecutingAssembly().Location,
                                                    ".jpg", ".png", ".gif", ".JPG", ".PNG", ".GIF");
    }

    _jumpList.Refresh();
}

为了文件正常打开,还需要修改Main方法,让衔接的路径可以传入应用程序,以便打开应用程序关联的文件:

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
    string filePath = "";
    if ((args != null) && (args.Length > 0))
    {
        for (int i = 0; i < args.Length; i++)
        {
            // 对于路径中间带空格的会自动分割成多个参数传入
            filePath += " " + args[i];
        }

        filePath.Trim();
    }

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Main() { FilePath = filePath });
}
/// <summary>
/// 应用程序文件
/// </summary>
public string FilePath
{
    get { return (_strFilePath); }
    set
    {
        _strFilePath = value;
        if (!string.IsNullOrEmpty(_strFilePath))
        {
            _pictureBox.ImageLocation = _strFilePath;
        }
    }
}

创建Custom Category 列表

如同上文创建JumpList 的方式:

1. 通过JumpListCustomCategory
类创建“自定义分类”列表实例。

2. 由JumpListCustomCategory(string categoryName) 方法为列表命名。

3. 使用AddJumpListItems
方法将链接加入到分类中。如下代码所示:

/// <summary>
/// 添加Custom Tasks
/// </summary>
private void AddCustomTasks(string categoryName)
{
    if (categoryName.Length > 0)
    {
        JumpListCustomCategory customCategory = new JumpListCustomCategory(categoryName);
        _jumpList.AddCustomCategories(customCategory);

        // Arguments需要打开的文件类型的参数(如文件路径等)
        JumpListLink jlItem = new JumpListLink(Assembly.GetExecutingAssembly().Location, "Chrysanthemum.jpg")
        {
            IconReference = new IconReference(Assembly.GetEntryAssembly().Location, 0),
            Arguments = @"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg"
        };

        customCategory.AddJumpListItems(jlItem);
        _jumpList.Refresh();
    }
}

时间: 2024-08-02 02:19:45

C# Windows 7任务栏开发之跳转列表(Jump Lists)的相关文章

C# Windows 7任务栏开发之进度条(Progress Bar)

Windows 7 任务栏为我们增添了许多其他功能:Jump Lists,Window Preview,Progress Bar,Overlay Icon 等等. 新任务栏的功能使我们的操作更加方便快捷,微软提供了方便的工具Windows API Code Pack for .NET Framework 来帮助我们完成这些开发,程序中增加Microsoft.WindowsAPICodePack.dll 和Microsoft.WindowsAPICodePack.Shell.dll. 在使用IE

C# Windows 7任务栏开发之图标闪动(Flash)

使用QQ聊天时,如果对方发出了信息QQ 图标会闪动提示,虽然Windows API 没有直接控制闪动效果的方法,但该效果在开发中可能会经常使用,下面代码为一个闪动效果类: /// <summary> /// Win32 API /// </summary> internal static class Win32 { /// <summary> /// 窗口闪动 /// </summary> /// <param name="hwnd"

windows下python web开发环境的搭建

windows下python web开发环境: python2.7,django1.5.1,eclipse4.3.2,pydev3.4.1 一. python环境安装 https://www.python.org/ftp/python/2.7/python-2.7.amd64.msi 不多说,装完后把C:\Python27加入到path环境变量里. 然后就溜溜python,看看version啦.OK,next step. 二. python web开发框架django安装 django是一个采用

Windows 7 下 PHP 开发环境搭建(手动)

Windows 7 下 PHP 开发环境搭建 1.说明 做开发的都知道一句话,就是“站在巨人的肩膀上”.确实现在打开浏览器随便一搜很多一键安装PHP环境的软件,比如wamp.xampp.AppServ....其实我之前也一直在用wamp,对于初学者确实很方便,一键安装,然后遇到不会的再去查,去改配置,等等. 但是用长了你会发现,很多问题根本不是所谓“一键安装”后就不会发生了!当你用wamp.xampp..对环境搭建感觉轻车熟路并且把注意力都放在php逻辑实现的时候很多bug都是在环境配置层出现的

为 WPF 程序添加 Windows 跳转列表的支持

原文:为 WPF 程序添加 Windows 跳转列表的支持 Windows 跳转列表是自 Windows 7 时代就带来的功能,这一功能是跟随 Windows 7 的任务栏而发布的.当时应用程序要想用上这样的功能需要调用 shell 提供的一些 API. 然而在 WPF 程序中使用 Windows 跳转列表功能非常简单,在 XAML 里面就能完成.本文将介绍如何让你的 WPF 应用支持 Windows 跳转列表功能. 本文内容 一个简单的跳转列表程序 定制跳转列表的功能 一个简单的跳转列表程序

Windows下Ionic Android开发环境搭建

转自 http://www.itwap.net/ArticleContent.aspx?id=26 来源: itwap.net 作者: 词略 时间: 2015-4-2 16:57:28 (一)Ionic简单介绍:   首先,Ionic是什么. Ionic是一款基于PhoneGap及AngularJS开发Hybrid/Web APP的前端框架,类似的其他框架有:Intel XDK等. 简单来说就是可以将你的Web应用打包发布成IOS/Android APP,并且提供了PhoneGap之外很多强大的

推荐提升效率的4个Windows 10任务栏快捷键

关于Linux的学习请关注书籍<Linux就该这么学>,还可以关注Linuxprobe网站 从 Windows 95 开始到现在的 Windows 10 系统,「任务栏」一直是 Windows 的重要组成部分和标志,虽然在使用过程中仍时不时会遇到一些奇怪问题,但时至今日无可否认,它在外观和功能上都已经有了突飞猛进的改善. Windows 10 中的任务栏可以算是(我个人认为)最好用的一个迭代版本,用户不仅可以在多个方面对其进行自定义定制,还可以进行调整让它更符合你的使用习惯,提高生产效率. 但

CozyRSS开发记录5-订阅列表栏里的项

CozyRSS开发记录5-订阅列表栏里的项 1.订阅列表栏里的项的原型图 这里列表项依然参考傲游的RSS阅读器,以后可能会微调. 2.使用ControlTemplate来定制ListBoxItem 给展示RSS源名称的TextBlock设置MaxWidth和ToolTip,是为了优化名称过长的情况. 这里暂时把内容都写死,后面会使用MVVM和bindling来处理. 3.ListBox效果展示 最后,我们修改ListBox的xaml,用上我们的模版. 效果还行

在windows下进行linux开发:利用Vagrant+virtualbox(ShowDoc与mp3dish的作者)

1,介绍Vagrant 我们做web开发的时候经常要安装各种本地测试环境,比如apache,php,mysql,redis等等.出于个人使用习惯,可能我们还是比较习惯用windows.虽然说在windows下搭建各种开发环境是可行的,各大开发环境都有windows版本.然而在windows下配置有时候会显得繁琐,并且还会导致开发环境(windows)和生产环境(lunix)不一致.能不能在windows下也像linux那样开发?也许你想到了,用虚拟机.用虚拟机装个linux系统就好了.装完lin