65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在 Windows Forms 中创建带有自定义事件的自定义 Jump List

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (13投票s)

2010年8月23日

CPOL

4分钟阅读

viewsIcon

76689

downloadIcon

2714

创建具有自定义事件的自定义 JumpList 并检查其在 Windows Forms 3.5 中的所有功能

Jumplist Jumplist

引言

Windows 7 引入了一组新功能 - 其中一个(也是最突出的功能之一)是 Jumplist,所以我们将探讨 Jumplist 的功能,我将向您展示如何处理从 Jumplist 中的自定义任务触发的自定义事件。

Jump Lists

简单来说,Jumplist 可以称为 Windows 7 中任务栏项的右键菜单,它们可以包含不同的项目集(类别),可以执行不同的任务(您可以查看 MSN Messenger 或 Internet Explorer 的 jumplist 以便更清楚)。每个应用程序默认都有自己的 jumplist,所以即使您的应用程序没有做任何事情,您也会得到包含这三个任务的默认 Jumplist(应用程序名称(在我们的例子中是 JumplistDemo)、将此程序固定到任务栏和关闭窗口)。

任何 Jumplist 都由类别组成,每个类别都有自己的 Jumptask。到目前为止,WindowsAPICodePack 支持两种类型的 Jumptask;JumplistLink(如截图中的记事本链接)和 JumplistSeperator(如画图和计算器之间的分隔符)。Jumptask 代表用户执行的操作,例如打开应用程序的新实例或启动另一个程序。这些 Jumptask 被分组到称为 JumplistCustomCategories 的类别中(如截图中的“操作”类别)。

如何为您的应用程序构建自定义 JumpList

为了能够处理 Windows Forms 中的 Jumplist 类,您需要在项目中包含这些 DLL(Microsoft.WindowsAPICodePack.dllMicrosoft.WindowsAPICodePack.Shell.dll)。您可以从附加的项目中获取它们,或者从 WindowsAPICodePack 下载开源库,其中包含可用于访问 Windows 7 和 Windows Vista 功能的源代码。

所以让我们来探索一下如何构建 Jumplist

//declaration of our list, windowHandle is the handle of the window 
//you want the JumpList to be attached to
JumpList list = JumpList.CreateJumpListForIndividualWindow
		(TaskbarManager.Instance.ApplicationId, windowHandle);

//defining a new Custom Category called Actions
JumpListCustomCategory userActionsCategory = new JumpListCustomCategory("Actions");

//defining the JumpListLink "Clear History"
JumpListLink userActionLink = new JumpListLink
	(Assembly.GetEntryAssembly().Location, "Clear History");
userActionLink.Arguments = "-1";

//add this link to the Actions Category
userActionsCategory.AddJumpListItems(userActionLink);

//finally add the category to the JumpList
list.AddCustomCategories(userActionsCategory);

上面的代码将创建一个 new Jumplist,其中包含一个名为 Actions 的自定义类别,以及一个名为 Clear History 的 JumpListLink。此链接将用于从 Jumplist 向应用程序发送消息。我们稍后会看到如何做到这一点,所以让我们完成 Jumplist 的实现。

//get the notepad.exe path
string notepadPath = Path.Combine(Environment.SystemDirectory, "notepad.exe");

//attach it to the JumpListLink
JumpListLink jlNotepad = new JumpListLink(notepadPath, "Notepad");

//set its icon path
jlNotepad.IconReference = new IconReference(notepadPath, 0);

//add it to the list
list.AddUserTasks(jlNotepad);

我们将对计算器和画图链接执行相同的步骤。只要我们没有为这些链接指定自定义类别,它们就会被分组到“任务”类别下,所以在完成列表构建后,我们必须调用 Refresh() 方法才能应用这些设置。您将在附加项目源代码的 MyJumplist 类中找到 JumpList 的完整实现。

list.Refresh();

您现在可以运行您的应用程序并检查新修改的 JumpList

响应自定义事件

附加的项目是一个非常简单的 Windows 应用程序,它有一个带有按钮的单个窗体,其中一个按钮是“清除历史记录”按钮,它会清除列表框并将“最近操作”标签更改为“清除历史记录”。从窗体上的“清除历史记录”按钮可以轻松完成此操作,但如何从“清除历史记录” JumplistLink 执行相同的操作呢?实际上,我们无法处理 JumpList 中任何链接的单击事件,但我们希望在 JumplistLink 被单击时收到通知;在对该问题(如何使 jumplist 调用应用程序中编写的一些方法并响应自定义事件)进行广泛搜索后,我发现最好的方法是在 Jumplist 和应用程序之间发送消息以处理这些自定义事件(感谢这篇文章:Windows 7: Jump Lists),所以我们将注册一个将在单击“清除历史记录”链接后发送的消息,我们的应用程序将通过重写 WndProc 方法来捕获此消息。

我在我的解决方案中包含了帮助类 WindowsMessageHelper,该类来自 Windows 7: Jump Lists 文章。该类调用了一些 API 来发送和注册消息,因此我们需要执行三个步骤才能在 Jumplist 和应用程序之间发送消息。

首先,通过 WindowsMessageHelper 类中的 static 方法 RegisterWindowMessage 注册消息。

//RegisterWindowMessage registers a window message and returns the message number
public static int ClearHistoryArg = 
	WindowsMessageHelper.RegisterWindowMessage("Jumplist.demo.ClearHistoryArg");

第二,重写 WndProc 方法并应用您的更改。

protected override void WndProc(ref Message m)
{
	//if the coming message has the same number as our registered message
	if (m.Msg == WindowsMessageHelper.ClearHistoryArg)
	{
		//clear history
		ClearHistory();

		//update recent action
		UpdateRecentAction(RecentActions.ClearHistory);
	}
	else
	{
		base.WndProc(ref m);
	}
}

第三,实现将消息发送到应用程序的方法。

public static void HandleCmdLineArgs()
{
	if (Environment.GetCommandLineArgs().Length > 1)
	{
		switch (Environment.GetCommandLineArgs()[1])
		{
			case "-1":
                        WindowsMessageHelper.SendMessage
			("Jumplist.demo", WindowsMessageHelper.ClearHistoryArg);
                        break;
		}
	}
}

在前面的方法中,我们检查其他命令行参数,因为该数组的第一个元素是执行程序的名称,这就是为什么我们检查 Length 是否大于 1 的原因。请记住,在 switch-case 子句中的值 -1 代表我们在创建 JumpList 时为 Clear History JumplistLink 设置的 Argument 值,因此如果您想添加更多自定义链接,可以为它们的参数设置任何您想要的值,并在该方法中用它们的值来捕获。

参考文献

结语

我已附加了一个充分说明上述步骤的项目,希望您觉得它很有用。

历史

本文由我(Ahmed Said)于 2010 年 8 月 23 日撰写。

© . All rights reserved.