MFC程序最小化到系统托盘

原创 2011年11月17日 10:20:12

          为了使MFC程序(SDI,MDI,DLG)均能最小化到系统托盘,这里运用消息机制来实现系统托盘效果。

          那么什么是托盘呢?所谓的“托盘”,在Windows系统界面中,指的就是下面任务条右侧,有系统时间等等的标志的那一部分。在程序最小化或挂起时,但有不希望占据任务栏的时候,就可以把程序放到托盘区。

          怎么实现呢?这里需要运用到的Windows API函数:

BOOL Shell_NotifyIcon(
    DWORD dwMessage, 
    PNOTIFYICONDATA lpdata
);
          函数了里面的参数对于实现不同的效果尤其重要,包括托盘图标、托盘菜单等等。那么我们来了解一下两个参数吧:

dwMessage可以取以下值:

NIM_ADD 向托盘中加入一个图标
NIM_MODIFY 修改托盘中的图标
NIM_DELETE 从托盘中删除一个图标

参数pnid是NOTIFYICONDATA结构的一个引用。该结构的原型如下:

typedef struct _NOTIFYICONDATA { 
    DWORD cbSize; // 结构的大小,必须在程序中给出
    HWND hWnd;    // 程序中将要接收托盘消息的窗口句柄
    UINT uID;     // 应用程序中定义的托盘图标ID,此参数用作标识
    UINT uFlags;  //设置属性 标记下边3个参数是否有效
    UINT uCallbackMessage;// 自定义的消息ID值
    HICON hIcon;//显示在系统托盘上的Icon的句柄
    #if (_WIN32_IE < 0x0500)
        TCHAR szTip[64;// 用于图标显示的提示字符串
    #else
        TCHAR szTip[128];
    #endif
    #if (_WIN32_IE >= 0x0500)
        DWORD dwState; 
        DWORD dwStateMask; 
        TCHAR szInfo[256]; 
        union {
            UINT  uTimeout; 
            UINT  uVersion; 
        } DUMMYUNIONNAME;
        TCHAR szInfoTitle[64]; 
        DWORD dwInfoFlags; 
    #endif
    #if (_WIN32_IE >= 0x600)
        GUID guidItem;
    #endif
} NOTIFYICONDATA, *PNOTIFYICONDATA; 
           具体步骤如下:

1.在程序中增加一个私有的NOTIFYICONDAT对象

private:
        NOTIFYICONDATA m_tnid;
2.在初始化窗口时对NOTIFYICONDAT对象初始化 用Shell_NotifyIcon函数进行注册
	m_notify.cbSize=sizeof NOTIFYICONDATA;
	m_notify.hWnd=this->m_hWnd;	
	m_notify.uID=IDR_MAINFRAME;
	m_notify.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
	strcpy(m_notify.szTip,"Michael_Chen is a good man");
	m_notify.uCallbackMessage=WM_USER_NOTIFYICON;
	m_notify.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; //OK,下面就是托盘产生了. 
	Shell_NotifyIcon(NIM_ADD,&m_notify);
3.增加自定义的消息处理函数或者重载WindowProc函数,在消息处理函数或WindowProc函数中对自定义的消息进行处理

1)运用自定义消息

i,WM_USER_NOTIFYICON是自定义的消息 在头文件中进行声明;

#define WM_USER_NOTIFYICON WM_USER+1
ii,在.h文件中声明消息函数原型
 	afx_msg LRESULT OnNotifyMsg(WPARAM wparam,LPARAM lparam);
iii,在.cpp文件中进行消息映射
BEGIN_MESSAGE_MAP(CNotifyiconDlg, CDialog)
	//{{AFX_MSG_MAP(CNotifyiconDlg)
                 ...
	ON_MESSAGE(WM_USER_NOTIFYICON,OnNotifyMsg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
iiii,在.cpp文件中添加自定义的消息响应代码,左键双击弹出应用程序主窗口,右键单击弹出菜单。
LRESULT  CNotifyiconDlg::OnNotifyMsg(WPARAM wparam,LPARAM lparam)
//wParam接收的是图标的ID,而lParam接收的是鼠标的行为   
{
	if(wparam!=IDR_MAINFRAME)   
		return    1;   
    switch(lparam)   
    {   
    case  WM_RBUTTONUP://右键起来时弹出快捷菜单,这里只有一个“关闭”   
		{     
			LPPOINT    lpoint=new    tagPOINT;   
			::GetCursorPos(lpoint);//得到鼠标位置   
			CMenu    menu;   
			menu.CreatePopupMenu();//声明一个弹出式菜单   
			//增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗口(已   
			//隐藏),将程序结束。   
			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_SHOW);//简单的显示主窗口完事儿   
		}   
		break;   
    }    
	return 0;
}

2)重载WindowProc函数

i,重载WindowProc函数(方法略)

ii,在WindowProc中增加的消息相应代码

