If you've noticed in the Windows 7 beta, if you copy files or other system actions, the windows explorer icon in the taskbar will fill up with a green progress bar equivalent to the progress bar on the form. Is there a way that, in my C# forms, I can force my taskbar progress bar to match the progress of whatever task I'm doing? Converting, transferring, generating, there are so many uses for that progress bar.
问题:
回答1:
I just wanted to add some taskbar progress animation to my WinForms application, without having to download code packs or switch to WPF to use TaskbarItemInfo.
The solution was a class that uses the ITaskbarList3 interface:
using System;
using System.Runtime.InteropServices;
public static class TaskbarProgress
{
public enum TaskbarStates
{
NoProgress = 0,
Indeterminate = 0x1,
Normal = 0x2,
Error = 0x4,
Paused = 0x8
}
[ComImport()]
[Guid("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface ITaskbarList3
{
// ITaskbarList
[PreserveSig]
void HrInit();
[PreserveSig]
void AddTab(IntPtr hwnd);
[PreserveSig]
void DeleteTab(IntPtr hwnd);
[PreserveSig]
void ActivateTab(IntPtr hwnd);
[PreserveSig]
void SetActiveAlt(IntPtr hwnd);
// ITaskbarList2
[PreserveSig]
void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
// ITaskbarList3
[PreserveSig]
void SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal);
[PreserveSig]
void SetProgressState(IntPtr hwnd, TaskbarStates state);
}
[ComImport()]
[Guid("56fdf344-fd6d-11d0-958a-006097c9a090")]
[ClassInterface(ClassInterfaceType.None)]
private class TaskbarInstance
{
}
private static ITaskbarList3 taskbarInstance = (ITaskbarList3)new TaskbarInstance();
private static bool taskbarSupported = Environment.OSVersion.Version >= new Version(6, 1);
public static void SetState(IntPtr windowHandle, TaskbarStates taskbarState)
{
if (taskbarSupported) taskbarInstance.SetProgressState(windowHandle, taskbarState);
}
public static void SetValue(IntPtr windowHandle, double progressValue, double progressMax)
{
if (taskbarSupported) taskbarInstance.SetProgressValue(windowHandle, (ulong)progressValue, (ulong)progressMax);
}
}
Example of how easy it is to use:
TaskbarProgress.SetState(this.Handle, TaskbarProgress.TaskbarStates.Indeterminate);
or
TaskbarProgress.SetValue(this.Handle, 50, 100);
TaskbarProgress.SetState(this.Handle, TaskbarProgress.TaskbarStates.Error);
回答2:
For people who want to skip reading the documentation and just get something that works...
- Download the Windows API Code Pack for Microsoft .Net Framework.
- Run the installer which creates a zip file
- Extract the following dlls from the binaries folder of the zip file:
Microsoft.WindowsAPICodePack.dll
Microsoft.WindowsAPICodePack.Shell.dll
- Add a reference to them in your project
- Put the following code into your app and modify as necessary:
--
int max = 100;
var prog = Microsoft.WindowsAPICodePack.Taskbar.TaskbarManager.Instance;
prog.SetProgressState(Microsoft.WindowsAPICodePack.Taskbar.TaskbarProgressBarState.Normal);
for(int i=0;i<max;i++) {
prog.SetProgressValue(i, max);
Thread.Sleep(100);
}
prog.SetProgressState(Microsoft.WindowsAPICodePack.Taskbar.TaskbarProgressBarState.NoProgress);
回答3:
Look into the Windows API Code Pack for Microsoft .Net Framework.
回答4:
Yes, Microsoft covered the new taskbar functions in the following document (sources included): Windows 7 taskbar: Developer Resources
回答5:
Yes, you need to use this API.
http://code.msdn.microsoft.com/WindowsAPICodePack
回答6:
I found a beautiful article (Link) that provides a simple solution to the taskbar progress bar problem. In summary, it instructs you to download the Windows API pack from the MSDN website, adding a reference to the Microsoft.WindowsAPICodePack.Shell.dll that it contains, and finally add three lines of code to your application:
Imports Microsoft.WindowsAPICodePack
Imports Microsoft.WindowsAPICodePack.Taskbar
// ...
TaskbarManager.Instance.SetProgressValue(X, 100)
where X is the progress you want to display.