建立一个任务栏通知程序1.首先建立一个基于对话框的应用程序,名称为Tray。
2.在对话框的OnInitDialog()函数中,加入如下代码,使对话框程序运行时出现在任务栏的通知区域:
//移动对话框到不可见区域
AfxGetMainWnd()->MoveWindow(-500,-500,100,100,true);
//设置对话框属性,使其不在任务栏上显示
SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE,
WS_EX_TOOLWINDOW|WS_EX_STATICEDGE);
(对于SDI应用程序,应该在CMainFrame::PreCreateWindow()中使用下面代码使其主窗口不可见且不在任务栏出现
cs.style = WS_POPUP;
cs.dwExStyle = WS_EX_TOOLWINDOW;)
//加到任务栏
NOTIFYICONDATA tnd;
tnd.cbSize=sizeof(NOTIFYICONDATA);
tnd.hWnd=AfxGetMainWnd()->m_hWnd;
tnd.uID=IDR_MAINFRAME;
tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
tnd.uCallbackMessage=WM_PROC;
tnd.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
strcpy(tnd.szTip,"我的任务栏程序");
Shell_NotifyIcon(NIM_ADD,&tnd);
3.添加自定义消息处理函数
在TrayDlg.h文件开头加入
#define WM_PROC WM_USER+100
在中间相应的地方加入:
afx_msg void OnProc(WPARAM wParam,LPARAM lParam);
在TrayDlg.cpp中加入:
ON_MESSAGE(WM_PROC,OnProc)
以及下面代码来响应鼠标的点击处理
void CTrayDlg::OnProc(WPARAM wParam,LPARAM lParam)
{
UINT uMouseMsg;//鼠标动作
uMouseMsg=(UINT) lParam;
if(uMouseMsg==WM_LBUTTONDOWN)
{
ATOM GlobalAtom;
if(!GlobalFindAtom("Aboutc"))
{
GlobalAtom=GlobalAddAtom("Aboutc");
CAboutDlg dlg; //弹出About对话框
dlg.DoModal();
GlobalDeleteAtom(GlobalAtom);
}
}
if(uMouseMsg==WM_RBUTTONDOWN)
{
AfxGetMainWnd()->SetForegroundWindow(); //弹出Popup菜单
CMenu menu;
menu.LoadMenu(IDR_TRAYMENU);
CMenu* pPopup=menu.GetSubMenu(0);
CPoint Point;
GetCursorPos(&Point);
pPopup->TrackPopupMenu(TPM_LEFTALIGN,Point.x,Point.y,AfxGetMainWnd(),NULL );
AfxGetMainWnd()->PostMessage(WM_NULL, 0, 0);
}
}
并添加一个只有两项(关于|关闭)的子菜单,用于右键点击图标时的弹出菜单
4.添加菜单处理程序
void CTrayDlg::OnAboutc()
{
//利用原子来禁止程序运行多个实例
ATOM GlobalAtom;
if(!GlobalFindAtom("Aboutc"))
{
GlobalAtom=GlobalAddAtom("Aboutc");
//弹出About对话框
CAboutDlg dlg;
dlg.DoModal();
GlobalDeleteAtom(GlobalAtom);
}
}
void CTrayDlg::OnClosec()
{
NOTIFYICONDATA tnid;
tnid.cbSize=sizeof(NOTIFYICONDATA);
tnid.hWnd=AfxGetMainWnd()->m_hWnd;
tnid.uID=IDR_MAINFRAME;
Shell_NotifyIcon(NIM_DELETE,&tnid);
CDialog::OnClose();
this->PostMessage(WM_CLOSE,0,0);
}