1 /*
2  *  ReactOS Task Manager
3  *
4  *  trayicon.c
5  *
6  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
7  *                2005         Klemens Friedl <frik85@reactos.at>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23 
24 #include "precomp.h"
25 
26 HICON TrayIcon_GetProcessorUsageIcon(void)
27 {
28     HICON     hTrayIcon = NULL;
29     HDC       hScreenDC = NULL;
30     HDC       hDC = NULL;
31     HBITMAP   hBitmap = NULL;
32     HBITMAP   hOldBitmap = NULL;
33     HBITMAP   hBitmapMask = NULL;
34     ICONINFO  iconInfo;
35     ULONG     ProcessorUsage;
36     int       nLinesToDraw;
37     HBRUSH    hBitmapBrush = NULL;
38     RECT      rc;
39 
40     /*
41      * Get a handle to the screen DC
42      */
43     hScreenDC = GetDC(NULL);
44     if (!hScreenDC)
45         goto done;
46 
47     /*
48      * Create our own DC from it
49      */
50     hDC = CreateCompatibleDC(hScreenDC);
51     if (!hDC)
52         goto done;
53 
54     /*
55      * Load the bitmaps
56      */
57     hBitmap = LoadBitmapW(hInst, MAKEINTRESOURCEW(IDB_TRAYICON));
58     hBitmapMask = LoadBitmapW(hInst, MAKEINTRESOURCEW(IDB_TRAYMASK));
59     if (!hBitmap || !hBitmapMask)
60         goto done;
61 
62     hBitmapBrush = CreateSolidBrush(RGB(0, 255, 0));
63     if (!hBitmapBrush)
64         goto done;
65 
66     /*
67      * Select the bitmap into our device context
68      * so we can draw on it.
69      */
70     hOldBitmap = (HBITMAP) SelectObject(hDC, hBitmap);
71 
72     /*
73      * Get the cpu usage
74      */
75     ProcessorUsage = PerfDataGetProcessorUsage();
76 
77     /*
78      * Calculate how many lines to draw
79      * since we have 11 rows of space
80      * to draw the cpu usage instead of
81      * just having 10.
82      */
83     nLinesToDraw = (ProcessorUsage + (ProcessorUsage / 10)) / 11;
84     rc.left = 3;
85     rc.top = 12 - nLinesToDraw;
86     rc.right = 13;
87     rc.bottom = 13;
88 
89     /*
90      * Now draw the cpu usage
91      */
92     if (nLinesToDraw)
93         FillRect(hDC, &rc, hBitmapBrush);
94 
95     /*
96      * Now that we are done drawing put the
97      * old bitmap back.
98      */
99     hBitmap = SelectObject(hDC, hOldBitmap);
100     hOldBitmap = NULL;
101 
102     iconInfo.fIcon = TRUE;
103     iconInfo.hbmMask = hBitmapMask;
104     iconInfo.hbmColor = hBitmap;
105 
106     hTrayIcon = CreateIconIndirect(&iconInfo);
107 
108 done:
109     /*
110      * Cleanup
111      */
112     if (hScreenDC)
113         ReleaseDC(NULL, hScreenDC);
114     if (hDC)
115         DeleteDC(hDC);
116     if (hBitmapBrush)
117         DeleteObject(hBitmapBrush);
118     if (hBitmap)
119         DeleteObject(hBitmap);
120     if (hBitmapMask)
121         DeleteObject(hBitmapMask);
122 
123     /*
124      * Return the newly created tray icon (if successful)
125      */
126     return hTrayIcon;
127 }
128 
129 BOOL TrayIcon_ShellAddTrayIcon(void)
130 {
131     NOTIFYICONDATAW nid;
132     HICON           hIcon = NULL;
133     BOOL            bRetVal;
134     WCHAR           szMsg[64];
135 
136     memset(&nid, 0, sizeof(NOTIFYICONDATAW));
137 
138     hIcon = TrayIcon_GetProcessorUsageIcon();
139 
140     nid.cbSize = sizeof(NOTIFYICONDATAW);
141     nid.hWnd = hMainWnd;
142     nid.uID = 0;
143     nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
144     nid.uCallbackMessage = WM_ONTRAYICON;
145     nid.hIcon = hIcon;
146 
147 
148     LoadStringW( GetModuleHandleW(NULL), IDS_MSG_TRAYICONCPUUSAGE, szMsg, sizeof(szMsg) / sizeof(szMsg[0]));
149     wsprintfW(nid.szTip, szMsg, PerfDataGetProcessorUsage());
150 
151     bRetVal = Shell_NotifyIconW(NIM_ADD, &nid);
152 
153     if (hIcon)
154         DestroyIcon(hIcon);
155 
156     return bRetVal;
157 }
158 
159 BOOL TrayIcon_ShellRemoveTrayIcon(void)
160 {
161     NOTIFYICONDATAW nid;
162     BOOL            bRetVal;
163 
164     memset(&nid, 0, sizeof(NOTIFYICONDATAW));
165 
166     nid.cbSize = sizeof(NOTIFYICONDATAW);
167     nid.hWnd = hMainWnd;
168     nid.uID = 0;
169     nid.uFlags = 0;
170     nid.uCallbackMessage = WM_ONTRAYICON;
171 
172     bRetVal = Shell_NotifyIconW(NIM_DELETE, &nid);
173 
174     return bRetVal;
175 }
176 
177 BOOL TrayIcon_ShellUpdateTrayIcon(void)
178 {
179     NOTIFYICONDATAW nid;
180     HICON           hIcon = NULL;
181     BOOL            bRetVal;
182     WCHAR           szTemp[64];
183 
184     memset(&nid, 0, sizeof(NOTIFYICONDATAW));
185 
186     hIcon = TrayIcon_GetProcessorUsageIcon();
187 
188     nid.cbSize = sizeof(NOTIFYICONDATAW);
189     nid.hWnd = hMainWnd;
190     nid.uID = 0;
191     nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
192     nid.uCallbackMessage = WM_ONTRAYICON;
193     nid.hIcon = hIcon;
194     LoadStringW(hInst, IDS_MSG_TRAYICONCPUUSAGE, szTemp, sizeof(szTemp)/sizeof(szTemp[0]));
195     wsprintfW(nid.szTip, szTemp, PerfDataGetProcessorUsage());
196 
197     bRetVal = Shell_NotifyIconW(NIM_MODIFY, &nid);
198 
199     if (hIcon)
200         DestroyIcon(hIcon);
201 
202     return bRetVal;
203 }
204