7639c4f7f17268fa1944b33bde65382d009029fb
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #include "precomp.h"
25
26 #include "perfpage.h"
27 #include "about.h"
28 #include "affinity.h"
29 #include "debug.h"
30 #include "priority.h"
31
32 #define STATUS_WINDOW 2001
33
34 /* Global Variables: */
35 HINSTANCE hInst; /* current instance */
36
37 HWND hMainWnd; /* Main Window */
38 HWND hStatusWnd; /* Status Bar Window */
39 HWND hTabWnd; /* Tab Control Window */
40
41 HMENU hWindowMenu = NULL;
42
43 int nMinimumWidth; /* Minimum width of the dialog (OnSize()'s cx) */
44 int nMinimumHeight; /* Minimum height of the dialog (OnSize()'s cy) */
45
46 int nOldWidth; /* Holds the previous client area width */
47 int nOldHeight; /* Holds the previous client area height */
48
49 BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
50 BOOL bWasKeyboardInput = FALSE; /* TabChange by Keyboard or Mouse ? */
51
52 TASKMANAGER_SETTINGS TaskManagerSettings;
53
54 ////////////////////////////////////////////////////////////////////////////////
55 // Taken from WinSpy++ 1.7
56 // http://www.catch22.net/software/winspy
57 // Copyright (c) 2002 by J Brown
58 //
59
60 //
61 // Copied from uxtheme.h
62 // If you have this new header, then delete these and
63 // #include <uxtheme.h> instead!
64 //
65 #define ETDT_DISABLE 0x00000001
66 #define ETDT_ENABLE 0x00000002
67 #define ETDT_USETABTEXTURE 0x00000004
68 #define ETDT_ENABLETAB (ETDT_ENABLE | ETDT_USETABTEXTURE)
69
70 //
71 typedef HRESULT (WINAPI * ETDTProc) (HWND, DWORD);
72
73 //
74 // Try to call EnableThemeDialogTexture, if uxtheme.dll is present
75 //
76 BOOL EnableDialogTheme(HWND hwnd)
77 {
78 HMODULE hUXTheme;
79 ETDTProc fnEnableThemeDialogTexture;
80
81 hUXTheme = LoadLibraryA("uxtheme.dll");
82
83 if(hUXTheme)
84 {
85 fnEnableThemeDialogTexture =
86 (ETDTProc)GetProcAddress(hUXTheme, "EnableThemeDialogTexture");
87
88 if(fnEnableThemeDialogTexture)
89 {
90 fnEnableThemeDialogTexture(hwnd, ETDT_ENABLETAB);
91
92 FreeLibrary(hUXTheme);
93 return TRUE;
94 }
95 else
96 {
97 // Failed to locate API!
98 FreeLibrary(hUXTheme);
99 return FALSE;
100 }
101 }
102 else
103 {
104 // Not running under XP? Just fail gracefully
105 return FALSE;
106 }
107 }
108
109 int APIENTRY wWinMain(HINSTANCE hInstance,
110 HINSTANCE hPrevInstance,
111 LPWSTR lpCmdLine,
112 int nCmdShow)
113 {
114 HANDLE hProcess;
115 HANDLE hToken;
116 TOKEN_PRIVILEGES tkp;
117 HANDLE hMutex;
118
119 /* check wether we're already running or not */
120 hMutex = CreateMutexW(NULL, TRUE, L"taskmgrros");
121 if (hMutex && GetLastError() == ERROR_ALREADY_EXISTS)
122 {
123 /* Restore existing taskmanager and bring window to front */
124 /* Relies on the fact that the application title string and window title are the same */
125 HWND hTaskMgr;
126 TCHAR szTaskmgr[128];
127
128 LoadString(hInst, IDS_APP_TITLE, szTaskmgr, sizeof(szTaskmgr)/sizeof(TCHAR));
129 hTaskMgr = FindWindow(NULL, szTaskmgr);
130
131 if (hTaskMgr != NULL)
132 {
133 SendMessage(hTaskMgr, WM_SYSCOMMAND, SC_RESTORE, 0);
134 SetForegroundWindow(hTaskMgr);
135 }
136
137 CloseHandle(hMutex);
138 return 0;
139 }
140 else if (!hMutex)
141 {
142 return 1;
143 }
144
145 /* Initialize global variables */
146 hInst = hInstance;
147
148 /* Change our priority class to HIGH */
149 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
150 SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS);
151 CloseHandle(hProcess);
152
153 /* Now lets get the SE_DEBUG_NAME privilege
154 * so that we can debug processes
155 */
156
157 /* Get a token for this process. */
158 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
159 {
160 /* Get the LUID for the debug privilege. */
161 if (LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid))
162 {
163 tkp.PrivilegeCount = 1; /* one privilege to set */
164 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
165
166 /* Get the debug privilege for this process. */
167 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
168 }
169 CloseHandle(hToken);
170 }
171
172 /* Load our settings from the registry */
173 LoadSettings();
174
175 /* Initialize perf data */
176 if (!PerfDataInitialize())
177 {
178 return -1;
179 }
180
181 /*
182 * Set our shutdown parameters: we want to shutdown the very last,
183 * without displaying any end task dialog if needed.
184 */
185 SetProcessShutdownParameters(1, SHUTDOWN_NORETRY);
186
187 DialogBoxW(hInst, (LPCWSTR)IDD_TASKMGR_DIALOG, NULL, TaskManagerWndProc);
188
189 /* Save our settings to the registry */
190 SaveSettings();
191 PerfDataUninitialize();
192 CloseHandle(hMutex);
193 if (hWindowMenu)
194 DestroyMenu(hWindowMenu);
195 return 0;
196 }
197
198 /* Message handler for dialog box. */
199 INT_PTR CALLBACK
200 TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
201 {
202 #if 0
203 HDC hdc;
204 PAINTSTRUCT ps;
205 RECT rc;
206 #endif
207 LPRECT pRC;
208 LPNMHDR pnmh;
209 WINDOWPLACEMENT wp;
210
211 switch (message) {
212 case WM_INITDIALOG:
213 hMainWnd = hDlg;
214 return OnCreate(hDlg);
215
216 case WM_COMMAND:
217 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
218 EndDialog(hDlg, LOWORD(wParam));
219 return TRUE;
220 }
221 /* Process menu commands */
222 switch (LOWORD(wParam))
223 {
224 case ID_FILE_NEW:
225 TaskManager_OnFileNew();
226 break;
227 case ID_OPTIONS_ALWAYSONTOP:
228 TaskManager_OnOptionsAlwaysOnTop();
229 break;
230 case ID_OPTIONS_MINIMIZEONUSE:
231 TaskManager_OnOptionsMinimizeOnUse();
232 break;
233 case ID_OPTIONS_HIDEWHENMINIMIZED:
234 TaskManager_OnOptionsHideWhenMinimized();
235 break;
236 case ID_OPTIONS_SHOW16BITTASKS:
237 TaskManager_OnOptionsShow16BitTasks();
238 break;
239 case ID_RESTORE:
240 TaskManager_OnRestoreMainWindow();
241 break;
242 case ID_VIEW_LARGE:
243 case ID_VIEW_SMALL:
244 case ID_VIEW_DETAILS:
245 ApplicationPage_OnView(LOWORD(wParam));
246 break;
247 case ID_VIEW_SHOWKERNELTIMES:
248 PerformancePage_OnViewShowKernelTimes();
249 break;
250 case ID_VIEW_CPUHISTORY_ONEGRAPHALL:
251 PerformancePage_OnViewCPUHistoryOneGraphAll();
252 break;
253 case ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU:
254 PerformancePage_OnViewCPUHistoryOneGraphPerCPU();
255 break;
256 case ID_VIEW_UPDATESPEED_HIGH:
257 case ID_VIEW_UPDATESPEED_NORMAL:
258 case ID_VIEW_UPDATESPEED_LOW:
259 case ID_VIEW_UPDATESPEED_PAUSED:
260 TaskManager_OnViewUpdateSpeed(LOWORD(wParam));
261 break;
262 case ID_VIEW_SELECTCOLUMNS:
263 ProcessPage_OnViewSelectColumns();
264 break;
265 case ID_VIEW_REFRESH:
266 PostMessageW(hDlg, WM_TIMER, 0, 0);
267 break;
268 case ID_WINDOWS_TILEHORIZONTALLY:
269 ApplicationPage_OnWindowsTile(MDITILE_HORIZONTAL);
270 break;
271 case ID_WINDOWS_TILEVERTICALLY:
272 ApplicationPage_OnWindowsTile(MDITILE_VERTICAL);
273 break;
274 case ID_WINDOWS_MINIMIZE:
275 ApplicationPage_OnWindowsMinimize();
276 break;
277 case ID_WINDOWS_MAXIMIZE:
278 ApplicationPage_OnWindowsMaximize();
279 break;
280 case ID_WINDOWS_CASCADE:
281 ApplicationPage_OnWindowsCascade();
282 break;
283 case ID_WINDOWS_BRINGTOFRONT:
284 ApplicationPage_OnWindowsBringToFront();
285 break;
286 case ID_APPLICATION_PAGE_SWITCHTO:
287 ApplicationPage_OnSwitchTo();
288 break;
289 case ID_APPLICATION_PAGE_ENDTASK:
290 ApplicationPage_OnEndTask();
291 break;
292 case ID_APPLICATION_PAGE_GOTOPROCESS:
293 ApplicationPage_OnGotoProcess();
294 break;
295 case ID_PROCESS_PAGE_ENDPROCESS:
296 ProcessPage_OnEndProcess();
297 break;
298 case ID_PROCESS_PAGE_ENDPROCESSTREE:
299 ProcessPage_OnEndProcessTree();
300 break;
301 case ID_PROCESS_PAGE_DEBUG:
302 ProcessPage_OnDebug();
303 break;
304 case ID_PROCESS_PAGE_SETAFFINITY:
305 ProcessPage_OnSetAffinity();
306 break;
307 case ID_PROCESS_PAGE_SETPRIORITY_REALTIME:
308 DoSetPriority(REALTIME_PRIORITY_CLASS);
309 break;
310 case ID_PROCESS_PAGE_SETPRIORITY_HIGH:
311 DoSetPriority(HIGH_PRIORITY_CLASS);
312 break;
313 case ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL:
314 DoSetPriority(ABOVE_NORMAL_PRIORITY_CLASS);
315 break;
316 case ID_PROCESS_PAGE_SETPRIORITY_NORMAL:
317 DoSetPriority(NORMAL_PRIORITY_CLASS);
318 break;
319 case ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL:
320 DoSetPriority(BELOW_NORMAL_PRIORITY_CLASS);
321 break;
322 case ID_PROCESS_PAGE_SETPRIORITY_LOW:
323 DoSetPriority(IDLE_PRIORITY_CLASS);
324 break;
325 case ID_PROCESS_PAGE_DEBUGCHANNELS:
326 ProcessPage_OnDebugChannels();
327 break;
328
329 /* ShutDown items */
330 case ID_SHUTDOWN_STANDBY:
331 ShutDown_StandBy();
332 break;
333 case ID_SHUTDOWN_HIBERNATE:
334 ShutDown_Hibernate();
335 break;
336 case ID_SHUTDOWN_POWEROFF:
337 ShutDown_PowerOff();
338 break;
339 case ID_SHUTDOWN_REBOOT:
340 ShutDown_Reboot();
341 break;
342 case ID_SHUTDOWN_LOGOFF:
343 ShutDown_LogOffUser();
344 break;
345 case ID_SHUTDOWN_SWITCHUSER:
346 ShutDown_SwitchUser();
347 break;
348 case ID_SHUTDOWN_LOCKCOMPUTER:
349 ShutDown_LockComputer();
350 break;
351 case ID_SHUTDOWN_DISCONNECT:
352 ShutDown_Disconnect();
353 break;
354 case ID_SHUTDOWN_EJECT_COMPUTER:
355 ShutDown_EjectComputer();
356 break;
357
358 case ID_HELP_ABOUT:
359 OnAbout();
360 break;
361 case ID_FILE_EXIT:
362 EndDialog(hDlg, IDOK);
363 break;
364 }
365 break;
366
367 case WM_ONTRAYICON:
368 switch(lParam)
369 {
370 case WM_RBUTTONDOWN:
371 {
372 POINT pt;
373 BOOL OnTop;
374 HMENU hMenu, hPopupMenu;
375
376 GetCursorPos(&pt);
377
378 OnTop = ((GetWindowLongPtrW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
379
380 hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_TRAY_POPUP));
381 hPopupMenu = GetSubMenu(hMenu, 0);
382
383 if(IsWindowVisible(hMainWnd))
384 {
385 DeleteMenu(hPopupMenu, ID_RESTORE, MF_BYCOMMAND);
386 }
387 else
388 {
389 SetMenuDefaultItem(hPopupMenu, ID_RESTORE, FALSE);
390 }
391
392 if(OnTop)
393 {
394 CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_CHECKED);
395 } else
396 {
397 CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_UNCHECKED);
398 }
399
400 SetForegroundWindow(hMainWnd);
401 TrackPopupMenuEx(hPopupMenu, 0, pt.x, pt.y, hMainWnd, NULL);
402
403 DestroyMenu(hMenu);
404 break;
405 }
406 case WM_LBUTTONDBLCLK:
407 TaskManager_OnRestoreMainWindow();
408 break;
409 }
410 break;
411
412 case WM_NOTIFY:
413 pnmh = (LPNMHDR)lParam;
414 if ((pnmh->hwndFrom == hTabWnd) &&
415 (pnmh->idFrom == IDC_TAB))
416 {
417 switch (pnmh->code)
418 {
419 case TCN_SELCHANGE:
420 TaskManager_OnTabWndSelChange();
421 break;
422 case TCN_KEYDOWN:
423 bWasKeyboardInput = TRUE;
424 break;
425 case NM_CLICK:
426 bWasKeyboardInput = FALSE;
427 break;
428 }
429 }
430 break;
431 #if 0
432 case WM_NCPAINT:
433 hdc = GetDC(hDlg);
434 GetClientRect(hDlg, &rc);
435 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
436 ReleaseDC(hDlg, hdc);
437 break;
438
439 case WM_PAINT:
440 hdc = BeginPaint(hDlg, &ps);
441 GetClientRect(hDlg, &rc);
442 Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
443 EndPaint(hDlg, &ps);
444 break;
445 #endif
446 case WM_SIZING:
447 /* Make sure the user is sizing the dialog */
448 /* in an acceptable range */
449 pRC = (LPRECT)lParam;
450 if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT)) {
451 /* If the width is too small enlarge it to the minimum */
452 if (nMinimumWidth > (pRC->right - pRC->left))
453 pRC->left = pRC->right - nMinimumWidth;
454 } else {
455 /* If the width is too small enlarge it to the minimum */
456 if (nMinimumWidth > (pRC->right - pRC->left))
457 pRC->right = pRC->left + nMinimumWidth;
458 }
459 if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) {
460 /* If the height is too small enlarge it to the minimum */
461 if (nMinimumHeight > (pRC->bottom - pRC->top))
462 pRC->top = pRC->bottom - nMinimumHeight;
463 } else {
464 /* If the height is too small enlarge it to the minimum */
465 if (nMinimumHeight > (pRC->bottom - pRC->top))
466 pRC->bottom = pRC->top + nMinimumHeight;
467 }
468 return TRUE;
469 break;
470
471 case WM_SIZE:
472 /* Handle the window sizing in it's own function */
473 OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
474 break;
475
476 case WM_MOVE:
477 /* Handle the window moving in it's own function */
478 OnMove(wParam, LOWORD(lParam), HIWORD(lParam));
479 break;
480
481 case WM_DESTROY:
482 ShowWindow(hDlg, SW_HIDE);
483 TrayIcon_ShellRemoveTrayIcon();
484 wp.length = sizeof(WINDOWPLACEMENT);
485 GetWindowPlacement(hDlg, &wp);
486 TaskManagerSettings.Left = wp.rcNormalPosition.left;
487 TaskManagerSettings.Top = wp.rcNormalPosition.top;
488 TaskManagerSettings.Right = wp.rcNormalPosition.right;
489 TaskManagerSettings.Bottom = wp.rcNormalPosition.bottom;
490 if (IsZoomed(hDlg) || (wp.flags & WPF_RESTORETOMAXIMIZED))
491 TaskManagerSettings.Maximized = TRUE;
492 else
493 TaskManagerSettings.Maximized = FALSE;
494 /* Get rid of the allocated command line cache, if any */
495 PerfDataDeallocCommandLineCache();
496 if (hWindowMenu)
497 DestroyMenu(hWindowMenu);
498 return DefWindowProcW(hDlg, message, wParam, lParam);
499
500 case WM_TIMER:
501 /* Refresh the performance data */
502 PerfDataRefresh();
503 RefreshApplicationPage();
504 RefreshProcessPage();
505 RefreshPerformancePage();
506 TrayIcon_ShellUpdateTrayIcon();
507 break;
508
509 case WM_ENTERMENULOOP:
510 TaskManager_OnEnterMenuLoop(hDlg);
511 break;
512 case WM_EXITMENULOOP:
513 TaskManager_OnExitMenuLoop(hDlg);
514 break;
515 case WM_MENUSELECT:
516 TaskManager_OnMenuSelect(hDlg, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
517 break;
518 case WM_SYSCOLORCHANGE:
519 /* Forward WM_SYSCOLORCHANGE to common controls */
520 SendMessage(hApplicationPageListCtrl, WM_SYSCOLORCHANGE, 0, 0);
521 SendMessage(hProcessPageListCtrl, WM_SYSCOLORCHANGE, 0, 0);
522 SendMessage(hProcessPageHeaderCtrl, WM_SYSCOLORCHANGE, 0, 0);
523 break;
524 }
525
526 return 0;
527 }
528
529 void FillSolidRect(HDC hDC, LPCRECT lpRect, COLORREF clr)
530 {
531 SetBkColor(hDC, clr);
532 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
533 }
534
535 void FillSolidRect2(HDC hDC, int x, int y, int cx, int cy, COLORREF clr)
536 {
537 RECT rect;
538
539 SetBkColor(hDC, clr);
540 rect.left = x;
541 rect.top = y;
542 rect.right = x + cx;
543 rect.bottom = y + cy;
544 ExtTextOutW(hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
545 }
546
547 void Draw3dRect(HDC hDC, int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight)
548 {
549 FillSolidRect2(hDC, x, y, cx - 1, 1, clrTopLeft);
550 FillSolidRect2(hDC, x, y, 1, cy - 1, clrTopLeft);
551 FillSolidRect2(hDC, x + cx, y, -1, cy, clrBottomRight);
552 FillSolidRect2(hDC, x, y + cy, cx, -1, clrBottomRight);
553 }
554
555 void Draw3dRect2(HDC hDC, LPRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight)
556 {
557 Draw3dRect(hDC, lpRect->left, lpRect->top, lpRect->right - lpRect->left,
558 lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
559 }
560
561 static void SetUpdateSpeed(HWND hWnd)
562 {
563 /* Setup update speed (pause=fall down) */
564 switch (TaskManagerSettings.UpdateSpeed) {
565 case ID_VIEW_UPDATESPEED_HIGH:
566 SetTimer(hWnd, 1, 1000, NULL);
567 break;
568 case ID_VIEW_UPDATESPEED_NORMAL:
569 SetTimer(hWnd, 1, 2000, NULL);
570 break;
571 case ID_VIEW_UPDATESPEED_LOW:
572 SetTimer(hWnd, 1, 4000, NULL);
573 break;
574 }
575 }
576
577 BOOL OnCreate(HWND hWnd)
578 {
579 HMENU hMenu;
580 HMENU hEditMenu;
581 HMENU hViewMenu;
582 HMENU hShutMenu;
583 HMENU hUpdateSpeedMenu;
584 HMENU hCPUHistoryMenu;
585 int nActivePage;
586 int nParts[3];
587 RECT rc;
588 WCHAR szTemp[256];
589 WCHAR szLogOffItem[MAX_PATH];
590 LPWSTR lpUserName;
591 TCITEM item;
592 DWORD len = 0;
593
594 SendMessageW(hMainWnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW(hInst, MAKEINTRESOURCEW(IDI_TASKMANAGER)));
595
596 /* Initialize the Windows Common Controls DLL */
597 InitCommonControls();
598
599 /* Get the minimum window sizes */
600 GetWindowRect(hWnd, &rc);
601 nMinimumWidth = (rc.right - rc.left);
602 nMinimumHeight = (rc.bottom - rc.top);
603
604 /* Create the status bar */
605 hStatusWnd = CreateStatusWindow(WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|SBT_NOBORDERS, L"", hWnd, STATUS_WINDOW);
606 if(!hStatusWnd)
607 return FALSE;
608
609 /* Create the status bar panes */
610 nParts[0] = STATUS_SIZE1;
611 nParts[1] = STATUS_SIZE2;
612 nParts[2] = STATUS_SIZE3;
613 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts);
614
615 /* Create tab pages */
616 hTabWnd = GetDlgItem(hWnd, IDC_TAB);
617 #if 1
618 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hWnd, ApplicationPageWndProc); EnableDialogTheme(hApplicationPage);
619 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hWnd, ProcessPageWndProc); EnableDialogTheme(hProcessPage);
620 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hWnd, PerformancePageWndProc); EnableDialogTheme(hPerformancePage);
621 #else
622 hApplicationPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE), hTabWnd, ApplicationPageWndProc); EnableDialogTheme(hApplicationPage);
623 hProcessPage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PROCESS_PAGE), hTabWnd, ProcessPageWndProc); EnableDialogTheme(hProcessPage);
624 hPerformancePage = CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE), hTabWnd, PerformancePageWndProc); EnableDialogTheme(hPerformancePage);
625 #endif
626
627 /* Insert tabs */
628 LoadStringW(hInst, IDS_TAB_APPS, szTemp, 256);
629 memset(&item, 0, sizeof(TCITEM));
630 item.mask = TCIF_TEXT;
631 item.pszText = szTemp;
632 (void)TabCtrl_InsertItem(hTabWnd, 0, &item);
633 LoadStringW(hInst, IDS_TAB_PROCESSES, szTemp, 256);
634 memset(&item, 0, sizeof(TCITEM));
635 item.mask = TCIF_TEXT;
636 item.pszText = szTemp;
637 (void)TabCtrl_InsertItem(hTabWnd, 1, &item);
638 LoadStringW(hInst, IDS_TAB_PERFORMANCE, szTemp, 256);
639 memset(&item, 0, sizeof(TCITEM));
640 item.mask = TCIF_TEXT;
641 item.pszText = szTemp;
642 (void)TabCtrl_InsertItem(hTabWnd, 2, &item);
643
644 /* Size everything correctly */
645 GetClientRect(hWnd, &rc);
646 nOldWidth = rc.right;
647 nOldHeight = rc.bottom;
648 /* nOldStartX = rc.left; */
649 /*nOldStartY = rc.top; */
650
651 #define PAGE_OFFSET_LEFT 17
652 #define PAGE_OFFSET_TOP 72
653 #define PAGE_OFFSET_WIDTH (PAGE_OFFSET_LEFT*2)
654 #define PAGE_OFFSET_HEIGHT (PAGE_OFFSET_TOP+32)
655
656 if ((TaskManagerSettings.Left != 0) ||
657 (TaskManagerSettings.Top != 0) ||
658 (TaskManagerSettings.Right != 0) ||
659 (TaskManagerSettings.Bottom != 0))
660 {
661 MoveWindow(hWnd, TaskManagerSettings.Left, TaskManagerSettings.Top, TaskManagerSettings.Right - TaskManagerSettings.Left, TaskManagerSettings.Bottom - TaskManagerSettings.Top, TRUE);
662 #ifdef __GNUC__TEST__
663 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);
664 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);
665 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);
666 #endif
667 }
668 if (TaskManagerSettings.Maximized)
669 ShowWindow(hWnd, SW_MAXIMIZE);
670
671 /* Set the always on top style */
672 hMenu = GetMenu(hWnd);
673 hEditMenu = GetSubMenu(hMenu, 1);
674 hViewMenu = GetSubMenu(hMenu, 2);
675 hShutMenu = GetSubMenu(hMenu, 4);
676 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
677 hCPUHistoryMenu = GetSubMenu(hViewMenu, 7);
678
679 /* Check or uncheck the always on top menu item */
680 if (TaskManagerSettings.AlwaysOnTop) {
681 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_CHECKED);
682 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
683 } else {
684 CheckMenuItem(hEditMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND|MF_UNCHECKED);
685 SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
686 }
687
688 /* Check or uncheck the minimize on use menu item */
689 if (TaskManagerSettings.MinimizeOnUse)
690 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_CHECKED);
691 else
692 CheckMenuItem(hEditMenu, ID_OPTIONS_MINIMIZEONUSE, MF_BYCOMMAND|MF_UNCHECKED);
693
694 /* Check or uncheck the hide when minimized menu item */
695 if (TaskManagerSettings.HideWhenMinimized)
696 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_CHECKED);
697 else
698 CheckMenuItem(hEditMenu, ID_OPTIONS_HIDEWHENMINIMIZED, MF_BYCOMMAND|MF_UNCHECKED);
699
700 /* Check or uncheck the show 16-bit tasks menu item */
701 if (TaskManagerSettings.Show16BitTasks)
702 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED);
703 else
704 CheckMenuItem(hEditMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_UNCHECKED);
705
706 /* Set the view mode */
707 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND);
708
709 if (TaskManagerSettings.ShowKernelTimes)
710 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
711 else
712 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
713
714 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, TaskManagerSettings.UpdateSpeed, MF_BYCOMMAND);
715
716 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
717 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
718 else
719 CheckMenuRadioItem(hCPUHistoryMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
720
721 nActivePage = TaskManagerSettings.ActiveTabPage;
722 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 0);
723 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 1);
724 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 2);
725 TabCtrl_SetCurFocus/*Sel*/(hTabWnd, nActivePage);
726
727 /* Set the username in the "Log Off %s" item of the Shutdown menu */
728
729 /* 1- Get the menu item text and store it temporarily */
730 GetMenuStringW(hShutMenu, ID_SHUTDOWN_LOGOFF, szTemp, 256, MF_BYCOMMAND);
731
732 /* 2- Retrieve the username length first, then allocate a buffer for it and call it again */
733 if (!GetUserNameW(NULL, &len) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
734 {
735 lpUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
736 if (lpUserName && GetUserNameW(lpUserName, &len))
737 {
738 _snwprintf(szLogOffItem, sizeof(szLogOffItem)/sizeof(szLogOffItem[0]), szTemp, lpUserName);
739 szLogOffItem[sizeof(szLogOffItem)/sizeof(szLogOffItem[0]) - 1] = UNICODE_NULL;
740 }
741 else
742 {
743 _snwprintf(szLogOffItem, sizeof(szLogOffItem)/sizeof(szLogOffItem[0]), szTemp, L"n/a");
744 }
745
746 if (lpUserName) HeapFree(GetProcessHeap(), 0, lpUserName);
747 }
748 else
749 {
750 _snwprintf(szLogOffItem, sizeof(szLogOffItem)/sizeof(szLogOffItem[0]), szTemp, L"n/a");
751 }
752
753 /* 3- Set the menu item text to its formatted counterpart */
754 ModifyMenuW(hShutMenu, ID_SHUTDOWN_LOGOFF, MF_BYCOMMAND | MF_STRING, ID_SHUTDOWN_LOGOFF, szLogOffItem);
755
756 /* Setup update speed */
757 SetUpdateSpeed(hWnd);
758
759 /*
760 * Refresh the performance data
761 * Sample it twice so we can establish
762 * the delta values & cpu usage
763 */
764 PerfDataRefresh();
765 PerfDataRefresh();
766
767 RefreshApplicationPage();
768 RefreshProcessPage();
769 RefreshPerformancePage();
770
771 TrayIcon_ShellAddTrayIcon();
772
773 return TRUE;
774 }
775
776 /* OnMove()
777 * This function handles all the moving events for the application
778 * It moves every child window that needs moving
779 */
780 void OnMove( WPARAM nType, int cx, int cy )
781 {
782 #ifdef __GNUC__TEST__
783 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);
784 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);
785 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);
786 #endif
787 }
788
789 /* OnSize()
790 * This function handles all the sizing events for the application
791 * It re-sizes every window, and child window that needs re-sizing
792 */
793 void OnSize( WPARAM nType, int cx, int cy )
794 {
795 int nParts[3];
796 int nXDifference;
797 int nYDifference;
798 RECT rc;
799
800 if (nType == SIZE_MINIMIZED)
801 {
802 if(TaskManagerSettings.HideWhenMinimized)
803 {
804 ShowWindow(hMainWnd, SW_HIDE);
805 }
806 return;
807 }
808
809 nXDifference = cx - nOldWidth;
810 nYDifference = cy - nOldHeight;
811 nOldWidth = cx;
812 nOldHeight = cy;
813
814 /* Update the status bar size */
815 GetWindowRect(hStatusWnd, &rc);
816 SendMessageW(hStatusWnd, WM_SIZE, nType, MAKELPARAM(cx,rc.bottom - rc.top));
817
818 /* Update the status bar pane sizes */
819 nParts[0] = bInMenuLoop ? -1 : STATUS_SIZE1;
820 nParts[1] = STATUS_SIZE2;
821 nParts[2] = cx;
822 SendMessageW(hStatusWnd, SB_SETPARTS, bInMenuLoop ? 1 : 3, (LPARAM) (LPINT) nParts);
823
824 /* Resize the tab control */
825 GetWindowRect(hTabWnd, &rc);
826 cx = (rc.right - rc.left) + nXDifference;
827 cy = (rc.bottom - rc.top) + nYDifference;
828 SetWindowPos(hTabWnd, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
829
830 /* Resize the application page */
831 GetWindowRect(hApplicationPage, &rc);
832 cx = (rc.right - rc.left) + nXDifference;
833 cy = (rc.bottom - rc.top) + nYDifference;
834 SetWindowPos(hApplicationPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
835
836 /* Resize the process page */
837 GetWindowRect(hProcessPage, &rc);
838 cx = (rc.right - rc.left) + nXDifference;
839 cy = (rc.bottom - rc.top) + nYDifference;
840 SetWindowPos(hProcessPage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
841
842 /* Resize the performance page */
843 GetWindowRect(hPerformancePage, &rc);
844 cx = (rc.right - rc.left) + nXDifference;
845 cy = (rc.bottom - rc.top) + nYDifference;
846 SetWindowPos(hPerformancePage, NULL, 0, 0, cx, cy, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOZORDER);
847 }
848
849 void LoadSettings(void)
850 {
851 HKEY hKey;
852 WCHAR szSubKey[] = L"Software\\ReactOS\\TaskManager";
853 int i;
854 DWORD dwSize;
855
856 /* Window size & position settings */
857 TaskManagerSettings.Maximized = FALSE;
858 TaskManagerSettings.Left = 0;
859 TaskManagerSettings.Top = 0;
860 TaskManagerSettings.Right = 0;
861 TaskManagerSettings.Bottom = 0;
862
863 /* Tab settings */
864 TaskManagerSettings.ActiveTabPage = 0;
865
866 /* Options menu settings */
867 TaskManagerSettings.AlwaysOnTop = FALSE;
868 TaskManagerSettings.MinimizeOnUse = TRUE;
869 TaskManagerSettings.HideWhenMinimized = TRUE;
870 TaskManagerSettings.Show16BitTasks = TRUE;
871
872 /* Update speed settings */
873 TaskManagerSettings.UpdateSpeed = ID_VIEW_UPDATESPEED_NORMAL;
874
875 /* Applications page settings */
876 TaskManagerSettings.ViewMode = ID_VIEW_DETAILS;
877
878 /* Processes page settings */
879 TaskManagerSettings.ShowProcessesFromAllUsers = FALSE; /* Server-only? */
880
881 for (i = 0; i < COLUMN_NMAX; i++) {
882 TaskManagerSettings.Columns[i] = ColumnPresets[i].bDefaults;
883 TaskManagerSettings.ColumnOrderArray[i] = i;
884 TaskManagerSettings.ColumnSizeArray[i] = ColumnPresets[i].size;
885 }
886
887 TaskManagerSettings.SortColumn = COLUMN_IMAGENAME;
888 TaskManagerSettings.SortAscending = TRUE;
889
890 /* Performance page settings */
891 TaskManagerSettings.CPUHistory_OneGraphPerCPU = TRUE;
892 TaskManagerSettings.ShowKernelTimes = FALSE;
893
894 /* Open the key */
895 if (RegOpenKeyExW(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
896 return;
897 /* Read the settings */
898 dwSize = sizeof(TASKMANAGER_SETTINGS);
899 RegQueryValueExW(hKey, L"Preferences", NULL, NULL, (LPBYTE)&TaskManagerSettings, &dwSize);
900
901 /*
902 * ATM, the 'ImageName' column is always visible
903 * (and grayed in configuration dialog)
904 * This will avoid troubles if the registry gets corrupted.
905 */
906 TaskManagerSettings.Column_ImageName = TRUE;
907
908 /* Close the key */
909 RegCloseKey(hKey);
910 }
911
912 void SaveSettings(void)
913 {
914 HKEY hKey;
915 WCHAR szSubKey[] = L"Software\\ReactOS\\TaskManager";
916
917 /* Open (or create) the key */
918 if (RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
919 return;
920 /* Save the settings */
921 RegSetValueExW(hKey, L"Preferences", 0, REG_BINARY, (LPBYTE)&TaskManagerSettings, sizeof(TASKMANAGER_SETTINGS));
922 /* Close the key */
923 RegCloseKey(hKey);
924 }
925
926 void TaskManager_OnRestoreMainWindow(void)
927 {
928 //HMENU hMenu, hOptionsMenu;
929 BOOL OnTop;
930
931 //hMenu = GetMenu(hMainWnd);
932 //hOptionsMenu = GetSubMenu(hMenu, OPTIONS_MENU_INDEX);
933 OnTop = ((GetWindowLongPtrW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
934
935 OpenIcon(hMainWnd);
936 SetForegroundWindow(hMainWnd);
937 SetWindowPos(hMainWnd, (OnTop ? HWND_TOPMOST : HWND_TOP), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
938 }
939
940 void TaskManager_OnEnterMenuLoop(HWND hWnd)
941 {
942 int nParts;
943
944 /* Update the status bar pane sizes */
945 nParts = -1;
946 SendMessageW(hStatusWnd, SB_SETPARTS, 1, (LPARAM) (LPINT)&nParts);
947 bInMenuLoop = TRUE;
948 SendMessageW(hStatusWnd, SB_SETTEXT, (WPARAM)0, (LPARAM)L"");
949 }
950
951 void TaskManager_OnExitMenuLoop(HWND hWnd)
952 {
953 RECT rc;
954 int nParts[3];
955 WCHAR text[260];
956 WCHAR szCpuUsage[256], szProcesses[256];
957
958 LoadStringW(hInst, IDS_STATUS_CPUUSAGE, szCpuUsage, 256);
959 LoadStringW(hInst, IDS_STATUS_PROCESSES, szProcesses, 256);
960
961 bInMenuLoop = FALSE;
962 /* Update the status bar pane sizes */
963 GetClientRect(hWnd, &rc);
964 nParts[0] = STATUS_SIZE1;
965 nParts[1] = STATUS_SIZE2;
966 nParts[2] = rc.right;
967 SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts);
968 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)L"");
969 wsprintfW(text, szCpuUsage, PerfDataGetProcessorUsage());
970 SendMessageW(hStatusWnd, SB_SETTEXT, 1, (LPARAM)text);
971 wsprintfW(text, szProcesses, PerfDataGetProcessCount());
972 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)text);
973 }
974
975 void TaskManager_OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
976 {
977 WCHAR str[100];
978
979 wcscpy(str, L"");
980 if (LoadStringW(hInst, nItemID, str, 100)) {
981 /* load appropriate string */
982 LPWSTR lpsz = str;
983 /* first newline terminates actual string */
984 lpsz = wcschr(lpsz, '\n');
985 if (lpsz != NULL)
986 *lpsz = '\0';
987 }
988 SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)str);
989 }
990
991 void TaskManager_OnViewUpdateSpeed(DWORD dwSpeed)
992 {
993 HMENU hMenu;
994 HMENU hViewMenu;
995 HMENU hUpdateSpeedMenu;
996
997 hMenu = GetMenu(hMainWnd);
998 hViewMenu = GetSubMenu(hMenu, 2);
999 hUpdateSpeedMenu = GetSubMenu(hViewMenu, 1);
1000
1001 TaskManagerSettings.UpdateSpeed = dwSpeed;
1002 CheckMenuRadioItem(hUpdateSpeedMenu, ID_VIEW_UPDATESPEED_HIGH, ID_VIEW_UPDATESPEED_PAUSED, dwSpeed, MF_BYCOMMAND);
1003
1004 KillTimer(hMainWnd, 1);
1005
1006 SetUpdateSpeed(hMainWnd);
1007 }
1008
1009 void TaskManager_OnTabWndSelChange(void)
1010 {
1011 int i;
1012 HMENU hMenu;
1013 HMENU hOptionsMenu;
1014 HMENU hViewMenu;
1015 HMENU hSubMenu;
1016 WCHAR szTemp[256];
1017 SYSTEM_INFO sysInfo;
1018
1019 hMenu = GetMenu(hMainWnd);
1020 hViewMenu = GetSubMenu(hMenu, 2);
1021 hOptionsMenu = GetSubMenu(hMenu, 1);
1022 TaskManagerSettings.ActiveTabPage = TabCtrl_GetCurSel(hTabWnd);
1023 for (i = GetMenuItemCount(hViewMenu) - 1; i > 2; i--) {
1024 hSubMenu = GetSubMenu(hViewMenu, i);
1025 if (hSubMenu)
1026 DestroyMenu(hSubMenu);
1027 RemoveMenu(hViewMenu, i, MF_BYPOSITION);
1028 }
1029 RemoveMenu(hOptionsMenu, 3, MF_BYPOSITION);
1030 if (hWindowMenu)
1031 DestroyMenu(hWindowMenu);
1032 switch (TaskManagerSettings.ActiveTabPage) {
1033 case 0:
1034 ShowWindow(hApplicationPage, SW_SHOW);
1035 ShowWindow(hProcessPage, SW_HIDE);
1036 ShowWindow(hPerformancePage, SW_HIDE);
1037 BringWindowToTop(hApplicationPage);
1038
1039 LoadStringW(hInst, IDS_MENU_LARGEICONS, szTemp, 256);
1040 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_LARGE, szTemp);
1041
1042 LoadStringW(hInst, IDS_MENU_SMALLICONS, szTemp, 256);
1043 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SMALL, szTemp);
1044
1045 LoadStringW(hInst, IDS_MENU_DETAILS, szTemp, 256);
1046 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_DETAILS, szTemp);
1047
1048 if (GetMenuItemCount(hMenu) <= 5) {
1049 hWindowMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_WINDOWSMENU));
1050
1051 LoadStringW(hInst, IDS_MENU_WINDOWS, szTemp, 256);
1052 InsertMenuW(hMenu, 3, MF_BYPOSITION|MF_POPUP, (UINT_PTR) hWindowMenu, szTemp);
1053
1054 DrawMenuBar(hMainWnd);
1055 }
1056 CheckMenuRadioItem(hViewMenu, ID_VIEW_LARGE, ID_VIEW_DETAILS, TaskManagerSettings.ViewMode, MF_BYCOMMAND);
1057
1058 /*
1059 * Give the application list control focus
1060 */
1061 if (!bWasKeyboardInput)
1062 SetFocus(hApplicationPageListCtrl);
1063 break;
1064
1065 case 1:
1066 ShowWindow(hApplicationPage, SW_HIDE);
1067 ShowWindow(hProcessPage, SW_SHOW);
1068 ShowWindow(hPerformancePage, SW_HIDE);
1069 BringWindowToTop(hProcessPage);
1070
1071 LoadStringW(hInst, IDS_MENU_SELECTCOLUMNS, szTemp, 256);
1072 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SELECTCOLUMNS, szTemp);
1073
1074 LoadStringW(hInst, IDS_MENU_16BITTASK, szTemp, 256);
1075 AppendMenuW(hOptionsMenu, MF_STRING, ID_OPTIONS_SHOW16BITTASKS, szTemp);
1076
1077 if (TaskManagerSettings.Show16BitTasks)
1078 CheckMenuItem(hOptionsMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED);
1079 if (GetMenuItemCount(hMenu) > 5)
1080 {
1081 DeleteMenu(hMenu, 3, MF_BYPOSITION);
1082 DrawMenuBar(hMainWnd);
1083 }
1084 /*
1085 * Give the process list control focus
1086 */
1087 if (!bWasKeyboardInput)
1088 SetFocus(hProcessPageListCtrl);
1089 break;
1090
1091 case 2:
1092 ShowWindow(hApplicationPage, SW_HIDE);
1093 ShowWindow(hProcessPage, SW_HIDE);
1094 ShowWindow(hPerformancePage, SW_SHOW);
1095 BringWindowToTop(hPerformancePage);
1096 if (GetMenuItemCount(hMenu) > 5) {
1097 DeleteMenu(hMenu, 3, MF_BYPOSITION);
1098 DrawMenuBar(hMainWnd);
1099 }
1100
1101 GetSystemInfo(&sysInfo);
1102
1103 /* Hide CPU graph options on single CPU systems */
1104 if (sysInfo.dwNumberOfProcessors > 1)
1105 {
1106 hSubMenu = CreatePopupMenu();
1107
1108 LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256);
1109 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp);
1110
1111 LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256);
1112 AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp);
1113
1114 LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256);
1115 AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp);
1116
1117 if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
1118 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
1119 else
1120 CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
1121 }
1122
1123 LoadStringW(hInst, IDS_MENU_SHOWKERNELTIMES, szTemp, 256);
1124 AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, szTemp);
1125
1126 if (TaskManagerSettings.ShowKernelTimes)
1127 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
1128 else
1129 CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
1130
1131 /*
1132 * Give the tab control focus
1133 */
1134 if (!bWasKeyboardInput)
1135 SetFocus(hTabWnd);
1136 break;
1137 }
1138 }
1139
1140 VOID ShowWin32Error(DWORD dwError)
1141 {
1142 LPWSTR lpMessageBuffer;
1143
1144 if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
1145 NULL,
1146 dwError,
1147 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1148 (LPWSTR)&lpMessageBuffer,
1149 0, NULL) != 0)
1150 {
1151 MessageBoxW(hMainWnd, lpMessageBuffer, NULL, MB_OK | MB_ICONERROR);
1152 if (lpMessageBuffer) LocalFree(lpMessageBuffer);
1153 }
1154 }
1155
1156 LPWSTR GetLastErrorText(LPWSTR lpszBuf, DWORD dwSize)
1157 {
1158 DWORD dwRet;
1159 LPWSTR lpszTemp = NULL;
1160
1161 dwRet = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
1162 NULL,
1163 GetLastError(),
1164 LANG_NEUTRAL,
1165 (LPWSTR)&lpszTemp,
1166 0,
1167 NULL );
1168
1169 /* supplied buffer is not long enough */
1170 if (!dwRet || ( (long)dwSize < (long)dwRet+14)) {
1171 lpszBuf[0] = L'\0';
1172 } else {
1173 lpszTemp[lstrlenW(lpszTemp)-2] = L'\0'; /*remove cr and newline character */
1174 wsprintfW(lpszBuf, L"%s (0x%x)", lpszTemp, (int)GetLastError());
1175 }
1176 if (lpszTemp) {
1177 LocalFree((HLOCAL)lpszTemp);
1178 }
1179 return lpszBuf;
1180 }
1181
1182 DWORD EndLocalThread(HANDLE *hThread, DWORD dwThread)
1183 {
1184 DWORD dwExitCodeThread = 0;
1185
1186 if (*hThread != NULL) {
1187 PostThreadMessage(dwThread,WM_QUIT,0,0);
1188 for (;;) {
1189 MSG msg;
1190
1191 if (WAIT_OBJECT_0 == WaitForSingleObject(*hThread, 500))
1192 break;
1193 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
1194 TranslateMessage(&msg);
1195 DispatchMessage(&msg);
1196 }
1197 }
1198 GetExitCodeThread(*hThread, &dwExitCodeThread);
1199 CloseHandle(*hThread);
1200 *hThread = NULL;
1201 }
1202 return dwExitCodeThread;
1203 }
1204