在Delphi中应用Windows7任务栏新特性(2)

继续。

ITaskbarList2 接口

下面是 ITaskbarList2 的定义:

{ interface ITaskbarList2 }
	ITaskbarList2 = interface(ITaskbarList) 
		[SID_ITaskbarList2]
		function MarkFullscreenWindow(hwnd: HWND; fFullscreen: BOOL): HRESULT; stdcall;
	end;
	{$EXTERNALSYM ITaskbarList2}

此接口的系统需求为:Windows XP、Windows Server 2003 以上。没有特别说明,其中的函数的系统需求也是如此。

下面是函数的相关说明。
MarkFullscreenWindow
说明:
标记窗体为全屏。
参数:
hwnd:窗口句柄。
fFullscreen:全屏模式。若设置 fFullscreen 为 True ,系统认为该窗口为全屏窗口,当窗口激活时,任务栏将会移至底层。若设置 fFullscreen 为 False 将移除全屏标识,但并不会导致系统将此窗口认定为非全屏窗口。当 fFullscreen 为 False 时,系统将会自动判断窗口的模式,窗口有可能仍然会被认为是全屏窗口。

ITaskbarList3 接口

下面是 ITaskbarList3 及其相关类型和常量的定义:

{ interface ITaskbarList3 }
type
	THUMBBUTTON = record 
		dwMask: DWORD;
		iId: UINT;
		iBitmap: UINT;
		hIcon: HICON;
		szTip: packed array[0..259] of WCHAR;
		dwFlags: DWORD;
	end;
	{$EXTERNALSYM THUMBBUTTON}
	tagTHUMBBUTTON = THUMBBUTTON;
	{$EXTERNALSYM tagTHUMBBUTTON}
	TThumbButton = THUMBBUTTON;
	PThumbButton = ^TThumbButton;

// THUMBBUTTON flags
const
	THBF_ENABLED        =  $0000;
	{$EXTERNALSYM THBF_ENABLED}
	THBF_DISABLED       =  $0001;
	{$EXTERNALSYM THBF_DISABLED}
	THBF_DISMISSONCLICK =  $0002;
	{$EXTERNALSYM THBF_DISMISSONCLICK}
	THBF_NOBACKGROUND   =  $0004;
	{$EXTERNALSYM THBF_NOBACKGROUND}
	THBF_HIDDEN         =  $0008;
	{$EXTERNALSYM THBF_HIDDEN}
	THBF_NONINTERACTIVE = $10; 
	{$EXTERNALSYM THBF_NONINTERACTIVE}
// THUMBBUTTON mask
	THB_BITMAP          =  $0001;
	{$EXTERNALSYM THB_BITMAP}
	THB_ICON            =  $0002;
	{$EXTERNALSYM THB_ICON}
	THB_TOOLTIP         =  $0004;
	{$EXTERNALSYM THB_TOOLTIP}
	THB_FLAGS           =  $0008;
	{$EXTERNALSYM THB_FLAGS}
	THBN_CLICKED        =  $1800;
	{$EXTERNALSYM THBN_CLICKED}

const
	TBPF_NOPROGRESS    = 0; 
	{$EXTERNALSYM TBPF_NOPROGRESS}
	TBPF_INDETERMINATE = $1; 
	{$EXTERNALSYM TBPF_INDETERMINATE}
	TBPF_NORMAL        = $2; 
	{$EXTERNALSYM TBPF_NORMAL}
	TBPF_ERROR         = $4; 
	{$EXTERNALSYM TBPF_ERROR}
	TBPF_PAUSED        = $8; 
	{$EXTERNALSYM TBPF_PAUSED}

	TBATF_USEMDITHUMBNAIL   = $1; 
	{$EXTERNALSYM TBATF_USEMDITHUMBNAIL}
	TBATF_USEMDILIVEPREVIEW = $2; 
	{$EXTERNALSYM TBATF_USEMDILIVEPREVIEW}

