1、在资源中的Icon中导入一个自己喜欢的图标,ID命名为IDR_MAINFRAME,将先前的IDR_MAINFRAME的图标删除掉;
2、在自己的Dialog头文件中定义一个变量 NOTIFYICONDATA m_nid,关于该结构体的具体信息可以查阅MSDN;
3、添加消息响应函数OnInitDialog(),并在该函数中添加以下代码,这样程序一启动,就在托盘中显示出了自己应用程序的图标。
//---------------------------托盘显示---------------------------------//
m_nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
m_nid.hWnd = this->m_hWnd;
m_nid.uID = IDR_MAINFRAME;
m_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;
m_nid.uCallbackMessage = WM_SHOWTASK; // 自定义的消息名称
m_nid.hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
strcpy(m_nid.szTip, "服务器程序"); // 信息提示条为"服务器程序",VS2008 UNICODE编码用wcscpy_s()函数
Shell_NotifyIcon(NIM_ADD, &m_nid); // 在托盘区添加图标
这时候编译,会报WM_SHOWTASK的错,因为该消息要自己定义。
4、在Dialog头文件中声明消息函数原型
LRESULT OnShowTask(WPARAM wParam, LPARAM lParam);
5、在Dialog源文件中进行消息映射
ON_MESSAGE(WM_SHOWTASK,OnShowTask)
6、在Dialog源文件中添加自定义的消息响应代码,左键双击弹出应用程序主窗口,右键单击弹出菜单。
LRESULT CServerDlg::OnShowTask(WPARAM wParam, LPARAM lParam)
{
if(wParam != IDR_MAINFRAME)
return 1;
switch(lParam)
{
case WM_RBUTTONUP: // 右键起来时弹出菜单
{
LPPOINT lpoint = new tagPOINT;
::GetCursorPos(lpoint); // 得到鼠标位置
CMenu menu;
menu.CreatePopupMenu(); // 声明一个弹出式菜单
menu.AppendMenu(MF_STRING, WM_DESTROY, "关闭");
menu.TrackPopupMenu(TPM_LEFTALIGN, lpoint->x ,lpoint->y, this);
HMENU hmenu = menu.Detach();
menu.DestroyMenu();
delete lpoint;
}
break;
case WM_LBUTTONDBLCLK: // 双击左键的处理
{
this->ShowWindow(SW_SHOWNORMAL); // 显示主窗口
}
break;
}
return 0;
}
7、添加OnSize消息响应函数,处理最小化时的操作。
void CServerDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if(nType == SIZE_MINIMIZED)
{
ShowWindow(SW_HIDE); // 当最小化市,隐藏主窗口
}
}
8、添加关闭窗口时的消息响应函数,将托盘中的应用程序图标删除
BOOL CServerDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
// 在托盘区删除图标
Shell_NotifyIcon(NIM_DELETE, &m_nid);
return CDialog::DestroyWindow();
}
经过以上的步骤,就编写出了一个简单的可以最小化到托盘的程序。该程序在一启动时,在托盘创立应用程序的图标,最小化程序时隐藏主窗口,双击托盘区的图标时,显示主窗口,右键点击托盘区窗口时,弹出菜单进行相应的操作。
*****************************************************************************************************************************************************************************
以工程为例说明过程:此程序编程环境是VS2008,在调试过程中,将字符集修改为“使用多字节字符集”(项目->属性->配置属性->字符集)。
例如新建一个MFC对话框工程Dialogtest,程序实现的功能是,修改对话框标题栏上默认的图标,在程序中改为添加的资源Icon IDI_ICON1,最小化对话框到托盘。
首先,在对话框资源属性页,选择Minimize Box为TRUE。这样可以实现对话框的最小化,但是这时最小化到了任务栏,为了使其最小化到托盘,还必须添加一些代码,步骤如下:
首先添加变量NOTIFYICONDATA m_nid;//NOTIFYICONDATA作用是用来向任务栏托盘区域发送消息和自定义消息响应函数OnShowTask ,自定义消息响应函数主要是添加三处代码:
1)头文件中声明部分添加#define WM_SHOWTASK WM_USER+1,代码部分添加afx_msg LRESULT OnShowTask(WPARAMwParam,LPARAM lParam);
2)在源程序中添加:BEGIN_MESSAGE_MAP(CDialogtestDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_SHOWTASK,OnShowTask)//此处为添加部分
END_MESSAGE_MAP()
3)源程序中的响应函数代码
在本实现中源程序中总共添加了五处代码:(红色为添加的代码)
1、修改图标资源:
CDialogtestDlg::CDialogtestDlg(CWnd*pParent /*=NULL*/)
:CDialog(CDialogtestDlg::IDD, pParent)
{
//m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);// IDR_MAINFRAME为系统默认
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
}
2、同上自定义消息2
BEGIN_MESSAGE_MAP(CDialogtestDlg,CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_SHOWTASK,OnShowTask)
ON_WM_SIZE()//为了隐藏最小化到任务栏的图标而添加的消息响应函数,这个函数系统自带直接添加
END_MESSAGE_MAP()
3、修改对话框标题栏图标并在托盘区添加图标:
BOOL CDialogtestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX& 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX< 0xF000);
CMenu* pSysMenu= GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX,strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon,TRUE); // 设置大图标
SetIcon(m_hIcon,FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
m_nid.hWnd = this->m_hWnd;
m_nid.uID = IDI_ICON1;
m_nid.uFlags = NIF_ICON|NIF_MESSAGE |NIF_TIP;
m_nid.uCallbackMessage = WM_SHOWTASK;
m_nid.hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
strcpy_s(m_nid.szTip,strlen("对话框")+1,"对话框");
Shell_NotifyIcon(NIM_ADD,&m_nid); // 在托盘区添加图标
return TRUE; // 除非将焦点设置到控件,否则返回TRUE
}
4、自定义的消息响应函数代码:
LRESULT CDialogtestDlg::OnShowTask(WPARAMwParam, LPARAM lParam)
{
if(wParam != IDI_ICON1) return 1;
switch(lParam)
{
case WM_RBUTTONUP: //右键起来时弹出菜单
{
LPPOINT lpoint = new tagPOINT;
::GetCursorPos(lpoint); // 得到鼠标位置
CMenu menu;
menu.CreatePopupMenu(); // 声明一个弹出式菜单
menu.AppendMenu(MF_STRING, WM_DESTROY, "退出");//Appends a new item to the end ofthis menu
//Displays a floating pop-up menu at the specifiedlocation and tracks the selection of items on the pop-up menu
menu.TrackPopupMenu(TPM_LEFTALIGN, lpoint->x ,lpoint->y,this);
HMENU hmenu = menu.Detach();
menu.DestroyMenu();
delete lpoint;
break;
}
case WM_LBUTTONDBLCLK: // 双击左键的处理
this->ShowWindow(SW_SHOWNORMAL); // 显示主窗口
break;
}
return 0;
}
5、处理最小化时任务栏出现图标的程序:
void CDialogtestDlg::OnSize(UINTnType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
if (nType == SIZE_MINIMIZED)
{
ShowWindow(SW_HIDE);//隐藏最小化到任务栏的图标
}
}