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