1 /* 2 * PROJECT: ReactOS Task Manager 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Tray Icon. 5 * COPYRIGHT: Copyright 1999-2001 Brian Palmer <brianp@reactos.org> 6 * Copyright 2005 Klemens Friedl <frik85@reactos.at> 7 */ 8 9 #include "precomp.h" 10 11 static HICON 12 TrayIcon_GetProcessorUsageIcon( 13 _In_ ULONG CpuUsage) 14 { 15 HICON hTrayIcon = NULL; 16 HDC hScreenDC = NULL; 17 HDC hDC = NULL; 18 HBITMAP hBitmap = NULL; 19 HBITMAP hOldBitmap = NULL; 20 HBITMAP hBitmapMask = NULL; 21 ICONINFO iconInfo; 22 int nLinesToDraw; 23 HBRUSH hBitmapBrush = NULL; 24 RECT rc; 25 26 /* Get a handle to the screen DC */ 27 hScreenDC = GetDC(NULL); 28 if (!hScreenDC) 29 goto done; 30 31 /* Create our own DC from it */ 32 hDC = CreateCompatibleDC(hScreenDC); 33 if (!hDC) 34 goto done; 35 36 /* 37 * Load the bitmaps 38 */ 39 hBitmap = LoadBitmapW(hInst, MAKEINTRESOURCEW(IDB_TRAYICON)); 40 hBitmapMask = LoadBitmapW(hInst, MAKEINTRESOURCEW(IDB_TRAYMASK)); 41 if (!hBitmap || !hBitmapMask) 42 goto done; 43 44 hBitmapBrush = CreateSolidBrush(RGB(0, 255, 0)); 45 if (!hBitmapBrush) 46 goto done; 47 48 /* 49 * Select the bitmap into our device context 50 * so we can draw on it. 51 */ 52 hOldBitmap = SelectObject(hDC, hBitmap); 53 54 /* 55 * Calculate how many lines to draw 56 * since we have 11 rows of space 57 * to draw the cpu usage instead of 58 * just having 10. 59 */ 60 nLinesToDraw = (CpuUsage + (CpuUsage / 10)) / 11; 61 rc.left = 3; 62 rc.top = 12 - nLinesToDraw; 63 rc.right = 13; 64 rc.bottom = 13; 65 66 /* Now draw the cpu usage */ 67 if (nLinesToDraw) 68 FillRect(hDC, &rc, hBitmapBrush); 69 70 /* 71 * Now that we are done drawing put the 72 * old bitmap back. 73 */ 74 hBitmap = SelectObject(hDC, hOldBitmap); 75 hOldBitmap = NULL; 76 77 iconInfo.fIcon = TRUE; 78 iconInfo.hbmMask = hBitmapMask; 79 iconInfo.hbmColor = hBitmap; 80 81 hTrayIcon = CreateIconIndirect(&iconInfo); 82 83 done: 84 /* 85 * Cleanup 86 */ 87 if (hScreenDC) 88 ReleaseDC(NULL, hScreenDC); 89 if (hDC) 90 DeleteDC(hDC); 91 if (hBitmapBrush) 92 DeleteObject(hBitmapBrush); 93 if (hBitmap) 94 DeleteObject(hBitmap); 95 if (hBitmapMask) 96 DeleteObject(hBitmapMask); 97 98 /* Return the newly created tray icon (if successful) */ 99 return hTrayIcon; 100 } 101 102 static BOOL 103 TrayIcon_Update( 104 _In_ DWORD dwMessage) 105 { 106 static WCHAR szMsg[64] = L""; 107 108 NOTIFYICONDATAW nid; 109 ULONG CpuUsage; 110 HICON hIcon = NULL; 111 BOOL bRetVal; 112 113 if (!*szMsg) 114 LoadStringW(hInst, IDS_MSG_TRAYICONCPUUSAGE, szMsg, _countof(szMsg)); 115 116 ZeroMemory(&nid, sizeof(nid)); 117 118 CpuUsage = PerfDataGetProcessorUsage(); 119 hIcon = TrayIcon_GetProcessorUsageIcon(CpuUsage); 120 121 nid.cbSize = sizeof(nid); 122 nid.hWnd = hMainWnd; 123 nid.uID = 0; 124 nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; 125 nid.uCallbackMessage = WM_ONTRAYICON; 126 nid.hIcon = hIcon; 127 128 StringCchPrintfW(nid.szTip, _countof(nid.szTip), szMsg, CpuUsage); 129 130 bRetVal = Shell_NotifyIconW(dwMessage, &nid); 131 132 if (hIcon) 133 DestroyIcon(hIcon); 134 135 return bRetVal; 136 } 137 138 BOOL TrayIcon_AddIcon(VOID) 139 { 140 return TrayIcon_Update(NIM_ADD); 141 } 142 143 BOOL TrayIcon_RemoveIcon(VOID) 144 { 145 NOTIFYICONDATAW nid; 146 147 ZeroMemory(&nid, sizeof(nid)); 148 149 nid.cbSize = sizeof(nid); 150 nid.hWnd = hMainWnd; 151 nid.uID = 0; 152 nid.uFlags = 0; 153 nid.uCallbackMessage = WM_ONTRAYICON; 154 155 return Shell_NotifyIconW(NIM_DELETE, &nid); 156 } 157 158 BOOL TrayIcon_UpdateIcon(VOID) 159 { 160 return TrayIcon_Update(NIM_MODIFY); 161 } 162