Chinaunix首页 | 论坛 | 博客
  • 博客访问: 588610
  • 博文数量: 752
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:47
文章分类

全部博文(752)

文章存档

2011年(1)

2008年(751)

我的朋友

分类:

2008-10-13 16:41:03

给托盘添加右击菜单--变化的背景图

图1 变化的背景图

给托盘添加右击菜单

  一般的商业程序都有托盘图标和在托盘上弹出右击菜单的功能,那么如何给自已的程序添加这样的功能呢?本文通过改变背景图的实例,介绍一种实现托盘上弹出右击菜单的方法。 

一、添加托盘图标

给程序添加托盘图标的方法在很多VC书中都有实例,通常在程序中按下面的步骤就可以实现:

1、在XXDlg.CPP文件头部加入

#define WM_NOTIFYICONWM_USER+5   
NOTIFYICONDATA nd;

2、在程序的初始化中加入下面代码

nd.cbSize= sizeof (NOTIFYICONDATA);
nd.hWnd= m_hWnd;
nd.uID= IDR_MAINFRAME;
nd.uFlags= NIF_ICON|NIF_MESSAGE|NIF_TIP;
nd.uCallbackMessage= WM_NOTIFYICON;
nd.hIcon= m_hIcon;
strcpy(nd.szTip, "我的托盘");
Shell_NotifyIcon(NIM_ADD, &nd);      
3、在程序的退了函数中加入删除托盘图标语句 

Shell_NotifyIcon(NIM_DELETE, &nd); 
二、在资源中添加菜单

1、建立菜单 

图2 菜单

2、建立菜单对应的函数

void CbackdropDlg::OnShow()
{
   ShowWindow( SW_SHOWNORMAL);//恢复正常显示
}

void CbackdropDlg::OnExit()
{
   ::PostQuitMessage(0); //退出
}
void CbackdropDlg::OnHide()
{
   ShowWindow(SW_HIDE);//隐藏
}

void CbackdropDlg::OnMin()
{
   ShowWindow(SW_SHOWMINIMIZED);//最小化
}
三、添加响应函数 

1、在类中加入托盘消息响应函数

LONG CbackdropDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam)      
2、手中添加消息映射
//}}AFX_MSG_MAP
ON_MESSAGE(WM_NOTIFYICON, OnNotifyIcon)//手工添加消息映射
END_MESSAGE_MAP()       
3、在托盘消息响应函数中添加代码
LONG CbackdropDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
{
	// 响应在托盘图标上的单击
	//wParam中是响应消息的图标ID,lParam中则是Windows的消息
	// The backdrop icon sent us a message.  Let''s see what it is
    switch ( lParam )
    {
	case WM_RBUTTONDOWN:
		{
		    // 用户在托盘图标上单击鼠标右键,弹出菜单	
			CMenu pMenu;
			if (pMenu.LoadMenu(IDR_MENU1))
			{
				CMenu* pPopup = pMenu.GetSubMenu(0);
				ASSERT(pPopup != NULL);
				CPoint Point;
				if(IsIconic()) pPopup->EnableMenuItem(IDC_MIN,MF_BYCOMMAND | 
					                             MF_DISABLED | MF_GRAYED);
				if (IsWindowVisible())// 根据对话框窗口的状态对相关菜单项使能
				{
					if(!IsIconic())
						pPopup->EnableMenuItem(IDC_SHOW,MF_BYCOMMAND | 
						                       MF_DISABLED | MF_GRAYED);
				}
				else
					pPopup->EnableMenuItem(IDC_HIDE,MF_BYCOMMAND | 
					                                MF_DISABLED | MF_GRAYED);
				if (bkbmp)// 根据对话框背景图状态改变菜单名称
					pMenu.ModifyMenu(IDC_FIX,MF_STRING,IDC_FIX,"变化背景");
				else
					pMenu.ModifyMenu(IDC_FIX,MF_STRING,IDC_FIX,"固定背景)");
				// 确定鼠标位置以便在该位置附近显示菜单
				GetCursorPos( &Point );
				SetForegroundWindow();
				pPopup->TrackPopupMenu(
					TPM_LEFTALIGN | TPM_RIGHTBUTTON,
					Point.x, Point.y, this);?
			}
		}
		break;
	case WM_LBUTTONDBLCLK:
	case WM_LBUTTONDOWN:
		// OnShow();
		break;
    }
    return 0;
}      
结束语
  自本人有幸找到VCKBASE以来的大半年里得到了论坛中的众多高手指点,收益匪浅,所以想为VCKBASE论坛做点什么,因本人水平较低,故只能将在VCKBASE论坛中现学会的关于托盘右击菜单的方法结合变化背景图实例向大家汇报一下。要进一步了解背景图的内容请参考背景图实例中代码,如想了解更多的托盘资料请参考本站有关文章和实例。由于时间、水平限制,缺点和不足之处在所难免,敬请各位高手多多批评指正.。在此再一次对本论坛和在论坛中对我提供帮助的众多高手深深表示感谢!
--------------------next---------------------

如果设计一个MFC程序,这段代码应该放到哪个类中?我试放到CMainFrame类中,编译没错,一执行就非法关闭...放到CXXXApp类中也不行... ( firefly3233 发表于 2007-4-29 20:31:00)
 
不错 ( uljtg021 发表于 2007-1-15 18:59:00)
 
程序写的不错 很有指导意义 ( uljtg021 发表于 2007-1-15 18:59:00)
 
这么简单的东西拜托不要随便拿上来啊 ( sohou 发表于 2005-5-12 13:24:00)
 
amethystwu:
您说的对!(当时我只是随手改的) ( vcxian 发表于 2005-4-20 19:15:00)
 
我又了一下,两位高手说的有道理,可以把这段程序改为:
void CbackdropDlg::OnTimer(UINT nIDEvent) 
{
if(!bkbmp)
{
bkbmp_n++;
if(bkbmp_n>2) bkbmp_n=0; 
//    Shell_NotifyIcon(NIM_DELETE, &nd);
switch(bkbmp_n)
{
case 0:
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
break;
case 1:
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
break;
case 2:
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON2);
break;
default:
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
nd.hIcon = m_hIcon;
// Shell_NotifyIcon(NIM_ADD, &nd);
    Shell_NotifyIcon(NIM_MODIFY, &nd);
InvalidateRect(NULL,TRUE);//刷当前程序界面

}
CDialog::OnTimer(nIDEvent);
} ( angcba 发表于 2005-4-20 17:08:00)
 
不要忘记在switch(bkbmp_n)中删除case 1的nd.uID = IDI_ICON1和case 2中的nd.uID = IDI_ICON2。这里面的uID可不是图标的ID哦。 ( amethystwu 发表于 2005-4-20 15:22:00)
 
angcba:
不知道你是在什么系统下测试? 我分别在Winxp,2K和me下试了一下, 切换托盘图标的时候用Shell_NotifyIcon(NIM_MODIFY, &nd)就够了。当然在程序退出的时候应该用Shell_NotifyIcon(NIM_DELETE, &nd)删除掉它。 ( amethystwu 发表于 2005-4-20 13:57:00)
 
试的结果就是这样!需要删除托盘 ( angcba 发表于 2005-4-20 12:01:00)
 
“不删的话程序执行时托盘上将会增加两个图标”?
不可能呀,你试了吗? ( vcxian 发表于 2005-4-20 10:32:00)
 
.......................................................

--------------------next---------------------

阅读(381) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~