ITaskbarList3是一种COM组件。使用COM组件前,需要先调用CoInitializeEx函数初始化COM。程序退出前也要执行CoUninitialize函数释放相关资源。
在GUI线程中必须使用COINIT_APARTMENTTHREADED选项,不能使用COINIT_MULTITHREADED选项,否则某些窗口控件可能无法正常工作。
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
CoUninitialize();
初始化COM完成后,就可以创建ITaskbarList3对象了。XP系统下返回的taskbar指针为NULL。
ITaskbarList3 *taskbar;
CoCreateInstance(&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskbarList3, &taskbar);
if (taskbar != NULL)
ITaskbarList3_HrInit(taskbar);
程序退出前要记得释放ITaskbarList3对象。
if (taskbar != NULL)
{
ITaskbarList3_Release(taskbar);
taskbar = NULL;
}
[Win7任务栏图标进度条操作方法]
进度条显示绿色(表示正常):ITaskbarList3_SetProgressState(taskbar, 表示窗口的HWND变量, TBPF_NORMAL);
设置当前进度:ITaskbarList3_SetProgressValue(taskbar, 表示窗口的HWND变量, 当前值, 最大值);
关闭进度条显示:ITaskbarList3_SetProgressState(taskbar, 表示窗口的HWND变量, TBPF_NOPROGRESS);
进度条显示红色(表示错误):ITaskbarList3_SetProgressState(taskbar, 表示窗口的HWND变量, TBPF_ERROR);
进度条显示黄色(表示暂停):ITaskbarList3_SetProgressState(taskbar, 表示窗口的HWND变量, TBPF_PAUSED);
进度条循环滚动:ITaskbarList3_SetProgressState(taskbar, 表示窗口的HWND变量, TBPF_INDETERMINATE);
[普通窗口进度条操作方法]
获取表示进度条控件的HWND变量:HWND progress_wnd = GetDlgItem(hDlg, 控件ID);
设置当前进度:SendMessage(表示进度条控件的HWND变量, PBM_SETPOS, 进度值, 0);
进度值的默认最小值为0,最大值为100。
第四个参数必须为0。函数返回之前的进度。
设置最小值和最大值(16位整数):SendMessage(表示进度条控件的HWND变量, PBM_SETRANGE, 0, MAKELPARAM(最小值, 最大值));
设置最小值和最大值(32位整数):SendMessage(表示进度条控件的HWND变量, PBM_SETRANGE32, 最小值, 最大值);
进入循环滚动模式:
LONG_PTR style = GetWindowLongPtr(表示进度条控件的HWND变量, GWL_STYLE);
if ((style & PBS_MARQUEE) == 0)
{
SetWindowLongPtr(表示进度条控件的HWND变量, GWL_STYLE, style | PBS_MARQUEE);
SendMessage(表示进度条控件的HWND变量, PBM_SETMARQUEE, TRUE, 0);
}
退出循环滚动模式:
LONG_PTR style = GetWindowLongPtr(表示进度条控件的HWND变量, GWL_STYLE);
if (style & PBS_MARQUEE)
{
SendMessage(表示进度条控件的HWND变量, PBM_SETMARQUEE, FALSE, 0);
SetWindowLongPtr(表示进度条控件的HWND变量, GWL_STYLE, style & ~PBS_MARQUEE);
}
[任务栏图标橙黄色闪烁]
XP系统也可以使用。必须在后台使用(也就是说目标窗口不是当前窗口)。
闪烁次数结束后任务栏图标一直是橙色,直到用户切换到目标窗口才恢复。
FLASHWINFO flash;
flash.cbSize = sizeof(FLASHWINFO);
flash.dwFlags = FLASHW_TIMERNOFG | FLASHW_TRAY; // 一直闪烁到用户切换回窗口
flash.dwTimeout = 0;
flash.hwnd = 表示窗口的HWND变量;
flash.uCount = 3; // 闪烁次数
FlashWindowEx(&flash);
【程序代码】
main.c:
#define COBJMACROS
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <CommCtrl.h>
#include <ShlObj.h>
#include "resource.h"
// 必须启用XP风格
// 否则窗口显示后需要等待几秒钟动画才开始播放
#pragma comment(lib, "comctl32.lib")
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#define TIMER_ID 1
HINSTANCE main_instance;
HWND animate_wnd;
ITaskbarList3 *taskbar; // Win7任务栏进度条
void CALLBACK timer_proc(HWND hDlg, UINT uMsg, UINT iTimerID, DWORD dwTime)
{
const int money[] = {1500, 1000, 500, 200, 0};
const int progress[] = {25, 50, 75, 90, 100};
static int step = 0;
static BOOL paused = FALSE;
char str[20];
if (paused)
return;
_snprintf_s(str, sizeof(str), sizeof(str) - 1, "剩余%d块", money[step]);
SetDlgItemTextA(hDlg, IDC_STATIC3, str);
SendDlgItemMessage(hDlg, IDC_PROGRESS1, PBM_SETPOS, progress[step], 0);
if (taskbar != NULL)
ITaskbarList3_SetProgressValue(taskbar, hDlg, progress[step], 100);
if (step == 3)
{
paused = TRUE;
if (MessageBoxA(hDlg, "确定要上缴所有钱钱,不留零花钱吗?", "工资上缴", MB_ICONQUESTION | MB_YESNO) == IDYES)
{
step = 4;
paused = FALSE;
}
else
EndDialog(hDlg, 0);
}
else if (step == 4)
{
SetDlgItemTextA(hDlg, IDC_STATIC2, "上缴完毕! 你是世上最诚实的男人!");
SetDlgItemTextA(hDlg, IDCANCEL, "完成");
KillTimer(hDlg, TIMER_ID);
}
else
step++;
}
INT_PTR CALLBACK dlg_proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int id;
HICON icon;
switch (uMsg)
{
case WM_COMMAND:
/* 响应窗口命令 */
id = LOWORD(wParam);
switch (id)
{
case IDOK:
case IDCANCEL:
KillTimer(hDlg, TIMER_ID);
EndDialog(hDlg, 0);
break;
}
break;
case WM_INITDIALOG:
/* 初始化窗口 */
// 设置窗口图标
icon = (HICON)LoadImage(main_instance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)icon);
icon = (HICON)LoadImage(main_instance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)icon);
// 初始化进度条
SendDlgItemMessage(hDlg, IDC_PROGRESS1, PBM_SETPOS, 4, 0);
if (taskbar != NULL)
{
ITaskbarList3_SetProgressState(taskbar, hDlg, TBPF_NORMAL);
ITaskbarList3_SetProgressValue(taskbar, hDlg, 4, 100);
}
// 初始化动画
animate_wnd = GetDlgItem(hDlg, IDC_ANIMATE1);
Animate_Open(animate_wnd, MAKEINTRESOURCE(IDR_AVI1));
SetTimer(hDlg, TIMER_ID, 1000, timer_proc);
break;
}
return 0;
}
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
CoCreateInstance(&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskbarList3, &taskbar);
if (taskbar != NULL)
ITaskbarList3_HrInit(taskbar);
main_instance = hInstance;
InitCommonControls();
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, dlg_proc);
if (taskbar != NULL)
{
ITaskbarList3_Release(taskbar);
taskbar = NULL;
}
CoUninitialize();
return 0;
}
【Win7系统下的运行效果】
【XP系统下的运行效果】
【开发环境】