2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Kern Sibbald, August 2007
34 * This is a generic tray monitor routine, which is used by all three
35 * of the daemons. Each one compiles it with slightly different
44 trayMonitor::trayMonitor()
47 // m_tbcreated_msg = RegisterWindowMessage("TaskbarCreated");
49 /* Create a window to handle tray icon messages */
52 trayclass.cbSize = sizeof(trayclass);
54 trayclass.lpfnWndProc = trayMonitor::trayWinProc;
55 trayclass.cbClsExtra = 0;
56 trayclass.cbWndExtra = 0;
57 trayclass.hInstance = appInstance;
58 trayclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
59 trayclass.hCursor = LoadCursor(NULL, IDC_ARROW);
60 trayclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
61 trayclass.lpszMenuName = NULL;
62 trayclass.lpszClassName = APP_NAME;
63 trayclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
65 RegisterClassEx(&trayclass);
67 m_hwnd = CreateWindow(APP_NAME, APP_NAME, WS_OVERLAPPEDWINDOW,
68 CW_USEDEFAULT, CW_USEDEFAULT, 200, 200,
69 NULL, NULL, appInstance, NULL);
75 /* Save our class pointer */
76 SetWindowLong(m_hwnd, GWL_USERDATA, (LONG)this);
79 // Load the icons for the tray
80 m_idle_icon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_IDLE));
81 m_running_icon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_RUNNING));
82 m_error_icon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_JOB_ERROR));
83 m_warn_icon = LoadIcon(appInstance, MAKEINTRESOURCE(IDI_JOB_WARNING));
86 m_hmenu = LoadMenu(appInstance, MAKEINTRESOURCE(IDR_TRAYMENU));
90 /* Install the icon in the tray */
93 /* Timer to trigger icon updating */
94 SetTimer(m_hwnd, 1, 5000, NULL);
97 trayMonitor::~trayMonitor()
99 /* Remove the icon from the tray */
100 sendMessage(NIM_DELETE, 0);
103 DestroyMenu(m_hmenu);
108 void trayMonitor::install()
111 sendMessage(NIM_ADD, bacstat);
114 void trayMonitor::update(int bacstat)
119 (void)bac_status(NULL, 0);
120 sendMessage(NIM_MODIFY, bacstat);
123 void trayMonitor::sendMessage(DWORD msg, int bacstat)
125 struct s_last_job *job;
127 // Create the tray icon message
129 m_nid.cbSize = sizeof(m_nid);
130 m_nid.uID = IDI_BACULA; // never changes after construction
133 m_nid.hIcon = m_idle_icon;
136 m_nid.hIcon = m_running_icon;
138 case JS_ErrorTerminated:
139 m_nid.hIcon = m_error_icon;
142 if (last_jobs->size() > 0) {
143 job = (struct s_last_job *)last_jobs->last();
145 m_nid.hIcon = m_warn_icon;
147 m_nid.hIcon = m_idle_icon;
150 m_nid.hIcon = m_idle_icon;
155 m_nid.uFlags = NIF_ICON | NIF_MESSAGE;
156 m_nid.uCallbackMessage = WM_TRAYNOTIFY;
159 /* Use the resource string as tip */
160 if (LoadString(appInstance, IDI_BACULA, m_nid.szTip, sizeof(m_nid.szTip))) {
161 m_nid.uFlags |= NIF_TIP;
164 /* Add the Bacula status to the tip string */
165 if (m_nid.uFlags & NIF_TIP) {
166 bac_status(m_nid.szTip, sizeof(m_nid.szTip));
169 if (Shell_NotifyIcon(msg, &m_nid)) {
170 EnableMenuItem(m_hmenu, ID_CLOSE, MF_ENABLED);
175 * This is the windows call back for our tray window
177 LRESULT CALLBACK trayMonitor::trayWinProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
180 trayMonitor *mon = (trayMonitor *)GetWindowLong(hwnd, GWL_USERDATA);
184 /* Every five seconds, a timer message causes the icon to update */
189 mon->update(bacstat);
196 /* User has clicked an item on the tray monitor menu */
197 switch (LOWORD(wParam)) {
199 /* show the dialog box */
200 mon->m_status.show(true);
201 mon->update(bacstat);
205 /* Show the About box */
206 mon->m_about.show(true);
209 /* This is turned off now */
212 /* User selected Close from the tray menu */
213 PostMessage(hwnd, WM_CLOSE, 0, 0);
220 /* Our special command to check for mouse events */
222 /* Right button click pops up the menu */
223 if (lParam == WM_RBUTTONUP) {
225 /* Get the menu and pop it up */
226 menu = GetSubMenu(mon->m_hmenu, 0);
231 /* The first menu item (Status) is the default */
232 SetMenuDefaultItem(menu, 0, TRUE);
233 GetCursorPos(&mouse);
234 SetForegroundWindow(mon->m_nid.hWnd); /* display the menu */
236 /* Open the menu at the mouse position */
237 TrackPopupMenu(menu, 0, mouse.x, mouse.y, 0, mon->m_nid.hWnd, NULL);
239 /* Left double click brings up status dialog directly */
240 } else if (lParam == WM_LBUTTONDBLCLK) {
241 mon->m_status.show(true);
242 mon->update(bacstat);
248 mon->sendMessage(NIM_DELETE, 0);
258 case WM_QUERYENDSESSION:
259 if (!isAService() || lParam == 0) {
266 /* Need to redraw tray icon */
267 // if (iMsg == mon->m_tbcreated_msg) {
273 return DefWindowProc(hwnd, iMsg, wParam, lParam);