type
	ITaskbarList3 = interface(ITaskbarList2) 
		[SID_ITaskbarList3]
		function SetProgressValue(hwnd: HWND; ullCompleted: ULONGLONG; ullTotal: ULONGLONG): HRESULT; stdcall;
		function SetProgressState(hwnd: HWND; tbpFlags: Integer): HRESULT; stdcall;
		function RegisterTab(hwndTab: HWND; hwndMDI: HWND): HRESULT; stdcall;
		function UnregisterTab(hwndTab: HWND): HRESULT; stdcall;
		function SetTabOrder(hwndTab: HWND; hwndInsertBefore: HWND): HRESULT; stdcall;
		function SetTabActive(hwndTab: HWND; hwndMDI: HWND; tbatFlags: Integer): HRESULT; stdcall;
		function ThumbBarAddButtons(hwnd: HWND; cButtons: UINT; pButton: PThumbButton): HRESULT; stdcall;
		function ThumbBarUpdateButtons(hwnd: HWND; cButtons: UINT; pButton: PThumbButton): HRESULT; stdcall;
		function ThumbBarSetImageList(hwnd: HWND; himl: HIMAGELIST): HRESULT; stdcall;
		function SetOverlayIcon(hwnd: HWND; hIcon: HICON; pszDescription: LPCWSTR): HRESULT; stdcall;
		function SetThumbnailTooltip(hwnd: HWND; pszTip: LPCWSTR): HRESULT; stdcall;
		function SetThumbnailClip(hwnd: HWND; var prcClip: TRect): HRESULT; stdcall;
	end;
	{$EXTERNALSYM ITaskbarList3}

此接口的系统需求为:Windows 7、Windows Server 2008 R2 以上。没有特别说明,其中的函数的系统需求也是如此。

这个接口非常重要,Windows7 的任务栏新特性几乎全部包括在这个接口中。下面说说 ITaskbarList3 接口的功能。
1、当 TDI(tabbed document interface 标签式文档界面) 应用程序或者 MDI(Multi-Document Interface 多文档界面)应用程序的窗口在任务栏上合并分组时:

  • 在任务栏上为标签页或文档显示独立的缩略图;
  • 从分组中移除独立标签页或文档的缩略图;
  • 更改缩略图在分组中的次序;
  • 显示缩略图时设置某一缩略图为选定项。

2、往任务栏图标上叠加小图标,比如状态标识。
3、显示操作的进度,比如复制或安装时。
4、向缩略图下方添加小工具栏。

备注:
当应用程序显示窗口的时候,系统会自动创建任务栏按钮。任务栏按钮放置完成后,任务栏会向窗口传递 TaskbarButtonCreated 消息。在窗口收到此消息后,应用程序才能调用 ITaskbarList3 接口。

楠窗听雨:这里的任务栏合并和上次提到的 ITaskbarList 中的任务栏按钮合并不同。简单点说就是:
上次是相同的程序运行两遍,任务栏自动合并,实际上是两个进程。若取消任务栏的自动合并设置,会发现其实有两个按钮。实际上,ITaskbarList 是对按钮进行操作,由于按钮合并了,所以看起来像是对标签进行操作。
而 ITaskbarList3 中是多标签页,是一个应用程序的多个窗口。比如火狐浏览器开启任务栏多标签显示之后,每个页面都有一个缩略图,但进程只有一个。

接下来,按照不同功能的实现,依次说说 ITaskbarList3 接口中的函数。

缩略图

