Windows 7 新功能:VB.NET 和 C# 实战教程
介绍 Windows 7 中所有必备的新功能,让您的应用程序看起来光鲜亮丽且专业,例如新的任务栏功能等。
引言
这是一份快速的分步指南,旨在帮助所有 .NET 开发人员充分利用 Windows 7 的新功能。
您将需要什么
- Visual Studio 2008 或 2010
- 适用于 Microsoft .NET Framework 的 Windows API Code Pack (可从 http://code.msdn.microsoft.com/WindowsAPICodePack 下载)
- .NET Framework 3.5 SP1 或更高版本。
- 一台 Windows 7 机器。
准备工作
您需要编译 Windows API Code Pack 的 DLL。解压缩 WindowsAPICodePack.zip 文件后,打开位于 WindowsAPICodePack 文件夹内的 WindowsAPICodePack.sln 文件并生成解决方案。这将生成以下 DLL
- 核心
- Shell (注意:这取决于 Core 项目)
您需要在您的应用程序中添加对它们的引用。
与不同 Windows 版本的兼容性
如果调用了仅限于 Windows 7 的功能,而在 Windows Vista 或 Windows XP 下运行,应用程序将崩溃并退出。因此,为了防止应用程序崩溃并确保与不同 Windows 版本的兼容性,您需要检查当前运行的 Windows 版本。
- 通过检查
MS.WindowsAPICodePack.Internal.CoreHelpers
下的共享布尔属性RunningOnWin7
、RunningOnVista
和RunningOnXP
,您需要在将 WindowsAPICodePack\Core 项目源代码添加到解决方案或其 DLL 后,添加对它的引用。 - 在使用
TaskbarManager
类时,您会发现它提供了一个简单的布尔属性IsPlatformCompatible
,您可以在调用代码之前使用它进行简单的检查。
从这里开始,您可以跳到本文的任何部分,继续学习您感兴趣的功能,因为本文的以下所有部分都是相互独立的。
跳转列表 (Jump lists)
应用程序在任务栏上的图标右键菜单中新增了 JumpLists 功能。您也可以在“开始”菜单的应用程序快捷方式中看到它。您可以添加自己的快捷方式到菜单中,并根据喜好进行分类。这些快捷方式可以指向任何内容,例如最近的文档、常用的文档和应用程序功能。它非常易于使用,但有几点您需要了解才能成功使用它
- 应用程序必须在任务栏上有一个有效的图标,因此您不能使用加载事件(例如)来创建跳转列表的新实例。
- 如果要添加文件,您必须确保文件与您的应用程序存在关联关系,例如,要添加“file.abc”,您需要确保 abc 文件类型已与您的应用程序关联。
- 您可以将项目添加到跳转列表的“用户任务”或“最近”部分,或者创建您自己的自定义类别。
- 要实际添加或更新跳转列表,您需要调用您创建的新跳转列表实例中的
refresh()
方法。
在您自己的应用程序中使用跳转列表
- 添加对 Microsoft.WindowsAPICodePack.Shell 和 Microsoft.WindowsAPICodePack 的引用。
- 您将使用
Microsoft.WindowsAPICodePack.Taskbar
和Microsoft.WindowsAPICodePack.Shell
命名空间。 - 在窗口创建后创建一个
JumpList
类的实例,这可以通过 WinForms 中的shown
事件或 WPF 中的loaded
事件来完成。 - 您可以在用户任务或最近部分向跳转列表添加不同的项目,或创建您自己的自定义类别。
- 通过调用
Refresh
方法显示跳转列表。
VB
Dim JList As JumpList
JList = JumpList.CreateJumpList()
JList.ClearAllUserTasks()
'Add 2 Links to the Usertasks with a Separator
Dim Link0 As New JumpListLink("cmd.exe", "Cmd") With {.IconReference =
New IconReference("cmd.exe", 0)}
Dim Link1 As New JumpListLink("Calc.exe", "Calculator") With {.IconReference =
New IconReference("Calc.exe", 0)}
JList.AddUserTasks(Link0)
JList.AddUserTasks(New JumpListSeparator())
JList.AddUserTasks(Link1)
'Create a Custom Category and Add an Item to it
Dim Link2 As New JumpListLink("Notepad.exe", "Notepad") With {.IconReference =
New IconReference("Notepad.exe", 0)}
Dim Category As New JumpListCustomCategory("New Category 1")
Category.AddJumpListItems(Link2)
JList.AddCustomCategories(Category)
'Add another Item to the Category But separete with a separator
Dim Link3 As New JumpListLink("mspaint.exe", "Paint") With {.IconReference =
New IconReference("mspaint.exe", 0)}
Category.AddJumpListItems(Link3)
'to control which category Recent/Frequent is displayed
JList.KnownCategoryToDisplay = JumpListKnownCategoryType.Frequent
JList.Refresh()
C#
JumpList JList = default(JumpList);
JList = JumpList.CreateJumpList();
JList.ClearAllUserTasks();
//Add 2 Links to the Usertasks with a Separator
JumpListLink Link0 = new JumpListLink("cmd.exe", "Cmd") { IconReference =
new IconReference("cmd.exe", 0) };
JumpListLink Link1 = new JumpListLink("Calc.exe", "Calculator") {
IconReference = new IconReference("Calc.exe", 0) };
JList.AddUserTasks(Link0);
JList.AddUserTasks(new JumpListSeparator());
JList.AddUserTasks(Link1);
//Create a Custom Category and Add an Item to it
JumpListLink Link2 = new JumpListLink("Notepad.exe", "Notepad") {
IconReference = new IconReference("Notepad.exe", 0) };
JumpListCustomCategory Category = new JumpListCustomCategory(
"New Category 1");
Category.AddJumpListItems(Link2);
JList.AddCustomCategories(Category);
//Add another Item to the Category But separete with a separator
JumpListLink Link3 = new JumpListLink("mspaint.exe", "Paint") {
IconReference = new IconReference("mspaint.exe", 0) };
Category.AddJumpListItems(Link3);
//to control which category Recent/Frequent is displayed
JList.KnownCategoryToDisplay = JumpListKnownCategoryType.Frequent;
JList.Refresh();
关于跳转列表的最后一点要注意的是,您可以向跳转列表中添加命令,这些命令将在您运行的应用程序中执行。例如,要添加“播放歌曲”或“新建文档”,在 API Code Pack 或 .NET Framework 中没有简单直接的方法。要添加命令,您可以向跳转列表中添加一个指向您应用程序的条目,并添加一个命令行参数,该参数将传递给您的应用程序。这将运行您应用程序的另一个实例,并将命令行参数传递给它。接下来您需要做的是,如果向应用程序传递了命令,它需要将其发送到应用程序的第一个实例,这称为进程间通信 (IPC),并且有多种实现方式。例如,您可以使用内存映射文件、TCP/IP 套接字或命名内核对象。一个选项是使用命名管道,它提供了一种在不更改安全或防火墙设置的情况下发送消息的直接方法,但这超出了本文的范围。我相信您会在 CodeProject 上找到许多涵盖此主题的文章。
图标叠加 (Icon overlay)
Windows 7 的这项新功能将使您能够更新任务栏上显示的应用程序图标。通过叠加,您可以用来指示状态更改或错误。例如,您可以通过叠加一个较小的图标来实现这一点,它将放置在主窗口图标的右下角以指示应用程序的状态。
要使用任务栏图标叠加,您需要
- 添加对 Microsoft.WindowsAPICodePack.Shell 和 Microsoft.WindowsAPICodePack 的引用。
- 您将使用
Microsoft.WindowsAPICodePack.Taskbar
和Microsoft.WindowsAPICodePack.Shell
命名空间。 - 更改叠加图标
TaskbarManager.Instance.SetOverlayIcon(Icon, "accessibility text")
SetOverlayIcon
方法接受一个 System.Drawing.Icon
对象和一个用于可访问性的文本。我想提一下 API Code Pack 中的 StockIcon
类。该类可用于从系统图标返回一个图标。
StockIcon
构造函数接受四个参数
- 一个
enum
值,代表一个非常大的股票图标集合。 - 图标大小,这不会改变叠加图标的大小,而是改变返回图标本身的大小,因为有些图标有多个位图用于不同的尺寸。
IsLink
是一个布尔值,如果为 true,将在返回图标上显示一个小的快捷方式箭头。IsSelected
是一个布尔值,它会稍微变暗返回的图标,以指示选定的状态。
VB
Dim ID As StockIconIdentifier =StockIconIdentifier.Shield
Dim Size As StockIconSizes =ShellSize
Dim SelectedIcon As New Microsoft.WindowsAPICodePack.Shell.StockIcon(ID, Size, false,
false)
TaskbarManager.Instance.SetOverlayIcon(Me.Handle, SelectedIcon.Icon, "Icon Name")
C#
StockIconIdentifier ID = StockIconIdentifier.Shield;
StockIconSizes Size = ShellSize;
Microsoft.WindowsAPICodePack.Shell.StockIcon SelectedIcon =
new Microsoft.WindowsAPICodePack.Shell.StockIcon(ID, Size, false, false);
TaskbarManager.Instance.SetOverlayIcon(this.Handle, SelectedIcon.Icon, "Icon Name");
进度条
Windows 7 任务栏上每个应用程序图标的区域都提供了新功能。如果您使用 Internet Explorer 8 下载文件,您会注意到图标背景可以充当进度条。
要使用任务栏进度条,您需要
- 添加对 Microsoft.WindowsAPICodePack.Shell 和 Microsoft.WindowsAPICodePack 的引用。
- 您将使用
Microsoft.WindowsAPICodePack.Taskbar
命名空间。 - 设置进度条值
- 更改进度条的状态
TaskbarManager.Instance.SetProgressValue(Value, Maximum , handle )
SetProgressValue
接受值、最大值以及显示进度条的窗口句柄。
TaskbarManager.Instance.SetProgressState
SetProgressState
接受一个单一的枚举参数 (TaskbarProgressBarState
),它具有以下值
NoProgress
:不显示进度。Indeterminate
:进度不确定(跑马灯效果)。Normal
:显示正常进度(绿色)。Error
:错误进度条(红色)。Paused
:暂停的进度条(黄色)。请注意,它所做的只是将颜色更改为黄色;如果您更改进度条的值,它会移动并且会一直保持黄色。
另请注意,如果您在将状态设置为 NoProgress
或 Indeterminate
后更改进度条的值,进度条将自动恢复到正常状态。
非常重要的一点:设置进度条值或更改状态的两种方法都有两个重载:第二个允许您选择要在其上显示进度条的窗口。如果您没有设置窗口句柄,进度条将显示在任务栏上的主应用程序图标上,而不是在带有进度条的打开窗口上。
不传递窗口句柄的另一个效果是,当进度窗口关闭时,进度条不会自动从主应用程序图标中清除,您需要手动清除它。为了更清楚地理解这一点,右键单击任务栏 > 属性 > 并将任务栏按钮设置为“从不合并”,然后使用本文提供的源代码进行实验,以了解传递窗口句柄与否的区别。
缩略图工具栏 (Thumbnail toolbars)
缩略图工具栏使用户即使在应用程序未获得焦点,或应用程序窗口隐藏在其他窗口后面而无法在屏幕上看到的情况下,也能访问应用程序的功能。它使您无需切换到应用程序并使其成为活动窗口即可访问应用程序。打开“Windows Media Player”可以很好地展示缩略图工具栏的功能。
要能够向缩略图工具栏添加按钮,需要遵循一些规则
- 您最多只能添加 7 个按钮,尺寸为 16 x 16 像素。
- 只能在添加按钮后隐藏它,一旦任务栏图标显示,就无法添加或删除按钮。
要添加缩略图工具栏,您需要
- 使用
ThumbnailToolbarButton
创建您想要添加的按钮实例。 - 通过调用
TaskbarManager.Instance.ThumbnailToolbars.AddButtons
方法将按钮添加到缩略图工具栏。此方法将接受您想要添加缩略图工具栏按钮的窗口句柄以及您想要添加的按钮实例。
VB
Dim B1Icon As Icon = New StockIcon(StockIconIdentifier.Shield).Icon
Dim B2Icon As Icon = New StockIcon(StockIconIdentifier.Users).Icon
Dim B3Icon As Icon = New StockIcon(StockIconIdentifier.Help).Icon
Dim button1 As New ThumbnailToolbarButton(B1Icon, "First Button")
Dim WithEvents button2 As New ThumbnailToolbarButton(B2Icon, "Second Button")
Dim WithEvents button3 As New ThumbnailToolbarButton(B3Icon, "Third Button")
AddHandler button1.Click, AddressOf Button_Click
AddHandler button2.Click, AddressOf Button_Click
AddHandler button3.Click, AddressOf Button_Click
'You can show or hide the buttons
button1.Visible = Not button1.Visible
'You can enable or disable the buttons
button2.Enabled = Not button2.Enabled
'And you can chnage the button tool tip text
button3.Tooltip = txtTooltip.Text
Sub Button_Click(ByVal sender As Object, ByVal e As ThumbnailButtonClickedEventArgs)
Me.EventsList.Items.Add(e.ThumbnailButton.Tooltip & " Clicked")
End Sub
C#
Icon B1Icon = new StockIcon(StockIconIdentifier.Shield).Icon;
Icon B2Icon = new StockIcon(StockIconIdentifier.Users).Icon;
Icon B3Icon = new StockIcon(StockIconIdentifier.Help).Icon;
ThumbnailToolbarButton button1 =
new Microsoft.WindowsAPICodePack.Taskbar.ThumbnailToolbarButton (B1Icon,
"First Button");
ThumbnailToolbarButton button2 =
new Microsoft.WindowsAPICodePack.Taskbar.ThumbnailToolbarButton(B2Icon,
"Second Button");
ThumbnailToolbarButton button3 =
new Microsoft.WindowsAPICodePack.Taskbar.ThumbnailToolbarButton(B3Icon,
"Third Button");
button1.Click += button_Click;
button2.Click += button_Click;
button3.Click += button_Click;
TaskbarManager.Instance.ThumbnailToolbars.AddButtons(this.Handle,button1,button2,button3);
//You can show or hide the buttons
button1.Visible = !button1.Visible;
//You can enable or disable the buttons
button2.Enabled = !button2.Enabled;
//And you can chnage the button tool tip text
button3.Tooltip = txtTooltip.Text;
网络管理 (Network management)
您可以使用它来了解应用程序正在运行的计算机是否具有网络连接。如果连接到互联网,则检索网络名称。如果您在域中,则获取 NetworkID,以及更多信息。
要利用网络管理 API,您需要
- 添加对 Microsoft.WindowsAPICodePack 的引用,仅限 Core 项目。
- 您将使用
Microsoft.WindowsAPICodePack.Net
命名空间。 - 要列出所有可用网络,请调用
NetworkListManager.GetNetworks()
方法。它接受一个枚举参数 All
:返回所有网络,包括已连接和断开连接的网络。Connected
:仅返回已连接的网络。Disconnected
:仅返回已断开连接的网络。- 您可以遍历返回的网络列表以获取有关所有网络的信息,例如网络 ID(即网络接口的 GUID)、网络名称、网络描述、它是否为域、此网络连接的创建时间、连接时间,以及该网络下的所有可用连接。
VB
Dim networks As NetworkCollection = _
NetworkListManager.GetNetworks(NetworkConnectivityLevels.All)
For Each n As Network In networks
Dim network As Network = n
txtName.Text = network.Name
txtDecription.Text = network.Description
txtDomainType.Text = network.DomainType.ToString()
chkIsConnected.Checked = network.IsConnected
chInternet.Checked = network.IsConnectedToInternet
txtCategory.Text = network.Category.ToString()
txtCreatedTime.Text = network.CreatedTime.ToString()
txtConnectedTime.Text = network.ConnectedTime.ToString()
txtConnectivity.Text = network.Connectivity.ToString()
Dim Connections As NetworkConnectionCollection = network.Connections
For Each Connection As NetworkConnection In network.Connections
lstConnections.Items.Add("ConnectionID: " &
Connection.ConnectionId.ToString)
lstConnections.Items.Add("Adapter ID:: " & Connection.AdapterId.ToString)
Next
End If
Next
C#
NetworkCollection networks =
NetworkListManager.GetNetworks(NetworkConnectivityLevels.All);
foreach (Network n in networks) {
Network network = n;
txtName.Text = network.Name;
txtDecription.Text = network.Description;
txtDomainType.Text = network.DomainType.ToString();
chkIsConnected.Checked = network.IsConnected;
chInternet.Checked = network.IsConnectedToInternet;
txtCategory.Text = network.Category.ToString();
txtCreatedTime.Text = network.CreatedTime.ToString();
txtConnectedTime.Text = network.ConnectedTime.ToString();
txtConnectivity.Text = network.Connectivity.ToString();
NetworkConnectionCollection Connections = network.Connections;
foreach (NetworkConnection Connection in network.Connections) {
lstConnections.Items.Add("ConnectionID: " +
Connection.ConnectionId.ToString);
lstConnections.Items.Add("Adapter ID:: " +
Connection.AdapterId.ToString);
}
}