分享
 
 
 

关于托盘的一点总结

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

关于托盘的一点总结

作者:张海明

下载本文示例工程

很多软件例如:KV3000等在关闭之后会在托盘区有一个小的托盘图标,这表示程序并没有真正停止而在后台运行。当我们单击鼠标时可以使它在桌面上出现一个最大化窗口;而如果我们单击程序右上角х,或者单击文件菜单中的退出项时程序仍然在托盘上运行;只有我们右键单击托盘图标在出现的菜单中选择退出才能够真正退出程序等。

现在我们通过一个类CSystemTray和修改系统菜单来实现上述功能。

我们先来改变系统菜单。

1、当我们在程序的标题栏上单击鼠标右键时,只出现如图的几项。

而通过MFC生成的还会出现About一项,我们已经把它给去掉了。

我们调用函数GetSystemMenu()来取的系统菜单,然后调用DeleteMenu()来去掉不要的系统菜单项,在这里我们去掉了“关闭”下面的分隔线和“about”项代码如下:CMenu *pSystemMenu=GetSystemMenu(FALSE);

pSystemMenu-DeleteMenu(8,MF_BYPOSITION);

pSystemMenu-DeleteMenu(7,MF_BYPOSITION);其中的数字7和8表示系统菜单的第7项和第8项,注意分隔线在VC中也算是一项。(这里和前面所讲的修改系统菜单的方法是一样的)。

当我们去掉“about”这项后就应该在系统命令中也去掉相应的相应代码。我们找到函数OnSysCommand(UINT nID, LPARAM lParam)去掉其中截获about对话框的代码:

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}它对我们没有任何用处,放在这里只能给我们调试带来麻烦。当然如果你不去掉它程序完全没有一点错误。

那么,为什么我们要去掉这两项呢,因为我们准备在托盘中实现相同的功能。

1, 我们再改变程序的关闭标志“X”的功能,把它改为隐藏而不是完全关闭。

我们来截获关闭命令,把它改为隐藏。if ((nID & 0xFFF0)==SC_CLOSE){

//OnClose();本来这个是关闭的这里也改为隐藏。

AnimateWindow(GetSafeHwnd(),1000,AW_HIDE|AW_BLEND);

KillTimer(0);

ShowWindow(SW_HIDE);//系统菜单的关闭也改为隐藏。

}在ShowWindow(SW_HIDE)前面的两句是为了实现一种特效,即是慢慢很温和的隐藏,不过只有这两句还是不行的还应该在stdafx.h的前面加上如下两行代码:

#undef WINVER

#define WINVER 0X500

2、我们来建立一个托盘菜单,ID号为IDR_TUOPAN当我们在托盘上点击右键时,会出现一个菜单,在菜单里我们有:关于、显示(隐藏)、换歌、退出四项。

我们先在头文件VioletPlayDlg.h中自定义一个消息:

#define WM_USER_TRAY_NOTIFICATION (WM_USER+0x101)

注意它的格式。在文件中定义一个托盘变量CSystemTray m_trayIcon,有了这些后我们就可以先做一个托盘雏形了。在主文件VioletPlayDlg.cpp中来产生一个托盘了。我们用Creat()函数定义如下:

m_trayIcon.Create(this, WM_USER_TRAY_NOTIFICATION, "VioletPlay", m_hIcon, IDR_TUOPAN);

其中第二个参数为我们自定义的功能,即出现托盘图标,第三个参数为当我们把鼠标放在图标上时出现的说明文字,第五个参数为当我们单击右键时出现的菜单,由于我们通过这个函数并不能响应右键,所以在这里并不能出现这个菜单,(下文会讲)

当我们的鼠标离开图标的时候出现的说明文字VioletPlay会自动消失,我们通过一个条件语句来实现。首先我们定义一个BOOL变量BOOL start_minimized我们来判断它的值:

if (start_minimized)

PostMessage(WM_CLOSE);

当我们鼠标移走的时候就发送一个CLOSE命令,关闭窗口。我们在文件VioletPlay.cpp中加上一句代码时程序运行的时候即可以在托盘中显示又可以在桌面上显示:

