一、什么是托盘
下面是一些托盘图标例子,不用讲大家应该都能懂吧(图片被打了水印,导致有点花)
二、制作托盘图标
1. 增加托盘
核心代码:
全局定义
NOTIFYICONDATA g_Nid = { 0 };
HWND hWnd = NULL; // 主窗口句柄
#define WM_SHOWTASK WM_USER + 1 // 托盘图标消息ID
#define IDM_FILE_SHOW 1001 // 菜单项 “显示”的ID
#define IDM_FILE_QUIT 1002 // 菜单项 “退出”的ID
两个方法
void AddToSysTray()
{
g_Nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
g_Nid.hWnd = hWnd; // 关联窗口
g_Nid.uID = IDR_MAINFRAME; // 应用程序定义的任务栏图标的标识符
g_Nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;
g_Nid.uCallbackMessage = WM_SHOWTASK; // 自定义消息
g_Nid.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SYSTRAY)); // 显示的图标,注:IDI_SYSTRAY如不存,需要手动添加到资源文件中
_tcscpy_s(g_Nid.szTip ,128 , _T("我的托盘")); // 信息提示条为"服务器程序"
Shell_NotifyIcon(NIM_ADD, &g_Nid); // 在托盘区添加图标
}
void DelToSysTray()
{
Shell_NotifyIcon(NIM_DELETE, &g_Nid);
}
在应用程序初始化的时候调用AddSysTray,注意,主窗口hWnd句柄必须初始化,托盘图标才起作用。
另外,还需要对窗口过程的消息处理进行改写:
代码如下:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_FILE_SHOW: // 点击菜单-显示
ShowWindow(hWnd, SW_SHOW);
break;
case IDM_EXIT: // 系统菜单
DelToSysTray();
PostQuitMessage(0);
break;
case IDM_FILE_QUIT: // 点击菜单-退出
DelToSysTray();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_SHOWTASK: // 托盘消息处理
{
if(wParam != IDR_MAINFRAME)
{
return 0;
}
switch(lParam)
{
case WM_LBUTTONDOWN: // 左键显示
ShowWindow(hWnd, SW_SHOW);
break;
case WM_RBUTTONUP: // 右键显示菜单
{
LPPOINT lpoint = new tagPOINT;
::GetCursorPos(lpoint);
//动态菜单
HMENU hMenuPop = CreatePopupMenu(); //下拉的菜单,垂直
AppendMenu(hMenuPop,MF_STRING,IDM_FILE_SHOW,_T("显示"));
AppendMenu(hMenuPop,MF_STRING,IDM_FILE_QUIT,_T("退出"));
TrackPopupMenu(hMenuPop, TPM_LEFTALIGN, lpoint->x ,lpoint->y, 0, hWnd, NULL);
delete lpoint;
lpoint = NULL;
}
}
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_CLOSE: // 处理系统X按钮
Shell_NotifyIcon(NIM_MODIFY, &g_Nid);
ShowWindow(hWnd, SW_HIDE);
break;
case WM_DESTROY:
DelToSysTray();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}