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("", "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, // 0registerInHKCU, // 1appId, // 2openWith,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方法,让衔接的路径可以传入应用程序,以便打开应用程序关联的文件:

到一个新的环境去欣赏去看去听,

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

相关文章:

你感兴趣的文章:

标签云: