VC++系统托盘简单实现介绍
托盘程序:就是屏幕右下角任务栏显示的一些小图标的程序。这些程序不用时,放到托盘里,随用随叫,不必将其关闭。
托盘编程主要用到的数据和方法介绍:
就是在托盘区绘制一个图标,然后把程序隐藏不见,当对托盘的图标进行操作时,对相关消息进行处理。
第一: 函数:
WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);
1、第一个参数:dwMessage
-
NIM_ADD (0X00000000): 添加一个系统托盘
-
NIM_MODIFY (0X00000001): 系统托盘的修改
-
NIM_DELETE (0X00000002): 系统托盘的删除
-
NIM_SETFOCUS (0X00000003): 令系统托盘获得焦点
-
NIM_SETVERSION (0X00000004): 系统托盘设置版本
typedef struct _NOTIFYICONDATA {
DWORD cbSize;//结构体的大小,单位是字节
HWND hWnd;//此托盘程序的句柄
UINT uID;// 系统为托盘区域每个图标分配的ID
UINT uFlags;//简单的说,就是一个标示
UINT uCallbackMessage;//回调消息。需要自定义一个消息,用来接收鼠标滑过或点击等消息。
HICON hIcon;//图标
TCHAR szTip[64];//提示文字的大小
DWORD dwState;//图标的状态
DWORD dwStateMask;//与上面类似
TCHAR szInfo[256];//显示在气泡通知中的文本
union {
UINT uTimeout;
UINT uVersion;
};
TCHAR szInfoTitle[64];//托盘通知的标题
DWORD dwInfoFlags;//修改托盘通知相关的标示
GUID guidItem;//图标的GUID
HICON hBalloonIcon;//托盘通知的图标
} NOTIFYICONDATA, *PNOTIFYICONDATA;
第二、实例
1、隐藏程序的主窗口
首先,要使程序的主窗口不可见,并且不在任务栏上出现任务按钮,要做到这两点,需分别设置主边框窗口的风格和扩展风格:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { cs.style =WS_POPUP;//使主窗口不可见 cs.dwExStyle |=WS_EX_TOOLWINDOW;//不显示任务按钮 return CFrameWnd::PreCreateWindow(cs); } |
2、将表示程序运行的图标加入任务栏
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { NOTIFYICONDATA tnd; tnd.cbSize=sizeof(NOTIFYICONDATA); tnd.hWnd=this->m_hWnd; tnd.uID=IDR_MAINFRAME; tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP; tnd.uCallbackMessage=WM_MYMESSAGE; file://用户自定义的消息,即鼠标在任务栏上程序图标上动作时图标发送的消息 tnd.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME)); strcpy(tnd.szTip,"测试程序");//图标提示为"测试程序" //向任务栏添加图标 Shell_NotifyIcon(NIM_ADD,&tnd); ShowWindow(SW_HIDE);//隐藏主窗口 } 3、用户与程序交互的消息菜单实现 当用户在该图标上单击或双击鼠标左键或右键时要执行相应的操作,当用户在图标上进行鼠标动作时,将向hWnd成员中指定的窗口发出自定义的消息,该消息为uCallbackMessage成员所指定的WM_MYESSAGE,取值为WM_USER+101(如何自定义消息,我就不多说了)。 #define WM_ICON_NOTIFY WM_USER+101 LRESULT CSysTray::OnTray(UINT wParam, LONG lParam) { if (wParam != m_NotifyIconData.uID) return 0L; CWnd *pMainWnd = AfxGetMainWnd(); switch(LOWORD(lParam)) { case WM_RBUTTONUP: { CMenu menu, *pSubMenu; if (!menu.LoadMenu(m_NotifyIconData.uID)) return 0; pSubMenu = menu.GetSubMenu(0); if (pSubMenu == NULL) return 0; CPoint pos; GetCursorPos(&pos); pSubMenu->TrackPopupMenu(0, pos.x, pos.y, pMainWnd, NULL); menu.DestroyMenu(); break; } case WM_LBUTTONDBLCLK: { pMainWnd->ShowWindow(SW_SHOW); pMainWnd->SetForegroundWindow(); break; } default: break; } return 1; } 4、程序结束时删除程序图标 当程序结束时,需要删去通告区中的图标,这时还应该调用Shell_NotifyIcon函数,只不过第一个参数是表示删除图标的NIM_DELETE了:
|
5、图标更改
m_tnd.uFlags = NIF_ICON;
m_tnd.hIcon = hIcon;
Shell_NotifyIcon(NIM_MODIFY, &m_tnd);