d3dx9: Override d3dx9_get_param_value_ptr() return value only on array overflow.
[wine.git] / programs / taskmgr / taskmgr.c
blobb280f7975d3ee03b5bc2245b292ea220700c4d68
1 /*
2 * ReactOS Task Manager
4 * taskmgr.c : Defines the entry point for the application.
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7 * Copyright (C) 2008 Vladimir Pankratov
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.
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.
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 St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <stdio.h>
25 #include <stdlib.h>
27 #include <windows.h>
28 #include <commctrl.h>
29 #include <winnt.h>
31 #include "wine/unicode.h"
32 #include "resource.h"
33 #include "taskmgr.h"
34 #include "perfdata.h"
35 #include "column.h"
37 #define STATUS_WINDOW 2001
39 /* Global Variables: */
40 HINSTANCE hInst; /* current instance */
42 HWND hMainWnd; /* Main Window */
43 HWND hStatusWnd; /* Status Bar Window */
44 HWND hTabWnd; /* Tab Control Window */
46 int nMinimumWidth; /* Minimum width of the dialog (OnSize()'s cx) */
47 int nMinimumHeight; /* Minimum height of the dialog (OnSize()'s cy) */
49 int nOldWidth; /* Holds the previous client area width */
50 int nOldHeight; /* Holds the previous client area height */
52 BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
54 TASKMANAGER_SETTINGS TaskManagerSettings;
57 void FillSolidRect(HDC hDC, LPCRECT lpRect, COLORREF clr)
59 SetBkColor(hDC, clr);
60 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
63 static void FillSolidRect2(HDC hDC, int x, int y, int cx, int cy, COLORREF clr)
65 RECT rect;
67 SetBkColor(hDC, clr);
68 SetRect(&rect, x, y, x + cx, y + cy);
69 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
72 static void Draw3dRect(HDC hDC, int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight)
74 FillSolidRect2(hDC, x, y, cx - 1, 1, clrTopLeft);
75 FillSolidRect2(hDC, x, y, 1, cy - 1, clrTopLeft);
76 FillSolidRect2(hDC, x + cx, y, -1, cy, clrBottomRight);
77 FillSolidRect2(hDC, x, y + cy, cx, -1, clrBottomRight);
80 void Font_DrawText(HDC hDC, LPWSTR lpwszText, int x, int y)
82 HDC hFontDC;
83 HBITMAP hFontBitmap;
84 HBITMAP hOldBitmap;
85 int i;
87 hFontDC = CreateCompatibleDC(hDC);
88 hFontBitmap = LoadBitmapW(hInst, MAKEINTRESOURCEW(IDB_FONT));
89 hOldBitmap = SelectObject(hFontDC, hFontBitmap);
91 for (i = 0; lpwszText[i]; i++) {
92 if ((lpwszText[i] >= '0') && (lpwszText[i] <= '9')) {
93 BitBlt(hDC, x + (i * 8), y, 8, 11, hFontDC, (lpwszText[i] - '0') * 8, 0, SRCCOPY);
95 else if (lpwszText[i] == 'K')
97 BitBlt(hDC, x + (i * 8), y, 8, 11, hFontDC, 80, 0, SRCCOPY);
99 else if (lpwszText[i] == '%')
101 BitBlt(hDC, x + (i * 8), y, 8, 11, hFontDC, 88, 0, SRCCOPY);
104 SelectObject(hFontDC, hOldBitmap);
105 DeleteObject(hFontBitmap);
106 DeleteDC(hFontDC);
109 static BOOL OnCreate(HWND hWnd)
111 HMENU hMenu;
112 HMENU hEditMenu;
113 HMENU hViewMenu;
114 HMENU hUpdateSpeedMenu;
115 HMENU hCPUHistoryMenu;
116 int nActivePage;
117 int nParts[3];
118 RECT rc;
119 TCITEMW item;
121 static WCHAR wszApplications[255];
122 static WCHAR wszProcesses[255];
123 static WCHAR wszPerformance[255];
125 LoadStringW(hInst, IDS_APPLICATIONS, wszApplications, sizeof(wszApplications)/sizeof(WCHAR));
126 LoadStringW(hInst, IDS_PROCESSES, wszProcesses, sizeof(wszProcesses)/sizeof(WCHAR));
127 LoadStringW(hInst, IDS_PERFORMANCE, wszPerformance, sizeof(wszPerformance)/sizeof(WCHAR));
129 SendMessageW(hMainWnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW(hInst, MAKEINTRESOURCEW(IDI_TASKMANAGER)));
130 SendMessageW(hMainWnd, WM_SETICON, ICON_SMALL,
131 (LPARAM)LoadImageW(hInst, MAKEINTRESOURCEW(IDI_TASKMANAGER), IMAGE_ICON,
132 GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
133 LR_SHARED));
135 /* Initialize the Windows Common Controls DLL */
136 InitCommonControls();
138 /* Get the minimum window sizes */
139 GetWindowRect(hWnd, &rc);
140 nMinimumWidth = (rc.right - rc.left);
141 nMinimumHeight = (rc.bottom - rc.top);
143 /* Create the status bar */
144 hStatusWnd = CreateStatusWindowW(WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|SBT_NOBORDERS, NULL, hWnd, STATUS_WINDOW);
145 if(!hStatusWnd)
146 return FALSE;
148 /* Create the status bar panes */
149 nParts[0] = 100;
150 nParts[1] = 210;
151 nParts[2] = 400;
152 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM)nParts);
154 /* Create tab pages */
155 hTabWnd = GetDlgItem(hWnd, IDC_TAB);
156 #if 1
157 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hWnd, ApplicationPageWndProc);
158 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hWnd, ProcessPageWndProc);
159 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hWnd, PerformancePageWndProc);
160 #else
161 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hTabWnd, ApplicationPageWndProc);
162 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hTabWnd, ProcessPageWndProc);
163 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hTabWnd, PerformancePageWndProc);
164 #endif
166 /* Insert tabs */
167 memset(&item, 0, sizeof(TCITEMW));
168 item.mask = TCIF_TEXT;
169 item.pszText = wszApplications;
170 SendMessageW(hTabWnd, TCM_INSERTITEMW, 0, (LPARAM)&item);
171 memset(&item, 0, sizeof(TCITEMW));
172 item.mask = TCIF_TEXT;
173 item.pszText = wszProcesses;
174 SendMessageW(hTabWnd, TCM_INSERTITEMW, 1, (LPARAM)&item);
175 memset(&item, 0, sizeof(TCITEMW));
176 item.mask = TCIF_TEXT;
177 item.pszText = wszPerformance;
178 SendMessageW(hTabWnd, TCM_INSERTITEMW, 2, (LPARAM)&item);
180 /* Size everything correctly */
181 GetClientRect(hWnd, &rc);
182 nOldWidth = rc.right;
183 nOldHeight = rc.bottom;
185 if ((TaskManagerSettings.Left != 0) ||
186 (TaskManagerSettings.Top != 0) ||
187 (TaskManagerSettings.Right != 0) ||
188 (TaskManagerSettings.Bottom != 0))
189 MoveWindow(hWnd, TaskManagerSettings.Left, TaskManagerSettings.Top, TaskManagerSettings.Right - TaskManagerSettings.Left, TaskManagerSettings.Bottom - TaskManagerSettings.Top, TRUE);
191 if (TaskManagerSettings.Maximized)
192 ShowWindow(hWnd, SW_MAXIMIZE);
194 /* Set the always on top style */
195 hMenu = GetMenu(hWnd);
196 hEditMenu = GetSubMenu(hMenu, 1);
197 hViewMenu = GetSubMenu(hMenu, 2);
198 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
199 hCPUHistoryMenu = GetSubMenu(hViewMenu, 7);
201 /* Check or uncheck the always on top menu item */
202 if (TaskManagerSettings.AlwaysOnTop) {
203 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_CHECKED);
204 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
205 } else {
206 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_UNCHECKED);
207 SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
210 /* Check or uncheck the minimize on use menu item */
211 if (TaskManagerSettings.MinimizeOnUse)
212 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_CHECKED);
213 else
214 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_UNCHECKED);
216 /* Check or uncheck the hide when minimized menu item */
217 if (TaskManagerSettings.HideWhenMinimized)
218 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_CHECKED);
219 else
220 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_UNCHECKED);
222 /* Check or uncheck the show 16-bit tasks menu item */
223 if (TaskManagerSettings.Show16BitTasks)
224 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED);
225 else
226 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_UNCHECKED);
228 if (TaskManagerSettings.View_LargeIcons)
229 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
230 else if (TaskManagerSettings.View_SmallIcons)
231 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
232 else
233 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
235 if (TaskManagerSettings.ShowKernelTimes)
236 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
237 else
238 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
240 if (TaskManagerSettings.UpdateSpeed == 1)
241 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_HIGH, MF_BYCOMMAND);
242 else if (TaskManagerSettings.UpdateSpeed == 2)
243 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_NORMAL, MF_BYCOMMAND);
244 else if (TaskManagerSettings.UpdateSpeed == 4)
245 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_LOW, MF_BYCOMMAND);
246 else
247 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_PAUSED, MF_BYCOMMAND);
249 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
250 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
251 else
252 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
254 nActivePage = TaskManagerSettings.ActiveTabPage;
255 SendMessageW(hTabWnd, TCM_SETCURFOCUS, 0, 0);
256 SendMessageW(hTabWnd, TCM_SETCURFOCUS, 1, 0);
257 SendMessageW(hTabWnd, TCM_SETCURFOCUS, 2, 0);
258 SendMessageW(hTabWnd, TCM_SETCURFOCUS, nActivePage, 0);
260 if (TaskManagerSettings.UpdateSpeed == 1)
261 SetTimer(hWnd, 1, 1000, NULL);
262 else if (TaskManagerSettings.UpdateSpeed == 2)
263 SetTimer(hWnd, 1, 2000, NULL);
264 else if (TaskManagerSettings.UpdateSpeed == 4)
265 SetTimer(hWnd, 1, 4000, NULL);
268 * Refresh the performance data
269 * Sample it twice so we can establish
270 * the delta values & cpu usage
272 PerfDataRefresh();
273 PerfDataRefresh();
275 RefreshApplicationPage();
276 RefreshProcessPage();
277 RefreshPerformancePage();
279 TrayIcon_ShellAddTrayIcon();
281 return TRUE;
284 /* OnSize()
285 * This function handles all the sizing events for the application
286 * It re-sizes every window, and child window that needs re-sizing
288 static void OnSize( UINT nType, int cx, int cy )
290 int nParts[3];
291 int nXDifference;
292 int nYDifference;
293 RECT rc;
295 if (nType == SIZE_MINIMIZED)
297 if(TaskManagerSettings.HideWhenMinimized)
299 ShowWindow(hMainWnd, SW_HIDE);
301 return;
304 nXDifference = cx - nOldWidth;
305 nYDifference = cy - nOldHeight;
306 nOldWidth = cx;
307 nOldHeight = cy;
309 /* Update the status bar size */
310 GetWindowRect(hStatusWnd, &rc);
311 SendMessageW(hStatusWnd, WM_SIZE, nType, MAKELPARAM(cx, cy + (rc.bottom - rc.top)));
313 /* Update the status bar pane sizes */
314 nParts[0] = bInMenuLoop ? -1 : 100;
315 nParts[1] = 210;
316 nParts[2] = cx;
317 SendMessageW(hStatusWnd, SB_SETPARTS, bInMenuLoop ? 1 : 3, (LPARAM)nParts);
319 /* Resize the tab control */
320 GetWindowRect(hTabWnd, &rc);
321 cx = (rc.right - rc.left) + nXDifference;
322 cy = (rc.bottom - rc.top) + nYDifference;
323 SetWindowPos(hTabWnd, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
325 /* Resize the application page */
326 GetWindowRect(hApplicationPage, &rc);
327 cx = (rc.right - rc.left) + nXDifference;
328 cy = (rc.bottom - rc.top) + nYDifference;
329 SetWindowPos(hApplicationPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
331 /* Resize the process page */
332 GetWindowRect(hProcessPage, &rc);
333 cx = (rc.right - rc.left) + nXDifference;
334 cy = (rc.bottom - rc.top) + nYDifference;
335 SetWindowPos(hProcessPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
337 /* Resize the performance page */
338 GetWindowRect(hPerformancePage, &rc);
339 cx = (rc.right - rc.left) + nXDifference;
340 cy = (rc.bottom - rc.top) + nYDifference;
341 SetWindowPos(hPerformancePage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
344 static void LoadSettings(void)
346 HKEY hKey;
347 int i;
348 DWORD dwSize;
350 static const WCHAR wszSubKey[] = {'S','o','f','t','w','a','r','e','\\',
351 'W','i','n','e','\\','T','a','s','k','M','a','n','a','g','e','r',0};
352 static const WCHAR wszPreferences[] = {'P','r','e','f','e','r','e','n','c','e','s',0};
354 /* Window size & position settings */
355 TaskManagerSettings.Maximized = FALSE;
356 TaskManagerSettings.Left = 0;
357 TaskManagerSettings.Top = 0;
358 TaskManagerSettings.Right = 0;
359 TaskManagerSettings.Bottom = 0;
361 /* Tab settings */
362 TaskManagerSettings.ActiveTabPage = 0;
364 /* Options menu settings */
365 TaskManagerSettings.AlwaysOnTop = FALSE;
366 TaskManagerSettings.MinimizeOnUse = TRUE;
367 TaskManagerSettings.HideWhenMinimized = TRUE;
368 TaskManagerSettings.Show16BitTasks = TRUE;
370 /* Update speed settings */
371 TaskManagerSettings.UpdateSpeed = 2;
373 /* Applications page settings */
374 TaskManagerSettings.View_LargeIcons = FALSE;
375 TaskManagerSettings.View_SmallIcons = FALSE;
376 TaskManagerSettings.View_Details = TRUE;
378 /* Processes page settings */
379 TaskManagerSettings.ShowProcessesFromAllUsers = FALSE; /* Server-only? */
380 TaskManagerSettings.Column_ImageName = TRUE;
381 TaskManagerSettings.Column_PID = TRUE;
382 TaskManagerSettings.Column_CPUUsage = TRUE;
383 TaskManagerSettings.Column_CPUTime = TRUE;
384 TaskManagerSettings.Column_MemoryUsage = TRUE;
385 TaskManagerSettings.Column_MemoryUsageDelta = FALSE;
386 TaskManagerSettings.Column_PeakMemoryUsage = FALSE;
387 TaskManagerSettings.Column_PageFaults = FALSE;
388 TaskManagerSettings.Column_USERObjects = FALSE;
389 TaskManagerSettings.Column_IOReads = FALSE;
390 TaskManagerSettings.Column_IOReadBytes = FALSE;
391 TaskManagerSettings.Column_SessionID = FALSE; /* Server-only? */
392 TaskManagerSettings.Column_UserName = FALSE; /* Server-only? */
393 TaskManagerSettings.Column_PageFaultsDelta = FALSE;
394 TaskManagerSettings.Column_VirtualMemorySize = FALSE;
395 TaskManagerSettings.Column_PagedPool = FALSE;
396 TaskManagerSettings.Column_NonPagedPool = FALSE;
397 TaskManagerSettings.Column_BasePriority = FALSE;
398 TaskManagerSettings.Column_HandleCount = FALSE;
399 TaskManagerSettings.Column_ThreadCount = FALSE;
400 TaskManagerSettings.Column_GDIObjects = FALSE;
401 TaskManagerSettings.Column_IOWrites = FALSE;
402 TaskManagerSettings.Column_IOWriteBytes = FALSE;
403 TaskManagerSettings.Column_IOOther = FALSE;
404 TaskManagerSettings.Column_IOOtherBytes = FALSE;
406 for (i = 0; i < 25; i++) {
407 TaskManagerSettings.ColumnOrderArray[i] = i;
409 TaskManagerSettings.ColumnSizeArray[0] = 105;
410 TaskManagerSettings.ColumnSizeArray[1] = 50;
411 TaskManagerSettings.ColumnSizeArray[2] = 107;
412 TaskManagerSettings.ColumnSizeArray[3] = 70;
413 TaskManagerSettings.ColumnSizeArray[4] = 35;
414 TaskManagerSettings.ColumnSizeArray[5] = 70;
415 TaskManagerSettings.ColumnSizeArray[6] = 70;
416 TaskManagerSettings.ColumnSizeArray[7] = 100;
417 TaskManagerSettings.ColumnSizeArray[8] = 70;
418 TaskManagerSettings.ColumnSizeArray[9] = 70;
419 TaskManagerSettings.ColumnSizeArray[10] = 70;
420 TaskManagerSettings.ColumnSizeArray[11] = 70;
421 TaskManagerSettings.ColumnSizeArray[12] = 70;
422 TaskManagerSettings.ColumnSizeArray[13] = 70;
423 TaskManagerSettings.ColumnSizeArray[14] = 60;
424 TaskManagerSettings.ColumnSizeArray[15] = 60;
425 TaskManagerSettings.ColumnSizeArray[16] = 60;
426 TaskManagerSettings.ColumnSizeArray[17] = 60;
427 TaskManagerSettings.ColumnSizeArray[18] = 60;
428 TaskManagerSettings.ColumnSizeArray[19] = 70;
429 TaskManagerSettings.ColumnSizeArray[20] = 70;
430 TaskManagerSettings.ColumnSizeArray[21] = 70;
431 TaskManagerSettings.ColumnSizeArray[22] = 70;
432 TaskManagerSettings.ColumnSizeArray[23] = 70;
433 TaskManagerSettings.ColumnSizeArray[24] = 70;
435 TaskManagerSettings.SortColumn = 1;
436 TaskManagerSettings.SortAscending = TRUE;
438 /* Performance page settings */
439 TaskManagerSettings.CPUHistory_OneGraphPerCPU = TRUE;
440 TaskManagerSettings.ShowKernelTimes = FALSE;
442 /* Open the key */
443 /* @@ Wine registry key: HKCU\Software\Wine\TaskManager */
444 if (RegOpenKeyExW(HKEY_CURRENT_USER, wszSubKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
445 return;
446 /* Read the settings */
447 dwSize = sizeof(TASKMANAGER_SETTINGS);
448 RegQueryValueExW(hKey, wszPreferences, NULL, NULL, (LPBYTE)&TaskManagerSettings, &dwSize);
450 /* Close the key */
451 RegCloseKey(hKey);
454 static void SaveSettings(void)
456 HKEY hKey;
458 static const WCHAR wszSubKey3[] = {'S','o','f','t','w','a','r','e','\\',
459 'W','i','n','e','\\','T','a','s','k','M','a','n','a','g','e','r',0};
460 static const WCHAR wszPreferences[] = {'P','r','e','f','e','r','e','n','c','e','s',0};
462 /* Open (or create) the key */
464 /* @@ Wine registry key: HKCU\Software\Wine\TaskManager */
465 if (RegCreateKeyExW(HKEY_CURRENT_USER, wszSubKey3, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
466 return;
467 /* Save the settings */
468 RegSetValueExW(hKey, wszPreferences, 0, REG_BINARY, (LPBYTE)&TaskManagerSettings, sizeof(TASKMANAGER_SETTINGS));
469 /* Close the key */
470 RegCloseKey(hKey);
473 static void TaskManager_OnRestoreMainWindow(void)
475 BOOL OnTop;
477 OnTop = (GetWindowLongW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
479 OpenIcon(hMainWnd);
480 SetForegroundWindow(hMainWnd);
481 SetWindowPos(hMainWnd, (OnTop ? HWND_TOPMOST : HWND_TOP), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
484 static void TaskManager_OnEnterMenuLoop(HWND hWnd)
486 int nParts;
488 /* Update the status bar pane sizes */
489 nParts = -1;
490 SendMessageW(hStatusWnd, SB_SETPARTS, 1, (LPARAM)&nParts);
491 bInMenuLoop = TRUE;
492 SendMessageW(hStatusWnd, SB_SETTEXTW, 0, 0);
495 static void TaskManager_OnExitMenuLoop(HWND hWnd)
497 RECT rc;
498 int nParts[3];
499 WCHAR text[256];
501 WCHAR wszCPU_Usage[255];
502 WCHAR wszProcesses[255];
504 LoadStringW(hInst, IDS_STATUS_BAR_CPU_USAGE, wszCPU_Usage, sizeof(wszCPU_Usage)/sizeof(WCHAR));
505 LoadStringW(hInst, IDS_STATUS_BAR_PROCESSES, wszProcesses, sizeof(wszProcesses)/sizeof(WCHAR));
507 bInMenuLoop = FALSE;
508 /* Update the status bar pane sizes */
509 GetClientRect(hWnd, &rc);
510 nParts[0] = 100;
511 nParts[1] = 210;
512 nParts[2] = rc.right;
513 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM)nParts);
514 SendMessageW(hStatusWnd, SB_SETTEXTW, 0, 0);
515 wsprintfW(text, wszCPU_Usage, PerfDataGetProcessorUsage());
516 SendMessageW(hStatusWnd, SB_SETTEXTW, 1, (LPARAM)text);
517 wsprintfW(text, wszProcesses, PerfDataGetProcessCount());
518 SendMessageW(hStatusWnd, SB_SETTEXTW, 0, (LPARAM)text);
521 static void TaskManager_OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
523 WCHAR wstr[256] = {0};
525 LoadStringW(hInst, nItemID, wstr, sizeof(wstr)/sizeof(WCHAR));
526 SendMessageW(hStatusWnd, SB_SETTEXTW, 0, (LPARAM)wstr);
529 static void TaskManager_OnViewUpdateSpeedHigh(void)
531 HMENU hMenu;
532 HMENU hViewMenu;
533 HMENU hUpdateSpeedMenu;
535 hMenu = GetMenu(hMainWnd);
536 hViewMenu = GetSubMenu(hMenu, 2);
537 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
539 TaskManagerSettings.UpdateSpeed = 1;
540 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_HIGH, MF_BYCOMMAND);
542 KillTimer(hMainWnd, 1);
543 SetTimer(hMainWnd, 1, 1000, NULL);
546 static void TaskManager_OnViewUpdateSpeedNormal(void)
548 HMENU hMenu;
549 HMENU hViewMenu;
550 HMENU hUpdateSpeedMenu;
552 hMenu = GetMenu(hMainWnd);
553 hViewMenu = GetSubMenu(hMenu, 2);
554 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
556 TaskManagerSettings.UpdateSpeed = 2;
557 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_NORMAL, MF_BYCOMMAND);
559 KillTimer(hMainWnd, 1);
560 SetTimer(hMainWnd, 1, 2000, NULL);
563 static void TaskManager_OnViewUpdateSpeedLow(void)
565 HMENU hMenu;
566 HMENU hViewMenu;
567 HMENU hUpdateSpeedMenu;
569 hMenu = GetMenu(hMainWnd);
570 hViewMenu = GetSubMenu(hMenu, 2);
571 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
573 TaskManagerSettings.UpdateSpeed = 4;
574 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_LOW, MF_BYCOMMAND);
576 KillTimer(hMainWnd, 1);
577 SetTimer(hMainWnd, 1, 4000, NULL);
580 static void TaskManager_OnViewUpdateSpeedPaused(void)
582 HMENU hMenu;
583 HMENU hViewMenu;
584 HMENU hUpdateSpeedMenu;
586 hMenu = GetMenu(hMainWnd);
587 hViewMenu = GetSubMenu(hMenu, 2);
588 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
589 TaskManagerSettings.UpdateSpeed = 0;
590 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, ID_VIEW_UPDATESPEED_PAUSED, MF_BYCOMMAND);
591 KillTimer(hMainWnd, 1);
594 static void TaskManager_OnTabWndSelChange(void)
596 int i;
597 HMENU hMenu;
598 HMENU hOptionsMenu;
599 HMENU hViewMenu;
600 HMENU hSubMenu;
602 WCHAR wszLargeIcons[255];
603 WCHAR wszSmallIcons[255];
604 WCHAR wszDetails[255];
605 WCHAR wszWindows[255];
606 WCHAR wszSelectColumns[255];
607 WCHAR wszShow16bTasks[255];
608 WCHAR wszOneGraphAllCPU[255];
609 WCHAR wszOneGraphPerCPU[255];
610 WCHAR wszCPUHistory[255];
611 WCHAR wszShowKernelTimes[255];
613 LoadStringW(hInst, IDS_VIEW_LARGE, wszLargeIcons, sizeof(wszLargeIcons)/sizeof(WCHAR));
614 LoadStringW(hInst, IDS_VIEW_SMALL, wszSmallIcons, sizeof(wszSmallIcons)/sizeof(WCHAR));
615 LoadStringW(hInst, IDS_VIEW_DETAILS, wszDetails, sizeof(wszDetails)/sizeof(WCHAR));
616 LoadStringW(hInst, IDS_WINDOWS, wszWindows, sizeof(wszWindows)/sizeof(WCHAR));
617 LoadStringW(hInst, IDS_VIEW_SELECTCOLUMNS, wszSelectColumns, sizeof(wszSelectColumns)/sizeof(WCHAR));
618 LoadStringW(hInst, IDS_OPTIONS_SHOW16BITTASKS, wszShow16bTasks, sizeof(wszShow16bTasks)/sizeof(WCHAR));
619 LoadStringW(hInst, IDS_VIEW_CPUHISTORY_ONEGRAPHALL, wszOneGraphAllCPU, sizeof(wszOneGraphAllCPU)/sizeof(WCHAR));
620 LoadStringW(hInst, IDS_VIEW_CPUHISTORY_ONEGRAPHPERCPU, wszOneGraphPerCPU, sizeof(wszOneGraphPerCPU)/sizeof(WCHAR));
621 LoadStringW(hInst, IDS_VIEW_CPUHISTORY, wszCPUHistory, sizeof(wszCPUHistory)/sizeof(WCHAR));
622 LoadStringW(hInst, IDS_VIEW_SHOWKERNELTIMES, wszShowKernelTimes, sizeof(wszShowKernelTimes)/sizeof(WCHAR));
624 hMenu = GetMenu(hMainWnd);
625 hViewMenu = GetSubMenu(hMenu, 2);
626 hOptionsMenu = GetSubMenu(hMenu, 1);
627 TaskManagerSettings.ActiveTabPage = SendMessageW(hTabWnd, TCM_GETCURSEL, 0, 0);
628 for (i = GetMenuItemCount(hViewMenu) - 1; i > 2; i--) {
629 hSubMenu = GetSubMenu(hViewMenu, i);
630 if (hSubMenu)
631 DestroyMenu(hSubMenu);
632 RemoveMenu(hViewMenu, i, MF_BYPOSITION);
634 RemoveMenu(hOptionsMenu, 3, MF_BYPOSITION);
635 switch (TaskManagerSettings.ActiveTabPage) {
636 case 0:
637 ShowWindow(hApplicationPage, SW_SHOW);
638 ShowWindow(hProcessPage, SW_HIDE);
639 ShowWindow(hPerformancePage, SW_HIDE);
640 BringWindowToTop(hApplicationPage);
641 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_LARGE, wszLargeIcons);
642 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SMALL, wszSmallIcons);
643 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_DETAILS, wszDetails);
645 if (GetMenuItemCount(hMenu) <= 4) {
646 hSubMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_WINDOWSMENU));
647 InsertMenuW(hMenu, 3, MF_BYPOSITION|MF_POPUP, (UINT_PTR)hSubMenu, wszWindows);
648 DrawMenuBar(hMainWnd);
650 if (TaskManagerSettings.View_LargeIcons)
651 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_LARGE, MF_BYCOMMAND);
652 else if (TaskManagerSettings.View_SmallIcons)
653 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_SMALL, MF_BYCOMMAND);
654 else
655 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, ID_VIEW_DETAILS, MF_BYCOMMAND);
657 * Give the application list control focus
659 SetFocus(hApplicationPageListCtrl);
660 break;
662 case 1:
663 ShowWindow(hApplicationPage, SW_HIDE);
664 ShowWindow(hProcessPage, SW_SHOW);
665 ShowWindow(hPerformancePage, SW_HIDE);
666 BringWindowToTop(hProcessPage);
667 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SELECTCOLUMNS, wszSelectColumns);
668 AppendMenuW(hOptionsMenu, MF_STRING, ID_OPTIONS_SHOW16BITTASKS, wszShow16bTasks);
669 if (TaskManagerSettings.Show16BitTasks)
670 CheckMenuItem(hOptionsMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED);
671 if (GetMenuItemCount(hMenu) > 4)
673 RemoveMenu(hMenu, 3, MF_BYPOSITION);
674 DrawMenuBar(hMainWnd);
677 * Give the process list control focus
679 SetFocus(hProcessPageListCtrl);
680 break;
682 case 2:
683 ShowWindow(hApplicationPage, SW_HIDE);
684 ShowWindow(hProcessPage, SW_HIDE);
685 ShowWindow(hPerformancePage, SW_SHOW);
686 BringWindowToTop(hPerformancePage);
687 if (GetMenuItemCount(hMenu) > 4) {
688 RemoveMenu(hMenu, 3, MF_BYPOSITION);
689 DrawMenuBar(hMainWnd);
691 hSubMenu = CreatePopupMenu();
692 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, wszOneGraphAllCPU);
693 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, wszOneGraphPerCPU);
694 AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR)hSubMenu, wszCPUHistory);
695 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, wszShowKernelTimes);
696 if (TaskManagerSettings.ShowKernelTimes)
697 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
698 else
699 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
700 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
701 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
702 else
703 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
705 * Give the tab control focus
707 SetFocus(hTabWnd);
708 break;
712 LPWSTR GetLastErrorText(LPWSTR lpwszBuf, DWORD dwSize)
714 DWORD dwRet;
715 LPWSTR lpwszTemp = NULL;
716 static const WCHAR wszFormat[] = {'%','s',' ','(','%','u',')',0};
718 dwRet = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
719 NULL,
720 GetLastError(),
721 LANG_NEUTRAL,
722 (LPWSTR)&lpwszTemp,
724 NULL );
726 /* supplied buffer is not long enough */
727 if (!dwRet || ( dwSize < dwRet+14)) {
728 lpwszBuf[0] = '\0';
729 } else {
730 lpwszTemp[strlenW(lpwszTemp)-2] = '\0'; /* remove cr and newline character */
731 sprintfW(lpwszBuf, wszFormat, lpwszTemp, GetLastError());
733 if (lpwszTemp) {
734 LocalFree(lpwszTemp);
736 return lpwszBuf;
739 /* Message handler for dialog box. */
740 static INT_PTR CALLBACK
741 TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
743 static const WCHAR wszTaskmgr[] = {'t','a','s','k','m','g','r',0};
744 HDC hdc;
745 PAINTSTRUCT ps;
746 LPRECT pRC;
747 RECT rc;
748 LPNMHDR pnmh;
749 WINDOWPLACEMENT wp;
751 switch (message) {
752 case WM_INITDIALOG:
753 hMainWnd = hDlg;
754 return OnCreate(hDlg);
756 case WM_COMMAND:
757 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
758 EndDialog(hDlg, LOWORD(wParam));
759 return TRUE;
761 /* Process menu commands */
762 switch (LOWORD(wParam))
764 case ID_FILE_NEW:
765 TaskManager_OnFileNew();
766 break;
767 case ID_OPTIONS_ALWAYSONTOP:
768 TaskManager_OnOptionsAlwaysOnTop();
769 break;
770 case ID_OPTIONS_MINIMIZEONUSE:
771 TaskManager_OnOptionsMinimizeOnUse();
772 break;
773 case ID_OPTIONS_HIDEWHENMINIMIZED:
774 TaskManager_OnOptionsHideWhenMinimized();
775 break;
776 case ID_OPTIONS_SHOW16BITTASKS:
777 TaskManager_OnOptionsShow16BitTasks();
778 break;
779 case ID_RESTORE:
780 TaskManager_OnRestoreMainWindow();
781 break;
782 case ID_VIEW_LARGE:
783 ApplicationPage_OnViewLargeIcons();
784 break;
785 case ID_VIEW_SMALL:
786 ApplicationPage_OnViewSmallIcons();
787 break;
788 case ID_VIEW_DETAILS:
789 ApplicationPage_OnViewDetails();
790 break;
791 case ID_VIEW_SHOWKERNELTIMES:
792 PerformancePage_OnViewShowKernelTimes();
793 break;
794 case ID_VIEW_CPUHISTORY_ONEGRAPHALL:
795 PerformancePage_OnViewCPUHistoryOneGraphAll();
796 break;
797 case ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU:
798 PerformancePage_OnViewCPUHistoryOneGraphPerCPU();
799 break;
800 case ID_VIEW_UPDATESPEED_HIGH:
801 TaskManager_OnViewUpdateSpeedHigh();
802 break;
803 case ID_VIEW_UPDATESPEED_NORMAL:
804 TaskManager_OnViewUpdateSpeedNormal();
805 break;
806 case ID_VIEW_UPDATESPEED_LOW:
807 TaskManager_OnViewUpdateSpeedLow();
808 break;
809 case ID_VIEW_UPDATESPEED_PAUSED:
810 TaskManager_OnViewUpdateSpeedPaused();
811 break;
812 case ID_VIEW_SELECTCOLUMNS:
813 ProcessPage_OnViewSelectColumns();
814 break;
815 case ID_VIEW_REFRESH:
816 PostMessageW(hDlg, WM_TIMER, 0, 0);
817 break;
818 case ID_WINDOWS_TILEHORIZONTALLY:
819 ApplicationPage_OnWindowsTileHorizontally();
820 break;
821 case ID_WINDOWS_TILEVERTICALLY:
822 ApplicationPage_OnWindowsTileVertically();
823 break;
824 case ID_WINDOWS_MINIMIZE:
825 ApplicationPage_OnWindowsMinimize();
826 break;
827 case ID_WINDOWS_MAXIMIZE:
828 ApplicationPage_OnWindowsMaximize();
829 break;
830 case ID_WINDOWS_CASCADE:
831 ApplicationPage_OnWindowsCascade();
832 break;
833 case ID_WINDOWS_BRINGTOFRONT:
834 ApplicationPage_OnWindowsBringToFront();
835 break;
836 case ID_APPLICATION_PAGE_SWITCHTO:
837 ApplicationPage_OnSwitchTo();
838 break;
839 case ID_APPLICATION_PAGE_ENDTASK:
840 ApplicationPage_OnEndTask();
841 break;
842 case ID_APPLICATION_PAGE_GOTOPROCESS:
843 ApplicationPage_OnGotoProcess();
844 break;
845 case ID_PROCESS_PAGE_ENDPROCESS:
846 ProcessPage_OnEndProcess();
847 break;
848 case ID_PROCESS_PAGE_ENDPROCESSTREE:
849 ProcessPage_OnEndProcessTree();
850 break;
851 case ID_PROCESS_PAGE_DEBUG:
852 ProcessPage_OnDebug();
853 break;
854 case ID_PROCESS_PAGE_SETAFFINITY:
855 ProcessPage_OnSetAffinity();
856 break;
857 case ID_PROCESS_PAGE_SETPRIORITY_REALTIME:
858 ProcessPage_OnSetPriorityRealTime();
859 break;
860 case ID_PROCESS_PAGE_SETPRIORITY_HIGH:
861 ProcessPage_OnSetPriorityHigh();
862 break;
863 case ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL:
864 ProcessPage_OnSetPriorityAboveNormal();
865 break;
866 case ID_PROCESS_PAGE_SETPRIORITY_NORMAL:
867 ProcessPage_OnSetPriorityNormal();
868 break;
869 case ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL:
870 ProcessPage_OnSetPriorityBelowNormal();
871 break;
872 case ID_PROCESS_PAGE_SETPRIORITY_LOW:
873 ProcessPage_OnSetPriorityLow();
874 break;
875 case ID_PROCESS_PAGE_DEBUGCHANNELS:
876 ProcessPage_OnDebugChannels();
877 break;
878 case ID_HELP_TOPICS:
879 WinHelpW(hDlg, wszTaskmgr, HELP_FINDER, 0);
880 break;
881 case ID_HELP_ABOUT:
882 OnAbout();
883 break;
884 case ID_FILE_EXIT:
885 EndDialog(hDlg, IDOK);
886 break;
888 break;
890 case WM_ONTRAYICON:
891 switch(lParam)
893 case WM_RBUTTONDOWN:
895 POINT pt;
896 BOOL OnTop;
897 HMENU hMenu, hPopupMenu;
899 GetCursorPos(&pt);
901 OnTop = (GetWindowLongW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
903 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_TRAY_POPUP));
904 hPopupMenu = GetSubMenu(hMenu, 0);
906 if(IsWindowVisible(hMainWnd))
908 DeleteMenu(hPopupMenu, ID_RESTORE, MF_BYCOMMAND);
910 else
912 SetMenuDefaultItem(hPopupMenu, ID_RESTORE, FALSE);
915 if(OnTop)
917 CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_CHECKED);
920 SetForegroundWindow(hMainWnd);
921 TrackPopupMenuEx(hPopupMenu, 0, pt.x, pt.y, hMainWnd, NULL);
923 DestroyMenu(hMenu);
924 break;
926 case WM_LBUTTONDBLCLK:
927 TaskManager_OnRestoreMainWindow();
928 break;
930 break;
932 case WM_NOTIFY:
933 pnmh = (LPNMHDR)lParam;
934 if ((pnmh->hwndFrom == hTabWnd) &&
935 (pnmh->idFrom == IDC_TAB) &&
936 (pnmh->code == TCN_SELCHANGE))
938 TaskManager_OnTabWndSelChange();
940 break;
942 case WM_NCPAINT:
943 hdc = GetDC(hDlg);
944 GetClientRect(hDlg, &rc);
945 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
946 ReleaseDC(hDlg, hdc);
947 break;
949 case WM_PAINT:
950 hdc = BeginPaint(hDlg, &ps);
951 GetClientRect(hDlg, &rc);
952 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
953 EndPaint(hDlg, &ps);
954 break;
956 case WM_SIZING:
957 /* Make sure the user is sizing the dialog */
958 /* in an acceptable range */
959 pRC = (LPRECT)lParam;
960 if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT)) {
961 /* If the width is too small enlarge it to the minimum */
962 if (nMinimumWidth > (pRC->right - pRC->left))
963 pRC->left = pRC->right - nMinimumWidth;
964 } else {
965 /* If the width is too small enlarge it to the minimum */
966 if (nMinimumWidth > (pRC->right - pRC->left))
967 pRC->right = pRC->left + nMinimumWidth;
969 if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) {
970 /* If the height is too small enlarge it to the minimum */
971 if (nMinimumHeight > (pRC->bottom - pRC->top))
972 pRC->top = pRC->bottom - nMinimumHeight;
973 } else {
974 /* If the height is too small enlarge it to the minimum */
975 if (nMinimumHeight > (pRC->bottom - pRC->top))
976 pRC->bottom = pRC->top + nMinimumHeight;
978 return TRUE;
980 case WM_SIZE:
981 /* Handle the window sizing in its own function */
982 OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
983 break;
985 case WM_DESTROY:
986 ShowWindow(hDlg, SW_HIDE);
987 TrayIcon_ShellRemoveTrayIcon();
988 wp.length = sizeof(WINDOWPLACEMENT);
989 GetWindowPlacement(hDlg, &wp);
990 TaskManagerSettings.Left = wp.rcNormalPosition.left;
991 TaskManagerSettings.Top = wp.rcNormalPosition.top;
992 TaskManagerSettings.Right = wp.rcNormalPosition.right;
993 TaskManagerSettings.Bottom = wp.rcNormalPosition.bottom;
994 if (IsZoomed(hDlg) || (wp.flags & WPF_RESTORETOMAXIMIZED))
995 TaskManagerSettings.Maximized = TRUE;
996 else
997 TaskManagerSettings.Maximized = FALSE;
998 return DefWindowProcW(hDlg, message, wParam, lParam);
1000 case WM_TIMER:
1001 /* Refresh the performance data */
1002 PerfDataRefresh();
1003 RefreshApplicationPage();
1004 RefreshProcessPage();
1005 RefreshPerformancePage();
1006 TrayIcon_ShellUpdateTrayIcon();
1007 break;
1009 case WM_ENTERMENULOOP:
1010 TaskManager_OnEnterMenuLoop(hDlg);
1011 break;
1012 case WM_EXITMENULOOP:
1013 TaskManager_OnExitMenuLoop(hDlg);
1014 break;
1015 case WM_MENUSELECT:
1016 TaskManager_OnMenuSelect(hDlg, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
1017 break;
1020 return 0;
1023 int APIENTRY WinMain(HINSTANCE hInstance,
1024 HINSTANCE hPrevInstance,
1025 LPSTR lpCmdLine,
1026 int nCmdShow)
1028 HANDLE hProcess;
1029 HANDLE hToken;
1030 TOKEN_PRIVILEGES tkp;
1032 /* Initialize global variables */
1033 hInst = hInstance;
1035 /* Change our priority class to HIGH */
1036 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
1037 SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS);
1038 CloseHandle(hProcess);
1040 /* Now let's get the SE_DEBUG_NAME privilege
1041 * so that we can debug processes
1044 /* Get a token for this process. */
1045 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
1046 static const WCHAR SeDebugPrivilegeW[] = {'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0};
1048 /* Get the LUID for the debug privilege. */
1049 LookupPrivilegeValueW(NULL, SeDebugPrivilegeW, &tkp.Privileges[0].Luid);
1051 tkp.PrivilegeCount = 1; /* one privilege to set */
1052 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1054 /* Get the debug privilege for this process. */
1055 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0);
1058 /* Load our settings from the registry */
1059 LoadSettings();
1061 /* Initialize perf data */
1062 if (!PerfDataInitialize()) {
1063 return -1;
1066 DialogBoxW(hInst, (LPWSTR)IDD_TASKMGR_DIALOG, NULL, TaskManagerWndProc);
1068 /* Save our settings to the registry */
1069 SaveSettings();
1070 return 0;