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

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

C# Windows 7任务栏开发之跳转列表(Jump Lists)_第1张图片


      “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);
/// 
        /// 添加User Tasks
        /// 
        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 内容。

C# Windows 7任务栏开发之跳转列表(Jump Lists)_第2张图片

创建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
{
    /// 
    /// 注册文件关联的应用程序的辅助类
    /// 
    public class FileAssociationsHelper
    {
        private static RegistryKey classesRoot;  // 注册表的根目录

        private static void Process(string[] args)
        {
            if (args.Length < 6)
            {
                string error = ("Usage:       [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 argList = new List();
                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)
            {
               
            }
        }

        /// 
        /// 注册类标识符
        /// 
        /// 类标识符
        /// 应用程序Id
        /// 打开文件的进程全路径
        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();
        }

        /// 
        /// 注销类标识符
        /// 
        /// 类标识符
        private static void UnregisterProgId(string progId)
        {
            try
            {
                classesRoot.DeleteSubKeyTree(progId);
            }
            catch { }
        }

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

        /// 
        /// 注销文件关联
        /// 
        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)
            {
                
            }
        }

        /// 
        /// 类标识符注册操作
        /// 
        /// 注册或注销
        /// 类标识符
        /// 是否在HKCU中注册文件关联 -- false
        /// 应用程序Id
        /// 打开文件的进程全路径
        /// 文件关联列表
        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:用户操作被取消。
                {
                    // 该操作已经被用户取消
                }
            }
        }

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

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

        /// 
        /// 注销类标识符的文件关联
        /// 
        /// 类标识符
        /// 是否在HKCU中注册文件关联 -- false
        /// 应用程序Id
        /// 打开文件的进程全路径
        /// 文件关联列表
        public static void UnregisterFileAssociations(string progId, bool registerInHKCU, string appId, string openWith,
                                                      params string[] extensions)
        {
            InternalRegisterFileAssociations(true, progId, registerInHKCU, appId, openWith, extensions);
        }
    }
}
/// 
/// 添加Known Tasks
/// 
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方法,让衔接的路径可以传入应用程序,以便打开应用程序关联的文件:

/// 
/// 应用程序的主入口点。
/// 
[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 });
}
/// 
/// 应用程序文件
/// 
public string FilePath
{
    get { return (_strFilePath); }
    set
    {
        _strFilePath = value;
        if (!string.IsNullOrEmpty(_strFilePath))
        {
            _pictureBox.ImageLocation = _strFilePath;
        }
    }
}
C# Windows 7任务栏开发之跳转列表(Jump Lists)_第3张图片

创建Custom Category 列表

      如同上文创建JumpList 的方式:

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

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

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

/// 
/// 添加Custom Tasks
/// 
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();
    }
}
C# Windows 7任务栏开发之跳转列表(Jump Lists)_第4张图片



你可能感兴趣的:(#,C#)