Kotlinthis->FlashWindowEx(FLASHW_TRAY | FLASHW_TIMERNOFG, 0, 0); // 仅任务栏,闪烁直到窗口激活,默认频率
CWnd::FlashWindowEx第一个参数是闪动方式:
OtherCComQIPtr<itaskbarlist3> m_tbl; // 任务栏:ITaskBarList3实例指针
LRESULT OnTaskbarButtonCreated(WPARAM wParam, LPARAM lParam); // 任务栏:"TaskbarButtonCreated"消息</itaskbarlist3>
然后修改对话框的CPP文件:Otherconst UINT WM_TASKBAR_BUTTON_CREATED = RegisterWindowMessage("TaskbarButtonCreated"); // 任务栏:注册消息
BEGIN_MESSAGE_MAP(CTaskBarTestDlg, CDialog)
// ... 其它消息映射 ...
ON_REGISTERED_MESSAGE(WM_TASKBAR_BUTTON_CREATED, OnTaskbarButtonCreated) // 任务栏:映射消息
END_MESSAGE_MAP()
为消息映射添加代码:OtherLRESULT CTaskBarTestDlg::OnTaskbarButtonCreated(WPARAM wParam, LPARAM lParam) // 任务栏图标创建时:ITaskBarList3实例化COM对象
{
// RegisterWindowsMessage("TaskbarButtonCreated") 注册的消息,ON_REGISTERED_MESSAGE(msg, fn) 登记
// 在任务栏按钮创建完毕时,"TaskbarButtonCreated"会被触发,
// 这个时候就可以实例化ITaskbarList3对象了
m_tbl.Release(); // 如果有的话,释放以前的
m_tbl.CoCreateInstance(CLSID_TaskbarList); // 任务栏:构造ITaskbarList3类型COM对象
return TRUE;
}
最后添加WM_DESTROY消息映射,释放ITaskbarList3实例(因为MFC在对话框析构之前调用了CoUninitialize(),不及时释放会崩溃):C++void CTaskBarTestDlg::OnDestroy() // 窗口销毁时:ITaskBarList3析构COM对象
{
CDialog::OnDestroy();
m_tbl.Release(); // 任务栏:析构COM对象(必须在调用CoUnintialize()之前,不能等待CComQIPtr析构函数,否则会崩溃)
}
这样,我们就可以使用m_tbl的成员函数SetProgressValue和SetProgressState来在任务栏显示进度了:Othervoid CTaskBarTestDlg::OnBnClickedSetProgress()
{
UpdateData(true);
if (m_tbl != NULL) {
m_tbl->SetProgressValue(m_hWnd, m_slider, 100); // 设置任务栏进度
}
}
void CTaskBarTestDlg::OnBnClickedButton1()
{
if (m_tbl != NULL) {
m_tbl->SetProgressState(m_hWnd, TBPF_NORMAL); // 设置任务栏进度状态:正常 - 绿色
}
}
void CTaskBarTestDlg::OnBnClickedButton2()
{
if (m_tbl != NULL) {
m_tbl->SetProgressState(m_hWnd, TBPF_ERROR); // 设置任务栏进度状态:错误 - 红色
}
}
void CTaskBarTestDlg::OnBnClickedButton3()
{
if (m_tbl != NULL) {
m_tbl->SetProgressState(m_hWnd, TBPF_PAUSED); // 设置任务栏进度状态:暂停 - 黄色
}
}
void CTaskBarTestDlg::OnBnClickedButton4()
{
if (m_tbl != NULL) {
m_tbl->SetProgressState(m_hWnd, TBPF_INDETERMINATE); // 设置任务栏进度状态:不确定 - 绿色滚动
}
}
void CTaskBarTestDlg::OnBnClickedButton5()
{
if (m_tbl != NULL) {
m_tbl->SetProgressState(m_hWnd, TBPF_NOPROGRESS); // 设置任务栏进度状态:清除进度
}
}
效果:
C++// 自定义图标消息
#define WM_ICON_MESSAGE (WM_USER + 100)
void CTaskBarTestDlg::OnBnClickedShowTray()
{
NOTIFYICONDATA tnd;
tnd.cbSize = sizeof(NOTIFYICONDATA); // 自身大小
// 窗口句柄
tnd.hWnd = this->m_hWnd;
// 通知图标ID
tnd.uID = IDR_MAINFRAME;
// 标志位:消息 + 图标 + 工具提示
tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
// 消息
tnd.uCallbackMessage = WM_ICON_MESSAGE;
// 图标
tnd.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
// 提示
strcpy(tnd.szTip,"测试程序");
Shell_NotifyIcon(NIM_ADD, &tnd); // 添加图标
m_is_icon_show = true;
}
删除图标的代码:Othervoid CTaskBarTestDlg::OnBnClickedHideTray()
{
NOTIFYICONDATA tnid;
tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = this->m_hWnd;
tnid.uID = IDR_MAINFRAME;
tnid.uFlags = NULL;
Shell_NotifyIcon(NIM_DELETE, &tnid); // 删除图标
m_is_icon_show = false;
}
explorer崩溃重建图标:Otherconst UINT WM_TASKBAR_CREATED = RegisterWindowMessage("TaskbarCreated"); // 通知图标:注册消息
BEGIN_MESSAGE_MAP(CTaskBarTestDlg, CDialog)
// ... 其它消息映射 ...
ON_REGISTERED_MESSAGE(WM_TASKBAR_CREATED, OnTaskbarCreated) // 通知图标:映射消息
END_MESSAGE_MAP()
// ... 其它代码 ...
LRESULT CTaskBarTestDlg::OnTaskbarCreated(WPARAM wParam, LPARAM lParam) // 当explorer崩溃时重建图标
{
// RegisterWindowsMessage("TaskbarCreated") 注册的消息,ON_REGISTERED_MESSAGE(msg, fn) 登记
if (m_is_icon_show)
OnBnClickedShowTray();
return TRUE;
}
图标点击消息:OtherBEGIN_MESSAGE_MAP(CTaskBarTestDlg, CDialog)
// ... 其它消息映射 ...
ON_MESSAGE(WM_ICON_MESSAGE, OnIconMessage) // 通知图标:映射消息
END_MESSAGE_MAP()
// ... 其它代码 ...
LRESULT CTaskBarTestDlg::OnIconMessage(WPARAM wParam, LPARAM lParam) // 自定义的通知图标消息WM_ICON_MESSAGE
{
// #define WM_ICON_MESSAGE (WM_USER + 100) 定义的消息,ON_MESSAGE(msg, fn) 登记
UINT uID = (UINT) wParam;
UINT uMouseMsg = (UINT) lParam;
if (uID = IDR_MAINFRAME) {
switch (uMouseMsg) {
case WM_LBUTTONDBLCLK: // 双击时:显示窗口并隐藏图标
this->SetForegroundWindow();
this->ShowWindow(SW_SHOW);
OnBnClickedHideTray();
return TRUE;
case WM_RBUTTONDOWN: // 右击时:显示弹出菜单
CMenu menu, *pMenu;
menu.LoadMenu(IDR_MENU1); // 加载菜单
pMenu = menu.GetSubMenu(0); // 获取子菜单
POINT ptPos;
GetCursorPos(&ptPos); // 获取鼠标指针
pMenu->SetDefaultItem(ID_POP_SHOW_MAIN); // 设置默认项
this->SetForegroundWindow(); //这一行代码很重要,否则右键菜单工作不正常。详见msdn说明: http://support.microsoft.com/kb/135788
pMenu->TrackPopupMenu(
TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
ptPos.x, ptPos.y,
this); // 弹出菜单
return TRUE;
}
}
return FALSE;
}
效果:
[修改于 10年0个月前 - 2015/05/28 18:25:14]