VC制作托盘(转)

来源:互联网 发布:寒门崛起抄袭软件 编辑:程序博客网 时间:2024/05/18 00:35


效果如图:托盘效果可以做的更好些.比如图标,还有ToolTip菜单提示,由于本人非专门搞界面的,所以就到此,有兴趣的可以深研,本节的模型很好,很适合扩展性,即封装性,即取即用

------------------------本节分2部分 第1部分:讲解 第2部分:详细代码-----------------------------
-----------------------------第1部分:讲解-----------------------------------
第1步:创建MFC对话框应用程序--->属性:不使用Unicode库(也就是用多字节库)--->属性:使用静态链接库(考虑到程序移植问题,因为用动态库,把程序给别人后,经常出现缺少库文件的提示)--->属性:把关于对话框留下(留着以后也许有用!不过危害性也同样大,因为打开类向导时,默认是在关于对话框类下,所以响应函数的时候一定要注意了!!!!--->一定要注意了,在类向导中使用的时候,速度一快,很容易忽略掉此错误
第2步:设置界面(对话框与菜单栏)--->按自己风格设置,此步不做任何响应
第3步:开始响应--->此步只在类向导中响应,注:响应中不做任何事件反应,仅是个框架而已,里面什么也没有--->注:本例涉及函数少才统一处理,多的话,就走一步算一步了
第4步:向框架中注入"灵魂"
--->模块1:随机启动--->这个直接复制函数中的代码过去就能用了(注:这个是自定义的,指定谁,谁就运行.当然也可指定自己)
--->模块2:设置托盘(把托盘弄出来)--->NOTIFYICONDATA nfydata;与Shell_NotifyIcon配合写出来(注:中间会产生一个自定义回调函数,专门供托盘菜单响应用的)
--->模块3:跟着2托盘菜单专门的回调函数添加菜单响应---->菜单1,菜单2,菜单3响应(注:基类可以是APP.CPP,也可以是DLG.CPP,但是不可是关于对话框.CPP)---之后是"退出"响应(基类必须是DLG.CPP,因为CDialog::OnCancel();明确说明DLG)
--->模块4:气泡显示--->复制函数即可
备注1:若想程序打开时,就显示托盘,应该怎么做?
直接放在OnInitDialog()函数中即可--->注:<<VC编程精选>>中采用的就是此步骤(当然原理是一样的)
-----------------------------第2部分:详细代码-----------------------------------


void C托盘Dlg::OnBnClickedSetTray()
{
//初始化数据
UpdateData();
nfydata.cbSize = sizeof(NOTIFYICONDATA);
nfydata.uFlags = NIF_ICON|NIF_TIP|NIF_MESSAGE;
nfydata.hWnd   = m_hWnd;
nfydata.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
nfydata.uCallbackMessage = UM_NOTIFY; //LEE :回调消息
strcpy_s(nfydata.szTip ,m_tray_message);

//显示系统托盘图标
Shell_NotifyIcon(NIM_ADD,&nfydata);

((CButton *)GetDlgItem(IDB_SHOW_BALL))->EnableWindow(TRUE);
}


void C托盘Dlg::OnBnClickedTray()
{
ShowWindow(SW_HIDE);//隐藏主窗口,即只显示托盘
}


void C托盘Dlg::OnBnClickedShowBall()
{
UpdateData();//刷新信息,这个函数本博客以前详细介绍过了.搜索一下本博客
nfydata.uFlags = NIF_ICON|NIF_TIP|NIF_INFO; //添加NIF_INFO 标识
strcpy_s(nfydata.szInfoTitle ,m_ball_title); //提示标题
strcpy_s(nfydata.szInfo,m_ball_message);     //提示信息
nfydata.uTimeout = 5000;               //超时值5秒,即显示5秒后自动退出气泡提示
nfydata.dwInfoFlags = NIIF_INFO; //图标类型,更多类型详见MSDN中函数的介绍

//LEE :修改系统托盘信息
Shell_NotifyIcon(NIM_MODIFY,&nfydata); 
}


void C托盘Dlg::OnBnClickedStartup()
{
//设置系统开机自运行程序
//备注:这个是自定义的,指定谁,谁就运行.当然也可指定自己
CString   StrFilter="可执行程序(*.exe)|*.exe|所有文件(*.*)|*.*||";
CFileDialog Dlg(TRUE,NULL,NULL,NULL,StrFilter,this); 
if(Dlg.DoModal()==IDCANCEL)
   return;
HKEY hKey;
LPCTSTR StrKey="Software\\Microsoft\\Windows\\CurrentVersion\\Run";
if (ERROR_SUCCESS==::RegOpenKeyEx(HKEY_CURRENT_USER,StrKey,NULL,KEY_ALL_ACCESS,&hKey))
{
   CString Value=Dlg.GetPathName();
   LPCSTR KeyValue=Dlg.GetFileTitle();
   if (ERROR_SUCCESS==::RegSetValueEx(hKey,(LPCTSTR)KeyValue,0,REG_SZ,(BYTE *)(LPCSTR)Value,strlen(Value)+1))
   {  
    MessageBox(Value+"程序已经被设置为系统开机自动运行程序!","信息提示",MB_OK);
   }
   ::RegCloseKey(hKey);
}
}
/////////////////////////以下是托盘的消息响应,函数来自设置托盘UM_
//LEE :处理系统托盘消息
LRESULT C托盘Dlg::OnNotify(WPARAM wParam, LPARAM lParam)
{

switch(lParam)
{
case WM_LBUTTONDOWN://响应左键双击
   ShowWindow(SW_SHOW);
   // TrayMessage(m_hWnd, NIM_DELETE, NULL, "");//不要删除托盘
   break;

case WM_RBUTTONUP://响应右键
   CMenu m;//弹出式菜单
   m.LoadMenu(IDR_TRAY_MENU);
   POINT p;
   GetCursorPos(&p);
   m.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN,p.x,p.y,this);//弹出位置(这项为x,y坐标为菜单的左上角)
   break;

}

return 0;
}