dlg.start_minimized=GetProfileInt(_T(""),_T("StartMinimized"),FALSE);

我们在这里在显示主程序的对话框之前加上这句代码,起到一个“拦截”作用。 这样我们就实现了最初的功能,即在托盘中出现了一个图标,但是这还是远远不够的,我们在来一步步实现其他的功能。

3、虽然我们有了一个托盘菜单,但是我们到现在还不能通过单击鼠标右键使它出现,因为我们的程序还不能响应这个消息,下面我们通过重载函数:afx_msg

LONG OnTrayNotification( WPARAM wparam, LPARAM lparam )并在里面加上响应代码来实现这个功能。

我们用switch…case…结构来响应鼠标右键这一消息,当然如果你愿意也是可以用if语句来实现同样的功能的。

代码如下:LONG CVioletPlayDlg::OnTrayNotification(WPARAM wparam, LPARAM lparam)

{

switch ( lparam )

{

case WM_RBUTTONDOWN:

{// 用户在托盘图标上单击鼠标右键,弹出上下文菜单隐藏/显示对话框。

CMenu oMenu;

if (oMenu.LoadMenu(IDR_TUOPAN))

{

CMenu* pPopup = oMenu.GetSubMenu(0);

ASSERT(pPopup != NULL);

CPoint oPoint;

if (IsWindowVisible())// 根据对话框窗口的显示/隐藏状态修改菜单名称

oMenu.ModifyMenu(IDC_SHOW,MF_STRING,IDC_SHOW,"隐藏(&H)");

else

oMenu.ModifyMenu(IDC_SHOW,MF_STRING,IDC_SHOW,"显示(&S)");

// 确定鼠标位置以便在该位置附近显示菜单

GetCursorPos( &oPoint );

SetForegroundWindow();

pPopup-TrackPopupMenu(

TPM_LEFTALIGN | TPM_RIGHTBUTTON,

oPoint.x, oPoint.y, this);

}

}

break;

// 单击/双击鼠标左键均显示出对话框

case WM_LBUTTONDBLCLK:

case WM_LBUTTONDOWN:

OnShow();

break;

}

return 0;

}

在上述代码中我们同时实现了动态改变菜单“显示/隐藏”的功能,当程序主界面出现时,菜单中变为“隐藏”表示如果我们再单击它时程序主界面就隐藏起来了。如果为隐藏状态时菜单中变为“显示”表示当我们单击它时可以显示程序主界面。

另外,在上面代码的最后三句表示不管我们是单击还是双击鼠标左键它发送的命令都是一样的即出现主程序界面,即OnShow()。

我们在对托盘菜单中的命令一个一个的分析。 这里的“退出”菜单我们使程序真正的退出,因此它接受的命令为 ::PostQuitMessage(0),使程序真正退出,注意前面我们也说了,其它的两个“退出”皆为隐藏。因为程序的使用者也许并不知道这一点,所以我们有必要在这里设计一个对话框进行提醒,如果要求这一点我们就把点击“退出”菜单所发送的命令改为调用一个AfxMessageBox,当是使用者点击“是”才实现真正的退出。点击“否”而不退出。

代码如下:

void CVioletPlayDlg::OnClose()

{

if(AfxMessageBox("真的要退出吗",MB_YESNO)==IDYES)

{

AnimateWindow(GetSafeHwnd(),1000,AW_HIDE|AW_BLEND);

KillTimer(0);

::PostQuitMessage(0);

}

}

当你点击了文件菜单中的退出时也是同样的道理只是当你点击“是”时只能隐藏主界面,而当你点击“否”时,不能隐藏主界面。我们只需要把上面代码中的退出命令:::PostQuitMessage(0)改为隐藏命令ShowWindow(SW_HIDE)就可以了。

到现在为止我们实现了托盘图标的所有功能。

注意:类CSystemTray继承于CWnd是public形式,类的定义和实现可以参考文件:VioletPlay,文件名分别为SystemTray.h和SystemTray.cpp

源文件见:VioletPlay (注,有一些代码用的是VCKBASE网站中,我只对其进行了分析和总结。再此表示谢意和歉意)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有