RegisterTab
说明:
通知任务栏,新的标签页/文档缩略图已准备就绪。
参数:
hwndTab:标签页/文档窗口的句柄。
hwndMDI:应用程序主窗口句柄。此参数用来告诉任务栏将缩略图添加到哪个分组中。
备注:
RegisterTab 后并不会显示该缩略图,必须同时调用 SetTabOrder 才会显示。
UnregisterTab
说明:
当应用程序中的标签页/文档关闭时,从预览分组中移除缩略图。
参数:
hwndTab:要移除的缩略图所属的标签页/文档窗口的句柄。此参数与 RegisterTab 时的句柄相同。
备注:
UnregisterTab 必须在句柄被释放之前调用。
SetTabActive
说明:
通知任务栏,某一标签页/文档窗口已被激活。
参数:
hwndTab:激活标签页窗口的句柄。该句柄必须已使用 RegisterTab 注册。若无标签页被激活,此参数可为空。
hwndMDI 应用程序主窗口句柄。此参数告诉任务栏缩略图所属的分组。
dwReserved 保留,设为 0 。
SetTabOrder
说明:
插入新缩略图到分组,或移动已有缩略图到新的位置。
参数:
hwndTab:将要放置缩略图的标签页窗口的句柄。该句柄必须已使用 RegisterTab 注册。
hwndInsertBefore:标签页句柄,hwndTab 将会插入/移动到此标签页左边。该句柄必须已使用 RegisterTab 注册。若参数为 nil ,hwndTab 将会插入/移动到最后(最右)。
备注:
必须调用此函数才能显示缩略图。请在 RegisterTab 之后调用该函数。
SetThumbnailClip
说明:
指定窗口客户区的一部分作为缩略图。
hwnd:标签页/文档窗口句柄。
prcClip:TRect 类型, 指定一片客户区域,相对于客户区左上角。要还原默认缩略图显示,请设置此参数为 nil 。
SetThumbnailTooltip
说明:
指定或更新提示文本,鼠标停留在缩略图上将会显示该文本。
hwnd:标签页/文档窗口句柄。该句柄必须属于调用此函数的进程。
pszTip:PWideChar 型字符串,内容为提示的信息。参数可以为 nil ,此时窗口标题将作为提示信息。

叠加图标

SetOverlayIcon
说明:
向任务栏按钮上叠加小图标,用来表明状态或通知。
参数:
hwnd:窗口句柄,图标将叠加在此窗口对应的任务栏按钮上。该句柄必须属于与任务栏按钮相关的调用此函数的进程。若句柄无效,忽略对此函数的调用。
hIcon:图标句柄,该图标将叠加在原始图标上。该图标规格应为 16×16 pixels 96 dpi 。如果已经有图标叠加在任务栏按钮上,已有图标将会被替换。参数值可以为 nil ,空句柄的作用取决于任务栏按钮对应的是单个窗口还是一组窗口。若任务栏按钮对应单个窗口,则移除叠加的图标。若任务栏按钮对应一组窗口且之前叠加的图标仍然有效(在当前图标之前叠加,且没有被释放),则显示之前叠加的图标。
pszDescription:PWideChar 型字符串,内容为叠加图标传递信息的替代文本。
备注:
不需要时请及时释放 hIcon 。通常在调用 SetOverlayIcon 之后就释放图标,因为任务栏会创建并使用该图标的副本。
要显示叠加图标,任务栏必须设置为默认的大图标模式。如果任务栏属性设置为小图标,叠加图标将不会显示,且对此函数的调用将被忽略。
因为叠加图标应用于任务栏按钮,所以叠加图标针对的是分组而不是单独的缩略图。叠加图标的请求可以来自分组中独立的窗口,但并不进行排序。最后接收的图标将会被显示。若最后接收的图标被移除,取而代之的是依然有效的图标。例如,窗口 1、2、3 依次设置了叠加图标 A、B、C 。由于 C 最后接收,故 C 显示在任务栏按钮上。窗口 2 传递空句柄调用 SetOverlayIcon ,则图标 B 被移除(要注意不是 C)。窗体 3 执行同样的操作,移除图标 C 。由于窗体 1 的图标仍然处于激活状态,故图标 A 显示在任务栏按钮上。
若 Windows 资源管理器意外关闭,当资源管理器重启后,叠加图标不会被恢复。应用程序应该等待接收 TaskbarButtonCreated 消息(此消息意味着资源管理器已启动且任务栏按钮已经重建),之后再调用 SetOverlayIcon 重新设置叠加图标。

设置叠加图标的例子:

var
	FormHandle: THandle;
	MyIcon: TIcon;