void C托盘Dlg::OnExit()
{
//删除系统托盘图标
Shell_NotifyIcon(NIM_DELETE,&nfydata);//虽然程序退出后就自动析构了,此处写出仅是提示作用,告诉其用法
CDialog::OnCancel();
}


void C托盘App::OnBaidu()
{
ShellExecute(0, 0, "http://www.baidu.com", NULL, NULL, SW_SHOW );
}


void C托盘App::OnXunlei()
{
ShellExecute(0, 0, "http://www.xunlei.com", NULL, NULL, SW_SHOW );
}


void C托盘App::OnQq()
{
ShellExecute(0, 0, "http://www.qq.com", NULL, NULL, SW_SHOW );
}
附注1:本程序已上传至邮箱,即取即用
附注2:本程序实现至菜单提示部分,介绍一下相关资料:

//////////////////////摘抄,仅供后续补充参考///////////////////////////

简单一点的就是Tooltip,难一点的,就是可自定义的就是

自己写,继承 CWnd,原理就是 SetWindowsPos OnPaint ShowWindow OnTimer
CToopTip 内部有个 CMap结构 用HWND 做哈希元素,要实现丰富的个性提示, 那个太逊了。
我是说怎么自定制,
另外CToolTipCtrl Members这个函数可能会有点帮助

以下是辅助代码,好像有些东西未消化,下面的代码应该会有帮助

#define WM_MSG 9078
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
ON_MESSAGE(WM_MSG,OnMes)
ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, OnBnClickedButton3)
END_MESSAGE_MAP()
BOOL CMyDlg::OnInitDialog()
{
        ...
d=LoadIcon(AfxGetInstanceHandle(),"B");
x=LoadIcon(AfxGetInstanceHandle(),"X");
return TRUE;
}
void CMyDlg::OnBnClickedButton1()//加入图标
{
NOTIFYICONDATA nfd;
nfd.cbSize=sizeof(nfd);
nfd.hWnd=this->GetSafeHwnd();
nfd.hIcon=d;
nfd.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
strcpy(nfd.szTip,"图标一");
nfd.uCallbackMessage=WM_MSG;//消息
Shell_NotifyIcon(NIM_ADD ,&nfd);
}

void CMyDlg::OnBnClickedButton2()//修改图标
{
NOTIFYICONDATA nfd;
nfd.cbSize=sizeof(NOTIFYICONDATA);
nfd.hWnd=this->GetSafeHwnd();
nfd.hIcon=x;
nfd.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
strcpy(nfd.szTip,"图标二");
nfd.uCallbackMessage=WM_MSG;
Shell_NotifyIcon(NIM_MODIFY,&nfd);

}

void CMyDlg::OnBnClickedButton3()//删除图标
{
NOTIFYICONDATA nfd;
nfd.cbSize=sizeof(nfd);
nfd.hWnd=this->GetSafeHwnd();
Shell_NotifyIcon(NIM_DELETE,&nfd);
}
LRESULT CMyDlg::OnMes(WPARAM wparam,LPARAM lparam)
{
switch((UINT)lparam)//右下角图标的消息处理函数
{
case WM_LBUTTONDOWN:
   AfxMessageBox("单击了左键");
   break;
case WM_LBUTTONDBLCLK:
   AfxMessageBox("双击了左键");
   break;
case WM_RBUTTONDBLCLK:
   AfxMessageBox("双击了右键");
   break;
case WM_RBUTTONDOWN:
   CMenu m;//弹出式菜单
   m.LoadMenu(IDR_MENU1);
   POINT p;
   GetCursorPos(&p);
   m.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN//弹出位置(这项为x,y坐标为菜单的左上角
    ,p.x,p.y,this);
   break;

}
return 0;
}

原创粉丝点击