MFC对话框程序中创建托盘图标的方法示例

1.在对话框类头文件中声名变量和函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
class CXXDlg{
// 原类中的代码...
private:
// 托盘图标用到的变量
NOTIFYICONDATA m_notifyIconData{ 0 };
public:
// 初始化m_notifyIconData
BOOL InitNotifyIcon();
// 控制显示/隐藏托盘图标
BOOL ShowNotifyIcon(BOOL bShow);
// 托盘图标回调函数
afx_msg LRESULT NotifyIconCallBack(WPARAM wParam, LPARAM lParam);
};

2.在cpp文件中定义函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
BOOL CXXDlg::InitNotifyIcon()
{
// Add a Shell_NotifyIcon notificaion
m_notifyIconData.cbSize = sizeof(m_notifyIconData);
// 图标ID
m_notifyIconData.uID = IDR_MAINFRAME;
m_notifyIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
m_notifyIconData.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
// 这里是定义的消息ID
m_notifyIconData.uCallbackMessage = WM_NOTIFY_MESSAGE;
lstrcpy(m_notifyIconData.szTip, _T("XX"));
m_notifyIconData.hWnd = m_hWnd;
// 增加图标到托盘
// Shell_NotifyIcon(NIM_ADD, &m_notifyIconData);
// 更新图标的代码
// m_notifyIconData.uFlags = NIF_ICON;
// m_notifyIconData.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));
return 0;
}

BOOL CXXDlg::ShowNotifyIcon(BOOL bShow)
{
BOOL bResult = FALSE;
if (bShow)
{
bResult = Shell_NotifyIcon(NIM_ADD, &m_notifyIconData);
}
else
{
bResult = Shell_NotifyIcon(NIM_DELETE, &m_notifyIconData);
}
return bResult;
}

LRESULT CXXDlg::NotifyIconCallBack(WPARAM wParam, LPARAM lParam)
{
UINT uID{ wParam };
UINT uMouseMsg{ (UINT)lParam };

switch (uMouseMsg)
{
// 在托盘图标上抬起右键
case WM_RBUTTONUP:
{
NotifyIconMesgRestore(0, 0);
}
break;
// 在托盘图标上抬起左键
case WM_LBUTTONUP:
{
NotifyIconMesgRestore(0, 0);
}
break;
default:
{
}
break;
}
return LRESULT();
}
// 还原窗口
LRESULT CXXDlg::NotifyIconMesgRestore(WPARAM wParam, LPARAM lParam)
{
// 还原到其原始大小并显示窗口
ShowWindow(SW_SHOWNORMAL);
// 置顶窗口
::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
// 删除托盘图标
ShowNotifyIcon(FALSE);
return LRESULT();
}

3.定义WM_NOTIFY_MESSAGE并在消息映射表中增加映射

1
2
3
4
5
6
7
8
9
10
11
12
// 定义一个在项目中独一无二的宏。消息ID
#define WM_NOTIFY_MESSAGE WM_USER + 101

BEGIN_MESSAGE_MAP(CXXDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_SIZE()
ON_WM_DESTROY()
// 增加的映射
ON_MESSAGE(WM_NOTIFY_MESSAGE, NotifyIconCallBack)
END_MESSAGE_MAP()

4.增加Onsize并在OnSize中增加最小化时创建托盘图标和隐藏窗口的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void CXXDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);

// TODO: 在此处添加消息处理程序代码

if (SIZE_MINIMIZED == nType)
{
// 最小化时创建托盘图标
ShowNotifyIcon(TRUE);
// 隐藏窗口
ShowWindow(SW_HIDE);
}
}

到这里对话框程序已经可以最小化到托盘了。

5.参考

Shell_NotifyIcon https://docs.microsoft.com/en-us/previous-versions/aa922175(v=msdn.10) )