begin
	if not Application.MainFormOnTaskBar then
		FormHandle := Application.Handle
	else
		FormHandle := Application.MainForm.Handle;
	MyIcon := TIcon.Create;
	try
		ImageList1.GetIcon(0, MyIcon);
		if Assigned(TaskbarList3) then
			TaskbarList3.SetOverlayIcon(FormHandle, MyIcon.Handle, PChar('Delphi2010'));
	finally
		MyIcon.Free;
	end;
end;

移除叠加图标的例子:

if Assigned(TaskbarList3) then
	TaskbarList3.SetOverlayIcon(FormHandle, 0, nil);

进度条

SetProgressState
说明:
设置任务栏进度条的类型和状态。
参数:
hwnd:需要显示进度条的窗口的句柄。与该窗体相关的任务栏按钮将会显示进度条。
tbpFlags:用来控制进度条状态的标记。下列状态互斥,故每次只能指定一个标记。

  • TBPF_NOPROGRESS (0x00000000)
    停止显示进度条,还原任务栏按钮的正常状态。当操作完成或取消时,可以使用此标记调用函数来撤除进度条。
  • TBPF_INDETERMINATE (0x00000001)
    进度条不按大小增长,取而代之的是循环掠过的光晕。这适用于操作在进行,但无法得知具体的进度的情况。
  • TBPF_NORMAL (0x00000002)
    进度条从左至右按大小增长。适用于能够确切得知进度的情况。
  • TBPF_ERROR (0x00000004)
    进度条转为红色,表明操作过程发生了错误。若进度条之前是不确定状态,红色的进度条并不意味着实际的进度。
  • TBPF_PAUSED (0x00000008)
    进度条转为黄色,表明进程操作过程暂停,等待用户继续。若进度条之前是不确定状态,黄色的进度条并不意味着实际的进度。

备注:
高对比色彩方案下,进度条不显示。
任务栏按钮只能同时显示一个窗口的进度。当任务栏按钮对应一个分组或包括多个窗口时,将按照以下优先级显示进度条(1 的优先级最高)。
1:TBPF_ERROR
2:TBPF_PAUSED
3:TBPF_NORMAL
4:TBPF_INDETERMINATE
优先级相同时,进度低的优先显示。
注意,调用 SetProgressValue 函数后,当前为 TBPF_INDETERMINATE 模式的进度条将会被切换为确定模式,TBPF_INDETERMINATE 标记将被清除。
SetProgressValue
说明:
按照指定的百分比显示或更新任务栏按钮的进度条。
参数:
hwnd:与显示进度条的任务栏按钮关联的窗体的句柄。
ullCompleted:已完成的进度数。
ullTotal:总进度数。
备注:
进度条使用完成后,必须使用 TBPF_NOPROGRESS 标记调用 SetProgressState 来撤除进度条。
除非进度条设置为锁定状态(TBPF_ERROR 或 TBPF_PAUSED),调用 SetProgressValue 时附带 TBPF_NORMAL 状态,TBPF_INDETERMINATE 将会被清除。

设置进度条的例子:

var
	FormHandle: THandle;
begin
	if not Application.MainFormOnTaskBar then
		FormHandle := Application.Handle
	else
		FormHandle := Application.MainForm.Handle;
	if Assigned(TaskbarList3) then
		TaskbarList3.SetProgressState(FormHandle, TBPF_NORMAL);
	Progress := Progress + 1;
	if Assigned(TaskbarList3) then
		TaskbarList3.SetProgressValue(FormHandle, Progress, 10);
end;

撤除进度条的例子:

var
	FormHandle: THandle;
begin
	if not Application.MainFormOnTaskBar then
		FormHandle := Application.Handle
	else
		FormHandle := Application.MainForm.Handle;
	if Assigned(TaskbarList3) then
		TaskbarList3.SetProgressState(FormHandle, TBPF_NOPROGRESS);
	Progress := 0;
end;

其他的下次再说。

在Delphi中应用Windows7任务栏新特性(2)》有4个想法

评论已关闭。