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