Win7推出之后,很多用户发现Windows的界面漂亮了很多。在这些界面中,Taskbar是最引人注目的一个更新。在最新的Taskbar中,缩略图能显示更加丰富的信息。右键点击Taskbar上的按钮,弹出的菜单提供了很多选项以方便用户的操作。比如右键单击文件管理器Explorer的按钮,就会在弹出的菜单中列出用户最经常浏览的文件夹。
微软在推出新的Taskbar效果的同时,也推出了一系列对应的API。调用这些API,程序员可以开发出具有很酷效果的应用程序。在MSDN中,http://msdn.microsoft.com/en-us/library/dd378460(VS.85).aspx有这些API的详细用法介绍。
到目前为止,Winforms还没有提供对最新的Taskbar的支持。程序员如果想用Winforms开发出具有Win7效果的Taskbar,需要利用.NET提供的InterOp功能。我们用InterOp定义ITaskbarList4如下:
[ComImportAttribute()]
[GuidAttribute("c43dc798-95d1-4bea-9030-bb99e2983a1a")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITaskbarList4
{
// 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, TBPFLAG tbpFlags);
[PreserveSig]
void RegisterTab(IntPtr hwndTab, IntPtr hwndMDI);
[PreserveSig]
void UnregisterTab(IntPtr hwndTab);
[PreserveSig]
void SetTabOrder(IntPtr hwndTab, IntPtr hwndInsertBefore);
[PreserveSig]
void SetTabActive(IntPtr hwndTab, IntPtr hwndInsertBefore, uint dwReserved);
[PreserveSig]
HRESULT ThumbBarAddButtons(
IntPtr hwnd,
uint cButtons,
[MarshalAs(UnmanagedType.LPArray)] THUMBBUTTON[] pButtons);
[PreserveSig]
HRESULT ThumbBarUpdateButtons(
IntPtr hwnd,
uint cButtons,
[MarshalAs(UnmanagedType.LPArray)] THUMBBUTTON[] pButtons);
[PreserveSig]
void ThumbBarSetImageList(IntPtr hwnd, IntPtr himl);
[PreserveSig]
void SetOverlayIcon(
IntPtr hwnd,
IntPtr hIcon,
[MarshalAs(UnmanagedType.LPWStr)] string pszDescription);
[PreserveSig]
void SetThumbnailTooltip(
IntPtr hwnd,
[MarshalAs(UnmanagedType.LPWStr)] string pszTip);
[PreserveSig]
void SetThumbnailClip(
IntPtr hwnd,
ref RECT prcClip);
// ITaskbarList4
void SetTabProperties(IntPtr hwndTab, STPFLAG stpFlags);
}
internal enum TBPFLAG
{
TBPF_NOPROGRESS = 0,
TBPF_INDETERMINATE = 0x1,
TBPF_NORMAL = 0x2,
TBPF_ERROR = 0x4,
TBPF_PAUSED = 0x8
}
internal enum STPFLAG
{
STPF_NONE = 0x0,
STPF_USEAPPTHUMBNAILALWAYS = 0x1,
STPF_USEAPPTHUMBNAILWHENACTIVE = 0x2,
STPF_USEAPPPEEKALWAYS = 0x4,
STPF_USEAPPPEEKWHENACTIVE = 0x8
}
internal enum THBMASK
{
THB_BITMAP = 0x1,
THB_ICON = 0x2,
THB_TOOLTIP = 0x4,
THB_FLAGS = 0x8
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct THUMBBUTTON
{
/// <summary>
/// WPARAM value for a THUMBBUTTON being clicked.
/// </summary>
internal const int THBN_CLICKED = 0x1800;
[MarshalAs(UnmanagedType.U4)]
internal THBMASK dwMask;
internal uint iId;
internal uint iBitmap;
internal IntPtr hIcon;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
internal string szTip;
[MarshalAs(UnmanagedType.U4)]
internal THBFLAGS dwFlags;
}
[Flags]
internal enum THBFLAGS
{
THBF_ENABLED = 0x00000000,
THBF_DISABLED = 0x00000001,
THBF_DISMISSONCLICK = 0x00000002,
THBF_NOBACKGROUND = 0x00000004,
THBF_HIDDEN = 0x00000008,
THBF_NONINTERACTIVE = 0x00000010
}
另外,我们还需要声明接口ITaskbarList4的一个实现如下:
[GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComImportAttribute()]
internal class CTaskbarList { }
接下来我问定义类TaskbarManager来管理Taskbar,代码如下:
class TaskbarManager
{
// Hide the default constructor
private TaskbarManager()
{
}
// Best practice recommends defining a private object to lock on
private static Object syncLock = new Object();
// Internal implemenation of ITaskbarList4 interface
private ITaskbarList4 taskbarList;
internal ITaskbarList4 TaskbarList
{
get
{
if (taskbarList == null)
{
// Create a new instance of ITaskbarList3
lock (syncLock)
{
if (taskbarList == null)
{
taskbarList = (ITaskbarList4)new CTaskbarList();
taskbarList.HrInit();
}
}
}
return taskbarList;
}
}
private static volatile TaskbarManager instance;
/// <summary>
/// Represents an instance of the Windows Taskbar
/// </summary>
public static TaskbarManager Instance
{
get
{
ThrowIfNotSupport();
if (instance == null)
{
lock (syncLock)
{
if (instance == null)
instance = new TaskbarManager();
}
}
return instance;
}
}
public static void ThrowIfNotSupport()
{
bool isWin7 = Environment.OSVersion.Version.Major > 6;
bool isSever2008R2 = Environment.OSVersion.Version.Major == 6
&& Environment.OSVersion.Version.Minor >= 1;
if (!isWin7 && !isSever2008R2)
{
throw new PlatformNotSupportedException("Only supported on Windows 7/Sever2008 R2 or newer.");
}
}
}
运行ITaskbarList4至少需要Win7或者Server 2008 R2,因此在之前版本的Windows上我们只能抛出异常。
在接下来的几篇博客,我将详细介绍如果调用ITaskbarList4中的接口,实现Taskbar的最新效果。