2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2018 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Kern Sibbald, August 2007
23 * This is a generic tray monitor routine, which is used by all three
24 * of the daemons. Each one compiles it with slightly different
33 trayMonitor::trayMonitor()
36 // m_tbcreated_msg = RegisterWindowMessage("TaskbarCreated");
38 /* Create a window to handle tray icon messages */
41 trayclass.cbSize = sizeof(trayclass);
43 trayclass.lpfnWndProc = trayMonitor::trayWinProc;
44 trayclass.cbClsExtra = 0;
45 trayclass.cbWndExtra = 0;
46 trayclass.hInstance = appInstance;
47 trayclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
48 trayclass.hCursor = LoadCursor(NULL, IDC_ARROW);
49 trayclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
50 trayclass.lpszMenuName = NULL;
51 trayclass.lpszClassName = APP_NAME;
52 trayclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
54 RegisterClassEx(&trayclass);
56 m_hwnd = CreateWindow(APP_NAME, APP_NAME, WS_OVERLAPPEDWINDOW,
57 CW_USEDEFAULT, CW_USEDEFAULT, 200, 200,
58 NULL, NULL, appInstance, NULL);
64 /* Save our class pointer */
65 SetWindowLong(m_hwnd, GWL_USERDATA, (LPARAM)this);
68 // Load the icons for the tray
69 m_idle_icon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_IDLE));
70 m_running_icon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_RUNNING));
71 m_error_icon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_JOB_ERROR));
72 m_warn_icon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_JOB_WARNING));
75 m_hmenu = LoadMenu(appInstance, MAKEINTRESOURCE(IDR_TRAYMENU));
79 /* Install the icon in the tray */
82 /* Timer to trigger icon updating */
83 SetTimer(m_hwnd, 1, 5000, NULL);
86 trayMonitor::~trayMonitor()
88 /* Remove the icon from the tray */
89 sendMessage(NIM_DELETE, 0);
97 void trayMonitor::install()
100 sendMessage(NIM_ADD, bacstat);
103 void trayMonitor::update(int bacstat)
108 (void)bac_status(NULL, 0);
109 sendMessage(NIM_MODIFY, bacstat);
112 void trayMonitor::sendMessage(DWORD msg, int bacstat)
114 struct s_last_job *job;
116 // Create the tray icon message
118 m_nid.cbSize = sizeof(m_nid);
119 m_nid.uID = IDI_BACULA; // never changes after construction
122 m_nid.hIcon = m_idle_icon;
125 m_nid.hIcon = m_running_icon;
127 case JS_ErrorTerminated:
128 m_nid.hIcon = m_error_icon;
131 if (last_jobs->size() > 0) {
132 job = (struct s_last_job *)last_jobs->last();
134 m_nid.hIcon = m_warn_icon;
136 m_nid.hIcon = m_idle_icon;
139 m_nid.hIcon = m_idle_icon;
144 m_nid.uFlags = NIF_ICON | NIF_MESSAGE;
145 m_nid.uCallbackMessage = WM_TRAYNOTIFY;
148 /* Use the resource string as tip */
149 if (LoadString(appInstance, IDI_BACULA, m_nid.szTip, sizeof(m_nid.szTip))) {
150 m_nid.uFlags |= NIF_TIP;
153 /* Add the Bacula status to the tip string */
154 if (m_nid.uFlags & NIF_TIP) {
155 bac_status(m_nid.szTip, sizeof(m_nid.szTip));
158 if (Shell_NotifyIcon(msg, &m_nid)) {
159 EnableMenuItem(m_hmenu, ID_CLOSE, MF_ENABLED);
164 * This is the windows call back for our tray window
166 LRESULT CALLBACK trayMonitor::trayWinProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
169 trayMonitor *mon = (trayMonitor *)GetWindowLong(hwnd, GWL_USERDATA);
173 /* Every five seconds, a timer message causes the icon to update */
178 mon->update(bacstat);
185 /* User has clicked an item on the tray monitor menu */
186 switch (LOWORD(wParam)) {
188 /* show the dialog box */
189 mon->m_status.show(true);
190 mon->update(bacstat);
194 /* Show the About box */
195 mon->m_about.show(true);
198 /* This is turned off now */
201 /* User selected Close from the tray menu */
202 PostMessage(hwnd, WM_CLOSE, 0, 0);
209 /* Our special command to check for mouse events */
211 /* Right button click pops up the menu */
212 if (lParam == WM_RBUTTONUP) {
214 /* Get the menu and pop it up */
215 menu = GetSubMenu(mon->m_hmenu, 0);
220 /* The first menu item (Status) is the default */
221 SetMenuDefaultItem(menu, 0, TRUE);
222 GetCursorPos(&mouse);
223 SetForegroundWindow(mon->m_nid.hWnd); /* display the menu */
225 /* Open the menu at the mouse position */
226 TrackPopupMenu(menu, 0, mouse.x, mouse.y, 0, mon->m_nid.hWnd, NULL);
228 /* Left double click brings up status dialog directly */
229 } else if (lParam == WM_LBUTTONDBLCLK) {
230 mon->m_status.show(true);
231 mon->update(bacstat);
237 mon->sendMessage(NIM_DELETE, 0);
247 case WM_QUERYENDSESSION:
248 if (!isAService() || lParam == 0) {
255 /* Need to redraw tray icon */
256 // if (iMsg == mon->m_tbcreated_msg) {
262 return DefWindowProc(hwnd, iMsg, wParam, lParam);