//WindowProc中增加的代码
LRESULT CNotifyiconDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	switch(message) //判断消息类型
	{ 
	case WM_USER_NOTIFYICON: 
		//如果是用户定义的消息 
		if(lParam==WM_LBUTTONDBLCLK)
			
		{ 
			//鼠标双击时主窗口出现 
			if(AfxGetApp()->m_pMainWnd->IsWindowVisible()) //判断窗口当前状态
			{
				AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE); //隐藏窗口
			}
			else
			{
				AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOW); //显示窗口
			}
			
		} 
		else if(lParam==WM_RBUTTONDOWN)
		{ //鼠标右键单击弹出选单 
			CMenu menu; 
			menu.LoadMenu(IDR_MENU1); //载入事先定义的选单 
			CMenu *pMenu=menu.GetSubMenu(0); 
			CPoint pos; 
			GetCursorPos(&pos); 
			pMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,pos.x,pos.y,AfxGetMainWnd()); 
		} 
		break; 
	case WM_SYSCOMMAND: 
		//如果是系统消息 
		if(wParam==SC_MINIMIZE)
		{ 
			//接收到最小化消息时主窗口隐藏 
			AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE); 
			return 0; 
		} 
		if(wParam==SC_CLOSE)
		{
			::Shell_NotifyIcon(NIM_DELETE,&m_notify); //关闭时删除系统托盘图标
		}
		break;
	}
	return CDialog::WindowProc(message, wParam, lParam);
}


        经过以上的步骤,就编写出了一个简单的可以最小化到托盘的程序。该程序在一启动时,在托盘创立应用程序的图标,最小化程序时隐藏主窗口,双击托盘区的图标时,显示主窗口,右键点击托盘区窗口时,弹出菜单。






版权声明:本文为博主原创文章,未经博主允许不得转载。

MFC系统托盘的实现

通常电脑里边的软件,当你打开后会在电脑最右下角的任务栏上生成一个系统托盘,当你点击最小化或者点击关闭按钮后,若想恢复窗口,可以左键双击或者单机这个系统图标,同时鼠标右键点击,又会有其他的菜单弹出,比如...
  • u013051748
  • u013051748
  • 2015年05月10日 16:34
  • 1501

MFC 程序最小化到系统托盘区的一个简单实例

准备工作:      在开始之前,我们需要弄清出一下东东,当然,你也可以知其然而不知其所以然,会用就好。          1. MFC 自定义消息的过程(详见后文)          2. BOOL...
  • JarvisChu
  • JarvisChu
  • 2010年08月01日 19:19
  • 6317

MFC托盘显示

#define WM_NOTIFYICON WM_USER + 5 #define IDI_ICON 0x0005  fx_msg LRESULT OnNotifyIcon(WPARAM wP...
  • zhoxier
  • zhoxier
  • 2013年01月18日 08:46
  • 739

MFC之托盘

在VC++中,想实现最小化MFC程序的时候,最小化到系统托盘,需要调用NOTIFYICONDATA类 下面我们就来讲解一下如何简单实现一个系统托盘我们以对话框程序为列 第一步:在Dlg类中//定义...
  • lyshiba
  • lyshiba
  • 2012年04月20日 17:35
  • 8235

MFC托盘程序

  • 2014年05月08日 12:19
  • 29.82MB
  • 下载

MFC将程序添加到系统图标栏,系统托盘栏

在对话框的初始化OnInitDialog()中: NOTIFYICONDATA tnid;    tnid.cbSize = sizeof(NOTIFYICONDATA);  tnid.h...
  • zengweicdut
  • zengweicdut
  • 2013年05月29日 08:54
  • 833

MFC程序启动时最小化到托盘

BOOL CMyClockDlg::OnInitDialog() { // ...... 省略前面代码 // 启动时最小化到托盘 PostMessage(WM_SYSCOMMAND, SC_M...
  • u_1_n_2_i_3
  • u_1_n_2_i_3
  • 2015年12月27日 22:16
  • 1624

MFC 关闭窗口最小化到托盘,并产生气泡消息提醒

关闭窗口最小化到托盘关于怎么实现托盘程序以及托盘菜单可以参考MFC下托盘图标的实现和托盘菜单 实现关闭窗口达到最小化的效果,网上说有用onsystem方法,其实用重载oncancel方法就可以实现...
  • leizicoder
  • leizicoder
  • 2015年09月01日 15:51
  • 1236

MFC对话框最小化到托盘

1、在资源中的Icon中导入一个自己喜欢的图标,ID命名为IDR_MAINFRAME,将先前的IDR_MAINFRAME的图标删除掉;2、在自己的Dialog头文件中定义一个变量  NOTIFYICO...
  • zhangjs0322
  • zhangjs0322
  • 2011年01月22日 22:07
  • 14011

VC+MFC 托盘图标闪烁与消息提示

  • 2013年01月17日 16:25
  • 3.54MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MFC程序最小化到系统托盘
举报原因:
原因补充:

(最多只允许输入30个字)