如何为Windows 7编写进度条并在任务栏上更新?

23

Windows 7有一个非常棒的新功能,就是应用程序可以通过状态栏报告当前活动的进度。例如,使用Windows资源管理器复制文件时,会在任务栏中的应用程序图标上叠加一个进度条,并显示更新的进度。

如何暴露进度条的API?是否有MSDN文档提供相关信息?

5个回答

48

对于低于.NET 4的版本,或任何.NET版本中的WinForms

使用Microsoft的Windows API Code Pack(如Keeron所提到的),非常简单。您只需要使用TaskbarManager即可。例如:

开始进度:

TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal);

更新进度:

TaskbarManager.Instance.SetProgressValue(currentValue, maxProgressValue);

当你完成时,要结束进程:

TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.NoProgress);

还有很多事情可以做,但这些应该能帮你入门并且可能是你所需要的所有内容。

针对使用 WPF 的 .NET 4 及以上版本

你可以使用 System.Windows.Shell.TaskbarItemInfo。例如,在你的主窗口的 Xaml 中,你需要添加:

<Window.TaskbarItemInfo>
    <TaskbarItemInfo x:Name="taskBarItemInfo" />
</Window.TaskbarItemInfo>

然后要更新进度,你可以这样做:

taskBarItemInfo.ProgressState = TaskbarItemProgressState.Normal;

for (int i = 0; i < 100; i++)
{
    taskBarItemInfo.ProgressValue = i / 100.0;
    Thread.Sleep(50); // whatever the 'work' really is
}

taskBarItemInfo.ProgressState = TaskbarItemProgressState.None;

不要忘记,如果你正在一个后台线程上执行“工作”(对于长时间运行的任务可能是个好主意),你需要切换回UI线程来更新任务栏。


4
Windows API CodePack的链接已经失效,但是通过nuget仍然可以获取。链接为http://www.nuget.org/packages/Microsoft.WindowsAPICodePack-Core/。 - Mark Hall
1
答案和评论中链接的包实际上并不包含所需的类。该类在Shell包中:https://www.nuget.org/packages/WindowsAPICodePack-Shell/ - Roman Starkov
我花了一些时间才弄清楚,在系统属性>高级>性能选项>视觉效果中禁用“任务栏和开始菜单中的动画”选项时,Indeterminate没有任何效果。 - Ben Hutchison
重要的是要记住,.ProgressValue以0到1的分数运行。 - DJ van Wyk

12

MSDN杂志上有一篇很棒的文章介绍新的任务栏API。而且,这个功能真的很棒 :-)

基本上,它就是关于实现IFileOperation的内容。在这里有一篇使用托管代码的好文章


你的第二个链接似乎已经失效了。 - Cameron
1
我改成了链接到archive.org。 - sigint

5

如果您计划使用其他Windows 7任务栏功能,另一种方法是使用来自Microsoft的库:.NET Framework的Windows API Code Pack,该库不再可在旧链接找到,但可以在nuget上找到。


1
我写了一篇关于在C#中实现Windows 7任务栏进度API的文章(请参见:使用C#和.NET实现Windows 7任务栏进度条)。该控件是开源的(BSD许可证),并且有C#和VB.NET的示例项目。
这样,您就不必从头开始转换C++代码了。

0

其实我使用Telerik的RadWindow,你不能仅仅使用<telerik:RadWindow.TaskbarItemInfo>。所以我为net6.0-windows WPF使用此解决方法:

在代码后台文件中,我创建了一个属性:

public Lazy<TaskbarItemInfo> TaskbarItemInfo { get; set; } = new Lazy<TaskbarItemInfo>(() => 
{
   return System.Windows.Application.Current.MainWindow.TaskbarItemInfo = new TaskbarItemInfo(); 
});

BackgroundWorker 的方法部分
private void WorkerProgressChanged(object sender, ProgressChangedEventArgs e)

我设置了进度的值:

TaskbarItemInfo.Value.ProgressState = TaskbarItemProgressState.Normal;
TaskbarItemInfo.Value.ProgressValue = (double)progressUserState.ProgressInPercent / 100;

private void WorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

我重置了状态:

TaskbarItemInfo.Value.ProgressValue = 0;
TaskbarItemInfo.Value.ProgressState = TaskbarItemProgressState.None;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接