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

本文介绍了如何使用Win7的Taskbar API为应用程序添加高级功能。通过.NET InterOp技术,开发者可以调用ITaskbarList4接口实现进度条、缩略图等效果。
部署运行你感兴趣的模型镜像

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

您可能感兴趣的与本文相关的镜像

Qwen-Image

Qwen-Image

图片生成
Qwen

Qwen-Image是阿里云通义千问团队于2025年8月发布的亿参数图像生成基础模型,其最大亮点是强大的复杂文本渲染和精确图像编辑能力,能够生成包含多行、段落级中英文文本的高保真图像

网上下载了emule0.50a-Xtreme8.1-sources源码,声称可以在VS2008下直接编译成功,经我实际测试,系统会报错,其中第一类错误,由于系统中为了兼容VISTA/WIN7,增加了相关定义,而这些定义在XP/WIN2003环境下会报错,共771个错误,如: 错误 2 error C2065:ITaskbarList3: 未声明的标识符 d:\emule相关资料\emule0.50a-xtreme\emule0.50a-xtreme8.1-sources\srchybrid\emuleDlg.h 195 emule 错误 3 error C2146: 语法错误 : 缺少“;”(在标识符“m_thbButtons”的前面) d:\emule相关资料\emule0.50a-xtreme\emule0.50a-xtreme8.1-sources\srchybrid\emuleDlg.h 196 emule 错误 4 error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int d:\emule相关资料\emule0.50a-xtreme\emule0.50a-xtreme8.1-sources\srchybrid\emuleDlg.h 196 emule 错误 5 error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int d:\emule相关资料\emule0.50a-xtreme\emule0.50a-xtreme8.1-sources\srchybrid\emuleDlg.h 196 emule 错误 6 error C2146: 语法错误 : 缺少“;”(在标识符“m_currentTBP_state”的前面) d:\emule相关资料\emule0.50a-xtreme\emule0.50a-xtreme8.1-sources\srchybrid\emuleDlg.h 198 emule 错误 7 error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int d:\emule相关资料\emule0.50a-xtreme\emule0.50a-xtreme8.1-sources\srchybrid\emuleDlg.h 198 emule 错误 8 error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int d:\emule相关资料\emule0.50a-xtreme\emule0.50a-xtreme8.1-sources\srchybrid\emuleDlg.h 198 emule 错误 10 error C2065:ITaskbarList3: 未声明的标识符 d:\emule相关资料\emule0.50a-xtreme\emule0.50a-xtreme8.1-sources\srchybrid\emuleDlg.h 195 emule ...... 此类错误中,ITaskbarList3是VISTA/WIN7环境下与任务栏相关的变量,只要屏闭掉相关定义就能正常。 除此之外还报有下面 5 个错误(实际引起错误的位置只有两个): 错误 135 error C2059: 语法错误 ::” d:\eMule\srchybrid\BaseClient.cpp 1603 emule 错误 136 error C2065: “tagName”: 未声明的标识符 d:\eMule\srchybrid\BaseClient.cpp 1604 emule 错误 137 error C2228: “.WriteTagToFile”的左边必须有类/结构/联合 d:\eMule\srchybrid\BaseClient.cpp 1604 emule 错误 139 error C2001: 常量中有换行符 d:\eMule\srchybrid\BaseClient.cpp 4832 emule 错误 140 fatal error C1057: 宏展开中遇到意外的文件结束 d:\eMule\srchybrid\BaseClient.cpp 4832 emule 此类错误中,实际上是是两个语法错误,由于太过简单,我与网友都怀疑是作者故意制造的错误,若是完全不懂C++的人,即使拿到源码,编也会报错,从而止步于此。而稍懂C++的人(本人即是此类菜鸟),则可以找出错误之处。 为方便诸多象我一样的初学者,我把修正之后,可以在 XP/WIN2003 +VS2003SP1 环境下直接编译成功的emule0.50a-Xtreme8.1-sources源码发布上来,以便互相学习交流。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值