Winforms: Windows 7中Taskbar的新效果(1)——概述

来源:互联网 发布:和珅 王刚 知乎 编辑:程序博客网 时间:2024/06/06 15:47

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的最新效果。