Gabriel Ilardi (gabrielilardi@hotmail.it)
[reactos.git] / reactos / base / applications / taskmgr / taskmgr.c
1 /*
2 * ReactOS Task Manager
3 *
4 * TaskMgr.c : Defines the entry point for the application.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include <precomp.h>
25
26 #define STATUS_WINDOW 2001
27
28 /* Global Variables: */
29 HINSTANCE hInst; /* current instance */
30
31 HWND hMainWnd; /* Main Window */
32 HWND hStatusWnd; /* Status Bar Window */
33 HWND hTabWnd; /* Tab Control Window */
34
35 int nMinimumWidth; /* Minimum width of the dialog (OnSize()'s cx) */
36 int nMinimumHeight; /* Minimum height of the dialog (OnSize()'s cy) */
37
38 int nOldWidth; /* Holds the previous client area width */
39 int nOldHeight; /* Holds the previous client area height */
40
41 BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
42
43 TASKMANAGER_SETTINGS TaskManagerSettings;
44
45
46 int APIENTRY wWinMain(HINSTANCE hInstance,
47 HINSTANCE hPrevInstance,
48 LPWSTR lpCmdLine,
49 int nCmdShow)
50 {
51 HANDLE hProcess;
52 HANDLE hToken;
53 TOKEN_PRIVILEGES tkp;
54 HANDLE hMutex;
55
56 /* check wether we're already running or not */
57 hMutex = CreateMutexW(NULL, TRUE, L"taskmgrros");
58 if ((!hMutex) || (GetLastError() == ERROR_ALREADY_EXISTS))
59 return 1;
60
61 /* Initialize global variables */
62 hInst = hInstance;
63
64 /* Change our priority class to HIGH */
65 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
66 SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS);
67 CloseHandle(hProcess);
68
69 /* Now lets get the SE_DEBUG_NAME privilege
70 * so that we can debug processes
71 */
72
73 /* Get a token for this process. */
74 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
75 /* Get the LUID for the debug privilege. */
76 LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
77
78 tkp.PrivilegeCount = 1; /* one privilege to set */
79 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
80
81 /* Get the debug privilege for this process. */
82 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
83 CloseHandle(hToken);
84 }
85
86 /* Load our settings from the registry */
87 LoadSettings();
88
89 /* Initialize perf data */
90 if (!PerfDataInitialize()) {
91 return -1;
92 }
93
94 DialogBoxW(hInst, (LPCWSTR)IDD_TASKMGR_DIALOG, NULL, TaskManagerWndProc);
95
96 /* Save our settings to the registry */
97 SaveSettings();
98 PerfDataUninitialize();
99 return 0;
100 }
101
102 /* Message handler for dialog box. */
103 INT_PTR CALLBACK
104 TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
105 {
106 HDC hdc;
107 PAINTSTRUCT ps;
108 LPRECT pRC;
109 RECT rc;
110 int idctrl;
111 LPNMHDR pnmh;
112 WINDOWPLACEMENT wp;
113
114 switch (message) {
115 case WM_INITDIALOG:
116 hMainWnd = hDlg;
117 return OnCreate(hDlg);
118
119 case WM_COMMAND:
120 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
121 EndDialog(hDlg, LOWORD(wParam));
122 return TRUE;
123 }
124 /* Process menu commands */
125 switch (LOWORD(wParam))
126 {
127 case ID_FILE_NEW:
128 TaskManager_OnFileNew();
129 break;
130 case ID_OPTIONS_ALWAYSONTOP:
131 TaskManager_OnOptionsAlwaysOnTop();
132 break;
133 case ID_OPTIONS_MINIMIZEONUSE:
134 TaskManager_OnOptionsMinimizeOnUse();
135 break;
136 case ID_OPTIONS_HIDEWHENMINIMIZED:
137 TaskManager_OnOptionsHideWhenMinimized();
138 break;
139 case ID_OPTIONS_SHOW16BITTASKS:
140 TaskManager_OnOptionsShow16BitTasks();
141 break;
142 case ID_RESTORE:
143 TaskManager_OnRestoreMainWindow();
144 break;
145 case ID_VIEW_LARGE:
146 case ID_VIEW_SMALL:
147 case ID_VIEW_DETAILS:
148 ApplicationPage_OnView(LOWORD(wParam));
149 break;
150 case ID_VIEW_SHOWKERNELTIMES:
151 PerformancePage_OnViewShowKernelTimes();
152 break;
153 case ID_VIEW_CPUHISTORY_ONEGRAPHALL:
154 PerformancePage_OnViewCPUHistoryOneGraphAll();
155 break;
156 case ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU:
157 PerformancePage_OnViewCPUHistoryOneGraphPerCPU();
158 break;
159 case ID_VIEW_UPDATESPEED_HIGH:
160 case ID_VIEW_UPDATESPEED_NORMAL:
161 case ID_VIEW_UPDATESPEED_LOW:
162 case ID_VIEW_UPDATESPEED_PAUSED:
163 TaskManager_OnViewUpdateSpeed(LOWORD(wParam));
164 break;
165 case ID_VIEW_SELECTCOLUMNS:
166 ProcessPage_OnViewSelectColumns();
167 break;
168 case ID_VIEW_REFRESH:
169 PostMessageW(hDlg, WM_TIMER, 0, 0);
170 break;
171 case ID_WINDOWS_TILEHORIZONTALLY:
172 ApplicationPage_OnWindowsTile(MDITILE_HORIZONTAL);
173 break;
174 case ID_WINDOWS_TILEVERTICALLY:
175 ApplicationPage_OnWindowsTile(MDITILE_VERTICAL);
176 break;
177 case ID_WINDOWS_MINIMIZE:
178 ApplicationPage_OnWindowsMinimize();
179 break;
180 case ID_WINDOWS_MAXIMIZE:
181 ApplicationPage_OnWindowsMaximize();
182 break;
183 case ID_WINDOWS_CASCADE:
184 ApplicationPage_OnWindowsCascade();
185 break;
186 case ID_WINDOWS_BRINGTOFRONT:
187 ApplicationPage_OnWindowsBringToFront();
188 break;
189 case ID_APPLICATION_PAGE_SWITCHTO:
190 ApplicationPage_OnSwitchTo();
191 break;
192 case ID_APPLICATION_PAGE_ENDTASK:
193 ApplicationPage_OnEndTask();
194 break;
195 case ID_APPLICATION_PAGE_GOTOPROCESS:
196 ApplicationPage_OnGotoProcess();
197 break;
198 case ID_PROCESS_PAGE_ENDPROCESS:
199 ProcessPage_OnEndProcess();
200 break;
201 case ID_PROCESS_PAGE_ENDPROCESSTREE:
202 ProcessPage_OnEndProcessTree();
203 break;
204 case ID_PROCESS_PAGE_DEBUG:
205 ProcessPage_OnDebug();
206 break;
207 case ID_PROCESS_PAGE_SETAFFINITY:
208 ProcessPage_OnSetAffinity();
209 break;
210 case ID_PROCESS_PAGE_SETPRIORITY_REALTIME:
211 DoSetPriority(REALTIME_PRIORITY_CLASS);
212 break;
213 case ID_PROCESS_PAGE_SETPRIORITY_HIGH:
214 DoSetPriority(HIGH_PRIORITY_CLASS);
215 break;
216 case ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL:
217 DoSetPriority(ABOVE_NORMAL_PRIORITY_CLASS);
218 break;
219 case ID_PROCESS_PAGE_SETPRIORITY_NORMAL:
220 DoSetPriority(NORMAL_PRIORITY_CLASS);
221 break;
222 case ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL:
223 DoSetPriority(BELOW_NORMAL_PRIORITY_CLASS);
224 break;
225 case ID_PROCESS_PAGE_SETPRIORITY_LOW:
226 DoSetPriority(IDLE_PRIORITY_CLASS);
227 break;
228 case ID_PROCESS_PAGE_DEBUGCHANNELS:
229 ProcessPage_OnDebugChannels();
230 break;
231 case ID_HELP_ABOUT:
232 OnAbout();
233 break;
234 case ID_FILE_EXIT:
235 EndDialog(hDlg, IDOK);
236 break;
237 }
238 break;
239
240 case WM_ONTRAYICON:
241 switch(lParam)
242 {
243 case WM_RBUTTONDOWN:
244 {
245 POINT pt;
246 BOOL OnTop;
247 HMENU hMenu, hPopupMenu;
248
249 GetCursorPos(&pt);
250
251 OnTop = ((GetWindowLongW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
252
253 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_TRAY_POPUP));
254 hPopupMenu = GetSubMenu(hMenu, 0);
255
256 if(IsWindowVisible(hMainWnd))
257 {
258 DeleteMenu(hPopupMenu, ID_RESTORE, MF_BYCOMMAND);
259 }
260 else
261 {
262 SetMenuDefaultItem(hPopupMenu, ID_RESTORE, FALSE);
263 }
264
265 if(OnTop)
266 {
267 CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_CHECKED);
268 }
269
270 SetForegroundWindow(hMainWnd);
271 TrackPopupMenuEx(hPopupMenu, 0, pt.x, pt.y, hMainWnd, NULL);
272
273 DestroyMenu(hMenu);
274 break;
275 }
276 case WM_LBUTTONDBLCLK:
277 TaskManager_OnRestoreMainWindow();
278 break;
279 }
280 break;
281
282 case WM_NOTIFY:
283 idctrl = (int)wParam;
284 pnmh = (LPNMHDR)lParam;
285 if ((pnmh->hwndFrom == hTabWnd) &&
286 (pnmh->idFrom == IDC_TAB) &&
287 (pnmh->code == TCN_SELCHANGE))
288 {
289 TaskManager_OnTabWndSelChange();
290 }
291 break;
292
293 case WM_NCPAINT:
294 hdc = GetDC(hDlg);
295 GetClientRect(hDlg, &rc);
296 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
297 ReleaseDC(hDlg, hdc);
298 break;
299
300 case WM_PAINT:
301 hdc = BeginPaint(hDlg, &ps);
302 GetClientRect(hDlg, &rc);
303 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
304 EndPaint(hDlg, &ps);
305 break;
306
307 case WM_SIZING:
308 /* Make sure the user is sizing the dialog */
309 /* in an acceptable range */
310 pRC = (LPRECT)lParam;
311 if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT)) {
312 /* If the width is too small enlarge it to the minimum */
313 if (nMinimumWidth > (pRC->right - pRC->left))
314 pRC->left = pRC->right - nMinimumWidth;
315 } else {
316 /* If the width is too small enlarge it to the minimum */
317 if (nMinimumWidth > (pRC->right - pRC->left))
318 pRC->right = pRC->left + nMinimumWidth;
319 }
320 if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) {
321 /* If the height is too small enlarge it to the minimum */
322 if (nMinimumHeight > (pRC->bottom - pRC->top))
323 pRC->top = pRC->bottom - nMinimumHeight;
324 } else {
325 /* If the height is too small enlarge it to the minimum */
326 if (nMinimumHeight > (pRC->bottom - pRC->top))
327 pRC->bottom = pRC->top + nMinimumHeight;
328 }
329 return TRUE;
330 break;
331
332 case WM_SIZE:
333 /* Handle the window sizing in it's own function */
334 OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
335 break;
336
337 case WM_MOVE:
338 /* Handle the window moving in it's own function */
339 OnMove(wParam, LOWORD(lParam), HIWORD(lParam));
340 break;
341
342 case WM_DESTROY:
343 ShowWindow(hDlg, SW_HIDE);
344 TrayIcon_ShellRemoveTrayIcon();
345 wp.length = sizeof(WINDOWPLACEMENT);
346 GetWindowPlacement(hDlg, &wp);
347 TaskManagerSettings.Left = wp.rcNormalPosition.left;
348 TaskManagerSettings.Top = wp.rcNormalPosition.top;
349 TaskManagerSettings.Right = wp.rcNormalPosition.right;
350 TaskManagerSettings.Bottom = wp.rcNormalPosition.bottom;
351 if (IsZoomed(hDlg) || (wp.flags & WPF_RESTORETOMAXIMIZED))
352 TaskManagerSettings.Maximized = TRUE;
353 else
354 TaskManagerSettings.Maximized = FALSE;
355 return DefWindowProcW(hDlg, message, wParam, lParam);
356
357 case WM_TIMER:
358 /* Refresh the performance data */
359 PerfDataRefresh();
360 RefreshApplicationPage();
361 RefreshProcessPage();
362 RefreshPerformancePage();
363 TrayIcon_ShellUpdateTrayIcon();
364 break;
365
366 case WM_ENTERMENULOOP:
367 TaskManager_OnEnterMenuLoop(hDlg);
368 break;
369 case WM_EXITMENULOOP:
370 TaskManager_OnExitMenuLoop(hDlg);
371 break;
372 case WM_MENUSELECT:
373 TaskManager_OnMenuSelect(hDlg, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
374 break;
375 }
376
377 return 0;
378 }
379
380 void FillSolidRect(HDC hDC, LPCRECT lpRect, COLORREF clr)
381 {
382 SetBkColor(hDC, clr);
383 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
384 }
385
386 void FillSolidRect2(HDC hDC, int x, int y, int cx, int cy, COLORREF clr)
387 {
388 RECT rect;
389
390 SetBkColor(hDC, clr);
391 rect.left = x;
392 rect.top = y;
393 rect.right = x + cx;
394 rect.bottom = y + cy;
395 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
396 }
397
398 void Draw3dRect(HDC hDC, int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight)
399 {
400 FillSolidRect2(hDC, x, y, cx - 1, 1, clrTopLeft);
401 FillSolidRect2(hDC, x, y, 1, cy - 1, clrTopLeft);
402 FillSolidRect2(hDC, x + cx, y, -1, cy, clrBottomRight);
403 FillSolidRect2(hDC, x, y + cy, cx, -1, clrBottomRight);
404 }
405
406 void Draw3dRect2(HDC hDC, LPRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight)
407 {
408 Draw3dRect(hDC, lpRect->left, lpRect->top, lpRect->right - lpRect->left,
409 lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
410 }
411
412 static void SetUpdateSpeed(HWND hWnd)
413 {
414 /* Setup update speed (pause=fall down) */
415 switch (TaskManagerSettings.UpdateSpeed) {
416 case ID_VIEW_UPDATESPEED_HIGH:
417 SetTimer(hWnd, 1, 1000, NULL);
418 break;
419 case ID_VIEW_UPDATESPEED_NORMAL:
420 SetTimer(hWnd, 1, 2000, NULL);
421 break;
422 case ID_VIEW_UPDATESPEED_LOW:
423 SetTimer(hWnd, 1, 4000, NULL);
424 break;
425 }
426 }
427
428 BOOL OnCreate(HWND hWnd)
429 {
430 HMENU hMenu;
431 HMENU hEditMenu;
432 HMENU hViewMenu;
433 HMENU hUpdateSpeedMenu;
434 HMENU hCPUHistoryMenu;
435 int nActivePage;
436 int nParts[3];
437 RECT rc;
438 WCHAR szTemp[256];
439 TCITEM item;
440
441 SendMessageW(hMainWnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW(hInst, MAKEINTRESOURCEW(IDI_TASKMANAGER)));
442
443 /* Initialize the Windows Common Controls DLL */
444 InitCommonControls();
445
446 /* Get the minimum window sizes */
447 GetWindowRect(hWnd, &rc);
448 nMinimumWidth = (rc.right - rc.left);
449 nMinimumHeight = (rc.bottom - rc.top);
450
451 /* Create the status bar */
452 hStatusWnd = CreateStatusWindow(WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|SBT_NOBORDERS, L"", hWnd, STATUS_WINDOW);
453 if(!hStatusWnd)
454 return FALSE;
455
456 /* Create the status bar panes */
457 nParts[0] = 100;
458 nParts[1] = 210;
459 nParts[2] = 400;
460 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts);
461
462 /* Create tab pages */
463 hTabWnd = GetDlgItem(hWnd, IDC_TAB);
464 #if 1
465 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hWnd, ApplicationPageWndProc);
466 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hWnd, ProcessPageWndProc);
467 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hWnd, PerformancePageWndProc);
468 #else
469 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hTabWnd, ApplicationPageWndProc);
470 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hTabWnd, ProcessPageWndProc);
471 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hTabWnd, PerformancePageWndProc);
472 #endif
473
474 /* Insert tabs */
475 LoadStringW(hInst, IDS_TAB_APPS, szTemp, 256);
476 memset(&item, 0, sizeof(TCITEM));
477 item.mask = TCIF_TEXT;
478 item.pszText = szTemp;
479 (void)TabCtrl_InsertItem(hTabWnd, 0, &item);
480 LoadStringW(hInst, IDS_TAB_PROCESSES, szTemp, 256);
481 memset(&item, 0, sizeof(TCITEM));
482 item.mask = TCIF_TEXT;
483 item.pszText = szTemp;
484 (void)TabCtrl_InsertItem(hTabWnd, 1, &item);
485 LoadStringW(hInst, IDS_TAB_PERFORMANCE, szTemp, 256);
486 memset(&item, 0, sizeof(TCITEM));
487 item.mask = TCIF_TEXT;
488 item.pszText = szTemp;
489 (void)TabCtrl_InsertItem(hTabWnd, 2, &item);
490
491 /* Size everything correctly */
492 GetClientRect(hWnd, &rc);
493 nOldWidth = rc.right;
494 nOldHeight = rc.bottom;
495 /* nOldStartX = rc.left; */
496 /*nOldStartY = rc.top; */
497
498 #define PAGE_OFFSET_LEFT 17
499 #define PAGE_OFFSET_TOP 72
500 #define PAGE_OFFSET_WIDTH (PAGE_OFFSET_LEFT*2)
501 #define PAGE_OFFSET_HEIGHT (PAGE_OFFSET_TOP+32)
502
503 if ((TaskManagerSettings.Left != 0) ||
504 (TaskManagerSettings.Top != 0) ||
505 (TaskManagerSettings.Right != 0) ||
506 (TaskManagerSettings.Bottom != 0))
507 {
508 MoveWindow(hWnd, TaskManagerSettings.Left, TaskManagerSettings.Top, TaskManagerSettings.Right - TaskManagerSettings.Left, TaskManagerSettings.Bottom - TaskManagerSettings.Top, TRUE);
509 #ifdef __GNUC__TEST__
510 MoveWindow(hApplicationPage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE);
511 MoveWindow(hProcessPage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE);
512 MoveWindow(hPerformancePage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE);
513 #endif
514 }
515 if (TaskManagerSettings.Maximized)
516 ShowWindow(hWnd, SW_MAXIMIZE);
517
518 /* Set the always on top style */
519 hMenu = GetMenu(hWnd);
520 hEditMenu = GetSubMenu(hMenu, 1);
521 hViewMenu = GetSubMenu(hMenu, 2);
522 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
523 hCPUHistoryMenu = GetSubMenu(hViewMenu, 7);
524
525 /* Check or uncheck the always on top menu item */
526 if (TaskManagerSettings.AlwaysOnTop) {
527 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_CHECKED);
528 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
529 } else {
530 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_UNCHECKED);
531 SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
532 }
533
534 /* Check or uncheck the minimize on use menu item */
535 if (TaskManagerSettings.MinimizeOnUse)
536 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_CHECKED);
537 else
538 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_UNCHECKED);
539
540 /* Check or uncheck the hide when minimized menu item */
541 if (TaskManagerSettings.HideWhenMinimized)
542 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_CHECKED);
543 else
544 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_UNCHECKED);
545
546 /* Check or uncheck the show 16-bit tasks menu item */
547 if (TaskManagerSettings.Show16BitTasks)
548 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED);
549 else
550 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_UNCHECKED);
551
552 /* Set the view mode */
553 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND);
554
555 if (TaskManagerSettings.ShowKernelTimes)
556 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
557 else
558 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
559
560 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, TaskManagerSettings.UpdateSpeed, MF_BYCOMMAND);
561
562 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
563 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
564 else
565 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
566
567 nActivePage = TaskManagerSettings.ActiveTabPage;
568 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 0);
569 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 1);
570 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 2);
571 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, nActivePage);
572
573 /* Setup update speed */
574 SetUpdateSpeed(hWnd);
575
576 /*
577 * Refresh the performance data
578 * Sample it twice so we can establish
579 * the delta values & cpu usage
580 */
581 PerfDataRefresh();
582 PerfDataRefresh();
583
584 RefreshApplicationPage();
585 RefreshProcessPage();
586 RefreshPerformancePage();
587
588 TrayIcon_ShellAddTrayIcon();
589
590 return TRUE;
591 }
592
593 /* OnMove()
594 * This function handles all the moving events for the application
595 * It moves every child window that needs moving
596 */
597 void OnMove( WPARAM nType, int cx, int cy )
598 {
599 #ifdef __GNUC__TEST__
600 MoveWindow(hApplicationPage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE);
601 MoveWindow(hProcessPage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE);
602 MoveWindow(hPerformancePage, TaskManagerSettings.Left + PAGE_OFFSET_LEFT, TaskManagerSettings.Top + PAGE_OFFSET_TOP, TaskManagerSettings.Right - TaskManagerSettings.Left - PAGE_OFFSET_WIDTH, TaskManagerSettings.Bottom - TaskManagerSettings.Top - PAGE_OFFSET_HEIGHT, FALSE);
603 #endif
604 }
605
606 /* OnSize()
607 * This function handles all the sizing events for the application
608 * It re-sizes every window, and child window that needs re-sizing
609 */
610 void OnSize( WPARAM nType, int cx, int cy )
611 {
612 int nParts[3];
613 int nXDifference;
614 int nYDifference;
615 RECT rc;
616
617 if (nType == SIZE_MINIMIZED)
618 {
619 if(TaskManagerSettings.HideWhenMinimized)
620 {
621 ShowWindow(hMainWnd, SW_HIDE);
622 }
623 return;
624 }
625
626 nXDifference = cx - nOldWidth;
627 nYDifference = cy - nOldHeight;
628 nOldWidth = cx;
629 nOldHeight = cy;
630
631 /* Update the status bar size */
632 GetWindowRect(hStatusWnd, &rc);
633 SendMessageW(hStatusWnd, WM_SIZE, nType, MAKELPARAM(cx, cy + (rc.bottom - rc.top)));
634
635 /* Update the status bar pane sizes */
636 nParts[0] = bInMenuLoop ? -1 : 100;
637 nParts[1] = 210;
638 nParts[2] = cx;
639 SendMessageW(hStatusWnd, SB_SETPARTS, bInMenuLoop ? 1 : 3, (LPARAM) (LPINT) nParts);
640
641 /* Resize the tab control */
642 GetWindowRect(hTabWnd, &rc);
643 cx = (rc.right - rc.left) + nXDifference;
644 cy = (rc.bottom - rc.top) + nYDifference;
645 SetWindowPos(hTabWnd, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
646
647 /* Resize the application page */
648 GetWindowRect(hApplicationPage, &rc);
649 cx = (rc.right - rc.left) + nXDifference;
650 cy = (rc.bottom - rc.top) + nYDifference;
651 SetWindowPos(hApplicationPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
652
653 /* Resize the process page */
654 GetWindowRect(hProcessPage, &rc);
655 cx = (rc.right - rc.left) + nXDifference;
656 cy = (rc.bottom - rc.top) + nYDifference;
657 SetWindowPos(hProcessPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
658
659 /* Resize the performance page */
660 GetWindowRect(hPerformancePage, &rc);
661 cx = (rc.right - rc.left) + nXDifference;
662 cy = (rc.bottom - rc.top) + nYDifference;
663 SetWindowPos(hPerformancePage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
664 }
665
666 void LoadSettings(void)
667 {
668 HKEY hKey;
669 WCHAR szSubKey[] = L"Software\\ReactOS\\TaskManager";
670 int i;
671 DWORD dwSize;
672
673 /* Window size & position settings */
674 TaskManagerSettings.Maximized = FALSE;
675 TaskManagerSettings.Left = 0;
676 TaskManagerSettings.Top = 0;
677 TaskManagerSettings.Right = 0;
678 TaskManagerSettings.Bottom = 0;
679
680 /* Tab settings */
681 TaskManagerSettings.ActiveTabPage = 0;
682
683 /* Options menu settings */
684 TaskManagerSettings.AlwaysOnTop = FALSE;
685 TaskManagerSettings.MinimizeOnUse = TRUE;
686 TaskManagerSettings.HideWhenMinimized = TRUE;
687 TaskManagerSettings.Show16BitTasks = TRUE;
688
689 /* Update speed settings */
690 TaskManagerSettings.UpdateSpeed = ID_VIEW_UPDATESPEED_NORMAL;
691
692 /* Applications page settings */
693 TaskManagerSettings.ViewMode = ID_VIEW_DETAILS;
694
695 /* Processes page settings */
696 TaskManagerSettings.ShowProcessesFromAllUsers = FALSE; /* Server-only? */
697
698 for (i = 0; i < COLUMN_NMAX; i++) {
699 TaskManagerSettings.Columns[i] = ColumnPresets[i].bDefaults;
700 TaskManagerSettings.ColumnOrderArray[i] = i;
701 TaskManagerSettings.ColumnSizeArray[i] = ColumnPresets[i].size;
702 }
703
704 TaskManagerSettings.SortColumn = 1;
705 TaskManagerSettings.SortAscending = TRUE;
706
707 /* Performance page settings */
708 TaskManagerSettings.CPUHistory_OneGraphPerCPU = TRUE;
709 TaskManagerSettings.ShowKernelTimes = FALSE;
710
711 /* Open the key */
712 if (RegOpenKeyExW(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
713 return;
714 /* Read the settings */
715 dwSize = sizeof(TASKMANAGER_SETTINGS);
716 RegQueryValueExW(hKey, L"Preferences", NULL, NULL, (LPBYTE)&TaskManagerSettings, &dwSize);
717
718 /*
719 * ATM, the 'ImageName' column is always visible
720 * (and grayed in configuration dialog)
721 * This will avoid troubles if the registry gets corrupted.
722 */
723 TaskManagerSettings.Column_ImageName = TRUE;
724
725 /* Close the key */
726 RegCloseKey(hKey);
727 }
728
729 void SaveSettings(void)
730 {
731 HKEY hKey;
732 WCHAR szSubKey1[] = L"Software";
733 WCHAR szSubKey2[] = L"Software\\ReactOS";
734 WCHAR szSubKey3[] = L"Software\\ReactOS\\TaskManager";
735
736 /* Open (or create) the key */
737 hKey = NULL;
738 RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey1, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
739 RegCloseKey(hKey);
740 hKey = NULL;
741 RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey2, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
742 RegCloseKey(hKey);
743 hKey = NULL;
744 if (RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey3, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
745 return;
746 /* Save the settings */
747 RegSetValueExW(hKey, L"Preferences", 0, REG_BINARY, (LPBYTE)&TaskManagerSettings, sizeof(TASKMANAGER_SETTINGS));
748 /* Close the key */
749 RegCloseKey(hKey);
750 }
751
752 void TaskManager_OnRestoreMainWindow(void)
753 {
754 HMENU hMenu, hOptionsMenu;
755 BOOL OnTop;
756
757 hMenu = GetMenu(hMainWnd);
758 hOptionsMenu = GetSubMenu(hMenu, OPTIONS_MENU_INDEX);
759 OnTop = ((GetWindowLongW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
760
761 OpenIcon(hMainWnd);
762 SetForegroundWindow(hMainWnd);
763 SetWindowPos(hMainWnd, (OnTop ? HWND_TOPMOST : HWND_TOP), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
764 }
765
766 void TaskManager_OnEnterMenuLoop(HWND hWnd)
767 {
768 int nParts;
769
770 /* Update the status bar pane sizes */
771 nParts = -1;
772 SendMessageW(hStatusWnd, SB_SETPARTS, 1, (LPARAM) (LPINT)&nParts);
773 bInMenuLoop = TRUE;
774 SendMessageW(hStatusWnd, SB_SETTEXT, (WPARAM)0, (LPARAM)L"");
775 }
776
777 void TaskManager_OnExitMenuLoop(HWND hWnd)
778 {
779 RECT rc;
780 int nParts[3];
781 WCHAR text[260];
782 WCHAR szCpuUsage[256], szProcesses[256];
783
784 LoadStringW(hInst, IDS_STATUS_CPUUSAGE, szCpuUsage, 256);
785 LoadStringW(hInst, IDS_STATUS_PROCESSES, szProcesses, 256);
786
787 bInMenuLoop = FALSE;
788 /* Update the status bar pane sizes */
789 GetClientRect(hWnd, &rc);
790 nParts[0] = 100;
791 nParts[1] = 210;
792 nParts[2] = rc.right;
793 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts);
794 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)L"");
795 wsprintfW(text, szCpuUsage, PerfDataGetProcessorUsage());
796 SendMessageW(hStatusWnd, SB_SETTEXT, 1, (LPARAM)text);
797 wsprintfW(text, szProcesses, PerfDataGetProcessCount());
798 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)text);
799 }
800
801 void TaskManager_OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
802 {
803 WCHAR str[100];
804
805 wcscpy(str, L"");
806 if (LoadStringW(hInst, nItemID, str, 100)) {
807 /* load appropriate string */
808 LPWSTR lpsz = str;
809 /* first newline terminates actual string */
810 lpsz = wcschr(lpsz, '\n');
811 if (lpsz != NULL)
812 *lpsz = '\0';
813 }
814 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)str);
815 }
816
817 void TaskManager_OnViewUpdateSpeed(DWORD dwSpeed)
818 {
819 HMENU hMenu;
820 HMENU hViewMenu;
821 HMENU hUpdateSpeedMenu;
822
823 hMenu = GetMenu(hMainWnd);
824 hViewMenu = GetSubMenu(hMenu, 2);
825 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
826
827 TaskManagerSettings.UpdateSpeed = dwSpeed;
828 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, dwSpeed, MF_BYCOMMAND);
829
830 KillTimer(hMainWnd, 1);
831
832 SetUpdateSpeed(hMainWnd);
833 }
834
835 void TaskManager_OnViewRefresh(void)
836 {
837 PostMessageW(hMainWnd, WM_TIMER, 0, 0);
838 }
839
840 void TaskManager_OnTabWndSelChange(void)
841 {
842 int i;
843 HMENU hMenu;
844 HMENU hOptionsMenu;
845 HMENU hViewMenu;
846 HMENU hSubMenu;
847 WCHAR szTemp[256];
848
849 hMenu = GetMenu(hMainWnd);
850 hViewMenu = GetSubMenu(hMenu, 2);
851 hOptionsMenu = GetSubMenu(hMenu, 1);
852 TaskManagerSettings.ActiveTabPage = TabCtrl_GetCurSel(hTabWnd);
853 for (i = GetMenuItemCount(hViewMenu) - 1; i > 2; i--) {
854 hSubMenu = GetSubMenu(hViewMenu, i);
855 if (hSubMenu)
856 DestroyMenu(hSubMenu);
857 RemoveMenu(hViewMenu, i, MF_BYPOSITION);
858 }
859 RemoveMenu(hOptionsMenu, 3, MF_BYPOSITION);
860 switch (TaskManagerSettings.ActiveTabPage) {
861 case 0:
862 ShowWindow(hApplicationPage, SW_SHOW);
863 ShowWindow(hProcessPage, SW_HIDE);
864 ShowWindow(hPerformancePage, SW_HIDE);
865 BringWindowToTop(hApplicationPage);
866
867 LoadStringW(hInst, IDS_MENU_LARGEICONS, szTemp, 256);
868 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_LARGE, szTemp);
869
870 LoadStringW(hInst, IDS_MENU_SMALLICONS, szTemp, 256);
871 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SMALL, szTemp);
872
873 LoadStringW(hInst, IDS_MENU_DETAILS, szTemp, 256);
874 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_DETAILS, szTemp);
875
876 if (GetMenuItemCount(hMenu) <= 4) {
877 hSubMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_WINDOWSMENU));
878
879 LoadStringW(hInst, IDS_MENU_WINDOWS, szTemp, 256);
880 InsertMenuW(hMenu, 3, MF_BYPOSITION|MF_POPUP, (UINT_PTR) hSubMenu, szTemp);
881
882 DrawMenuBar(hMainWnd);
883 }
884 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND);
885
886 /*
887 * Give the application list control focus
888 */
889 SetFocus(hApplicationPageListCtrl);
890 break;
891
892 case 1:
893 ShowWindow(hApplicationPage, SW_HIDE);
894 ShowWindow(hProcessPage, SW_SHOW);
895 ShowWindow(hPerformancePage, SW_HIDE);
896 BringWindowToTop(hProcessPage);
897
898 LoadStringW(hInst, IDS_MENU_SELECTCOLUMNS, szTemp, 256);
899 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SELECTCOLUMNS, szTemp);
900
901 LoadStringW(hInst, IDS_MENU_16BITTASK, szTemp, 256);
902 AppendMenuW(hOptionsMenu, MF_STRING, ID_OPTIONS_SHOW16BITTASKS, szTemp);
903
904 if (TaskManagerSettings.Show16BitTasks)
905 CheckMenuItem(hOptionsMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED);
906 if (GetMenuItemCount(hMenu) > 4)
907 {
908 DeleteMenu(hMenu, 3, MF_BYPOSITION);
909 DrawMenuBar(hMainWnd);
910 }
911 /*
912 * Give the process list control focus
913 */
914 SetFocus(hProcessPageListCtrl);
915 break;
916
917 case 2:
918 ShowWindow(hApplicationPage, SW_HIDE);
919 ShowWindow(hProcessPage, SW_HIDE);
920 ShowWindow(hPerformancePage, SW_SHOW);
921 BringWindowToTop(hPerformancePage);
922 if (GetMenuItemCount(hMenu) > 4) {
923 DeleteMenu(hMenu, 3, MF_BYPOSITION);
924 DrawMenuBar(hMainWnd);
925 }
926 hSubMenu = CreatePopupMenu();
927
928 LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256);
929 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp);
930
931 LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256);
932 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp);
933
934 LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256);
935 AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp);
936
937 LoadStringW(hInst, IDS_MENU_SHOWKERNELTIMES, szTemp, 256);
938 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, szTemp);
939
940 if (TaskManagerSettings.ShowKernelTimes)
941 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
942 else
943 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
944 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
945 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
946 else
947 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
948 /*
949 * Give the tab control focus
950 */
951 SetFocus(hTabWnd);
952 break;
953 }
954 }
955
956 LPWSTR GetLastErrorText(LPWSTR lpszBuf, DWORD dwSize)
957 {
958 DWORD dwRet;
959 LPWSTR lpszTemp = NULL;
960
961 dwRet = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
962 NULL,
963 GetLastError(),
964 LANG_NEUTRAL,
965 (LPWSTR)&lpszTemp,
966 0,
967 NULL );
968
969 /* supplied buffer is not long enough */
970 if (!dwRet || ( (long)dwSize < (long)dwRet+14)) {
971 lpszBuf[0] = L'\0';
972 } else {
973 lpszTemp[lstrlenW(lpszTemp)-2] = L'\0'; /*remove cr and newline character */
974 wsprintfW(lpszBuf, L"%s (0x%x)", lpszTemp, (int)GetLastError());
975 }
976 if (lpszTemp) {
977 LocalFree((HLOCAL)lpszTemp);
978 }
979 return lpszBuf;
980 }