4 * taskmgr.c : Defines the entry point for the application.
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7 * 2005 Klemens Friedl <frik85@reactos.at>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 #define STATUS_WINDOW 2001
34 /* Global Variables: */
35 HINSTANCE hInst
; /* current instance */
37 HWND hMainWnd
; /* Main Window */
38 HWND hStatusWnd
; /* Status Bar Window */
39 HWND hTabWnd
; /* Tab Control Window */
41 int nMinimumWidth
; /* Minimum width of the dialog (OnSize()'s cx) */
42 int nMinimumHeight
; /* Minimum height of the dialog (OnSize()'s cy) */
44 int nOldWidth
; /* Holds the previous client area width */
45 int nOldHeight
; /* Holds the previous client area height */
47 BOOL bInMenuLoop
= FALSE
; /* Tells us if we are in the menu loop */
49 TASKMANAGER_SETTINGS TaskManagerSettings
;
51 ////////////////////////////////////////////////////////////////////////////////
52 // Taken from WinSpy++ 1.7
53 // http://www.catch22.net/software/winspy
54 // Copyright (c) 2002 by J Brown
58 // Copied from uxtheme.h
59 // If you have this new header, then delete these and
60 // #include <uxtheme.h> instead!
62 #define ETDT_DISABLE 0x00000001
63 #define ETDT_ENABLE 0x00000002
64 #define ETDT_USETABTEXTURE 0x00000004
65 #define ETDT_ENABLETAB (ETDT_ENABLE | ETDT_USETABTEXTURE)
68 typedef HRESULT (WINAPI
* ETDTProc
) (HWND
, DWORD
);
71 // Try to call EnableThemeDialogTexture, if uxtheme.dll is present
73 BOOL
EnableDialogTheme(HWND hwnd
)
76 ETDTProc fnEnableThemeDialogTexture
;
78 hUXTheme
= LoadLibraryA("uxtheme.dll");
82 fnEnableThemeDialogTexture
=
83 (ETDTProc
)GetProcAddress(hUXTheme
, "EnableThemeDialogTexture");
85 if(fnEnableThemeDialogTexture
)
87 fnEnableThemeDialogTexture(hwnd
, ETDT_ENABLETAB
);
89 FreeLibrary(hUXTheme
);
94 // Failed to locate API!
95 FreeLibrary(hUXTheme
);
101 // Not running under XP? Just fail gracefully
106 int APIENTRY
wWinMain(HINSTANCE hInstance
,
107 HINSTANCE hPrevInstance
,
113 TOKEN_PRIVILEGES tkp
;
116 /* check wether we're already running or not */
117 hMutex
= CreateMutexW(NULL
, TRUE
, L
"taskmgrros");
118 if (hMutex
&& GetLastError() == ERROR_ALREADY_EXISTS
)
120 /* Restore existing taskmanager and bring window to front */
121 /* Relies on the fact that the application title string and window title are the same */
123 TCHAR szTaskmgr
[128];
125 LoadString(hInst
, IDS_APP_TITLE
, szTaskmgr
, sizeof(szTaskmgr
)/sizeof(TCHAR
));
126 hTaskMgr
= FindWindow(NULL
, szTaskmgr
);
128 if (hTaskMgr
!= NULL
)
130 SendMessage(hTaskMgr
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
131 SetForegroundWindow(hTaskMgr
);
142 /* Initialize global variables */
145 /* Change our priority class to HIGH */
146 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, FALSE
, GetCurrentProcessId());
147 SetPriorityClass(hProcess
, HIGH_PRIORITY_CLASS
);
148 CloseHandle(hProcess
);
150 /* Now lets get the SE_DEBUG_NAME privilege
151 * so that we can debug processes
154 /* Get a token for this process. */
155 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, &hToken
)) {
156 /* Get the LUID for the debug privilege. */
157 LookupPrivilegeValueW(NULL
, SE_DEBUG_NAME
, &tkp
.Privileges
[0].Luid
);
159 tkp
.PrivilegeCount
= 1; /* one privilege to set */
160 tkp
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
162 /* Get the debug privilege for this process. */
163 AdjustTokenPrivileges(hToken
, FALSE
, &tkp
, 0, (PTOKEN_PRIVILEGES
)NULL
, 0);
167 /* Load our settings from the registry */
170 /* Initialize perf data */
171 if (!PerfDataInitialize()) {
176 * Set our shutdown parameters: we want to shutdown the very last,
177 * without displaying any end task dialog if needed.
179 SetProcessShutdownParameters(1, SHUTDOWN_NORETRY
);
181 DialogBoxW(hInst
, (LPCWSTR
)IDD_TASKMGR_DIALOG
, NULL
, TaskManagerWndProc
);
183 /* Save our settings to the registry */
185 PerfDataUninitialize();
190 /* Message handler for dialog box. */
192 TaskManagerWndProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
206 return OnCreate(hDlg
);
209 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
) {
210 EndDialog(hDlg
, LOWORD(wParam
));
213 /* Process menu commands */
214 switch (LOWORD(wParam
))
217 TaskManager_OnFileNew();
219 case ID_OPTIONS_ALWAYSONTOP
:
220 TaskManager_OnOptionsAlwaysOnTop();
222 case ID_OPTIONS_MINIMIZEONUSE
:
223 TaskManager_OnOptionsMinimizeOnUse();
225 case ID_OPTIONS_HIDEWHENMINIMIZED
:
226 TaskManager_OnOptionsHideWhenMinimized();
228 case ID_OPTIONS_SHOW16BITTASKS
:
229 TaskManager_OnOptionsShow16BitTasks();
232 TaskManager_OnRestoreMainWindow();
236 case ID_VIEW_DETAILS
:
237 ApplicationPage_OnView(LOWORD(wParam
));
239 case ID_VIEW_SHOWKERNELTIMES
:
240 PerformancePage_OnViewShowKernelTimes();
242 case ID_VIEW_CPUHISTORY_ONEGRAPHALL
:
243 PerformancePage_OnViewCPUHistoryOneGraphAll();
245 case ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU
:
246 PerformancePage_OnViewCPUHistoryOneGraphPerCPU();
248 case ID_VIEW_UPDATESPEED_HIGH
:
249 case ID_VIEW_UPDATESPEED_NORMAL
:
250 case ID_VIEW_UPDATESPEED_LOW
:
251 case ID_VIEW_UPDATESPEED_PAUSED
:
252 TaskManager_OnViewUpdateSpeed(LOWORD(wParam
));
254 case ID_VIEW_SELECTCOLUMNS
:
255 ProcessPage_OnViewSelectColumns();
257 case ID_VIEW_REFRESH
:
258 PostMessageW(hDlg
, WM_TIMER
, 0, 0);
260 case ID_WINDOWS_TILEHORIZONTALLY
:
261 ApplicationPage_OnWindowsTile(MDITILE_HORIZONTAL
);
263 case ID_WINDOWS_TILEVERTICALLY
:
264 ApplicationPage_OnWindowsTile(MDITILE_VERTICAL
);
266 case ID_WINDOWS_MINIMIZE
:
267 ApplicationPage_OnWindowsMinimize();
269 case ID_WINDOWS_MAXIMIZE
:
270 ApplicationPage_OnWindowsMaximize();
272 case ID_WINDOWS_CASCADE
:
273 ApplicationPage_OnWindowsCascade();
275 case ID_WINDOWS_BRINGTOFRONT
:
276 ApplicationPage_OnWindowsBringToFront();
278 case ID_APPLICATION_PAGE_SWITCHTO
:
279 ApplicationPage_OnSwitchTo();
281 case ID_APPLICATION_PAGE_ENDTASK
:
282 ApplicationPage_OnEndTask();
284 case ID_APPLICATION_PAGE_GOTOPROCESS
:
285 ApplicationPage_OnGotoProcess();
287 case ID_PROCESS_PAGE_ENDPROCESS
:
288 ProcessPage_OnEndProcess();
290 case ID_PROCESS_PAGE_ENDPROCESSTREE
:
291 ProcessPage_OnEndProcessTree();
293 case ID_PROCESS_PAGE_DEBUG
:
294 ProcessPage_OnDebug();
296 case ID_PROCESS_PAGE_SETAFFINITY
:
297 ProcessPage_OnSetAffinity();
299 case ID_PROCESS_PAGE_SETPRIORITY_REALTIME
:
300 DoSetPriority(REALTIME_PRIORITY_CLASS
);
302 case ID_PROCESS_PAGE_SETPRIORITY_HIGH
:
303 DoSetPriority(HIGH_PRIORITY_CLASS
);
305 case ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL
:
306 DoSetPriority(ABOVE_NORMAL_PRIORITY_CLASS
);
308 case ID_PROCESS_PAGE_SETPRIORITY_NORMAL
:
309 DoSetPriority(NORMAL_PRIORITY_CLASS
);
311 case ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL
:
312 DoSetPriority(BELOW_NORMAL_PRIORITY_CLASS
);
314 case ID_PROCESS_PAGE_SETPRIORITY_LOW
:
315 DoSetPriority(IDLE_PRIORITY_CLASS
);
317 case ID_PROCESS_PAGE_DEBUGCHANNELS
:
318 ProcessPage_OnDebugChannels();
324 EndDialog(hDlg
, IDOK
);
336 HMENU hMenu
, hPopupMenu
;
340 OnTop
= ((GetWindowLongPtrW(hMainWnd
, GWL_EXSTYLE
) & WS_EX_TOPMOST
) != 0);
342 hMenu
= LoadMenuW(hInst
, MAKEINTRESOURCEW(IDR_TRAY_POPUP
));
343 hPopupMenu
= GetSubMenu(hMenu
, 0);
345 if(IsWindowVisible(hMainWnd
))
347 DeleteMenu(hPopupMenu
, ID_RESTORE
, MF_BYCOMMAND
);
351 SetMenuDefaultItem(hPopupMenu
, ID_RESTORE
, FALSE
);
356 CheckMenuItem(hPopupMenu
, ID_OPTIONS_ALWAYSONTOP
, MF_BYCOMMAND
| MF_CHECKED
);
359 CheckMenuItem(hPopupMenu
, ID_OPTIONS_ALWAYSONTOP
, MF_BYCOMMAND
| MF_UNCHECKED
);
362 SetForegroundWindow(hMainWnd
);
363 TrackPopupMenuEx(hPopupMenu
, 0, pt
.x
, pt
.y
, hMainWnd
, NULL
);
368 case WM_LBUTTONDBLCLK
:
369 TaskManager_OnRestoreMainWindow();
375 pnmh
= (LPNMHDR
)lParam
;
376 if ((pnmh
->hwndFrom
== hTabWnd
) &&
377 (pnmh
->idFrom
== IDC_TAB
) &&
378 (pnmh
->code
== TCN_SELCHANGE
))
380 TaskManager_OnTabWndSelChange();
386 GetClientRect(hDlg
, &rc
);
387 Draw3dRect(hdc
, rc
.left
, rc
.top
, rc
.right
, rc
.top
+ 2, GetSysColor(COLOR_3DSHADOW
), GetSysColor(COLOR_3DHILIGHT
));
388 ReleaseDC(hDlg
, hdc
);
392 hdc
= BeginPaint(hDlg
, &ps
);
393 GetClientRect(hDlg
, &rc
);
394 Draw3dRect(hdc
, rc
.left
, rc
.top
, rc
.right
, rc
.top
+ 2, GetSysColor(COLOR_3DSHADOW
), GetSysColor(COLOR_3DHILIGHT
));
399 /* Make sure the user is sizing the dialog */
400 /* in an acceptable range */
401 pRC
= (LPRECT
)lParam
;
402 if ((wParam
== WMSZ_LEFT
) || (wParam
== WMSZ_TOPLEFT
) || (wParam
== WMSZ_BOTTOMLEFT
)) {
403 /* If the width is too small enlarge it to the minimum */
404 if (nMinimumWidth
> (pRC
->right
- pRC
->left
))
405 pRC
->left
= pRC
->right
- nMinimumWidth
;
407 /* If the width is too small enlarge it to the minimum */
408 if (nMinimumWidth
> (pRC
->right
- pRC
->left
))
409 pRC
->right
= pRC
->left
+ nMinimumWidth
;
411 if ((wParam
== WMSZ_TOP
) || (wParam
== WMSZ_TOPLEFT
) || (wParam
== WMSZ_TOPRIGHT
)) {
412 /* If the height is too small enlarge it to the minimum */
413 if (nMinimumHeight
> (pRC
->bottom
- pRC
->top
))
414 pRC
->top
= pRC
->bottom
- nMinimumHeight
;
416 /* If the height is too small enlarge it to the minimum */
417 if (nMinimumHeight
> (pRC
->bottom
- pRC
->top
))
418 pRC
->bottom
= pRC
->top
+ nMinimumHeight
;
424 /* Handle the window sizing in it's own function */
425 OnSize(wParam
, LOWORD(lParam
), HIWORD(lParam
));
429 /* Handle the window moving in it's own function */
430 OnMove(wParam
, LOWORD(lParam
), HIWORD(lParam
));
434 ShowWindow(hDlg
, SW_HIDE
);
435 TrayIcon_ShellRemoveTrayIcon();
436 wp
.length
= sizeof(WINDOWPLACEMENT
);
437 GetWindowPlacement(hDlg
, &wp
);
438 TaskManagerSettings
.Left
= wp
.rcNormalPosition
.left
;
439 TaskManagerSettings
.Top
= wp
.rcNormalPosition
.top
;
440 TaskManagerSettings
.Right
= wp
.rcNormalPosition
.right
;
441 TaskManagerSettings
.Bottom
= wp
.rcNormalPosition
.bottom
;
442 if (IsZoomed(hDlg
) || (wp
.flags
& WPF_RESTORETOMAXIMIZED
))
443 TaskManagerSettings
.Maximized
= TRUE
;
445 TaskManagerSettings
.Maximized
= FALSE
;
446 return DefWindowProcW(hDlg
, message
, wParam
, lParam
);
449 /* Refresh the performance data */
451 RefreshApplicationPage();
452 RefreshProcessPage();
453 RefreshPerformancePage();
454 TrayIcon_ShellUpdateTrayIcon();
457 case WM_ENTERMENULOOP
:
458 TaskManager_OnEnterMenuLoop(hDlg
);
460 case WM_EXITMENULOOP
:
461 TaskManager_OnExitMenuLoop(hDlg
);
464 TaskManager_OnMenuSelect(hDlg
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
466 case WM_SYSCOLORCHANGE
:
467 /* Forward WM_SYSCOLORCHANGE to common controls */
468 SendMessage(hApplicationPageListCtrl
, WM_SYSCOLORCHANGE
, 0, 0);
469 SendMessage(hProcessPageListCtrl
, WM_SYSCOLORCHANGE
, 0, 0);
470 SendMessage(hProcessPageHeaderCtrl
, WM_SYSCOLORCHANGE
, 0, 0);
477 void FillSolidRect(HDC hDC
, LPCRECT lpRect
, COLORREF clr
)
479 SetBkColor(hDC
, clr
);
480 ExtTextOutW(hDC
, 0, 0, ETO_OPAQUE
, lpRect
, NULL
, 0, NULL
);
483 void FillSolidRect2(HDC hDC
, int x
, int y
, int cx
, int cy
, COLORREF clr
)
487 SetBkColor(hDC
, clr
);
491 rect
.bottom
= y
+ cy
;
492 ExtTextOutW(hDC
, 0, 0, ETO_OPAQUE
, &rect
, NULL
, 0, NULL
);
495 void Draw3dRect(HDC hDC
, int x
, int y
, int cx
, int cy
, COLORREF clrTopLeft
, COLORREF clrBottomRight
)
497 FillSolidRect2(hDC
, x
, y
, cx
- 1, 1, clrTopLeft
);
498 FillSolidRect2(hDC
, x
, y
, 1, cy
- 1, clrTopLeft
);
499 FillSolidRect2(hDC
, x
+ cx
, y
, -1, cy
, clrBottomRight
);
500 FillSolidRect2(hDC
, x
, y
+ cy
, cx
, -1, clrBottomRight
);
503 void Draw3dRect2(HDC hDC
, LPRECT lpRect
, COLORREF clrTopLeft
, COLORREF clrBottomRight
)
505 Draw3dRect(hDC
, lpRect
->left
, lpRect
->top
, lpRect
->right
- lpRect
->left
,
506 lpRect
->bottom
- lpRect
->top
, clrTopLeft
, clrBottomRight
);
509 static void SetUpdateSpeed(HWND hWnd
)
511 /* Setup update speed (pause=fall down) */
512 switch (TaskManagerSettings
.UpdateSpeed
) {
513 case ID_VIEW_UPDATESPEED_HIGH
:
514 SetTimer(hWnd
, 1, 1000, NULL
);
516 case ID_VIEW_UPDATESPEED_NORMAL
:
517 SetTimer(hWnd
, 1, 2000, NULL
);
519 case ID_VIEW_UPDATESPEED_LOW
:
520 SetTimer(hWnd
, 1, 4000, NULL
);
525 BOOL
OnCreate(HWND hWnd
)
530 HMENU hUpdateSpeedMenu
;
531 HMENU hCPUHistoryMenu
;
538 SendMessageW(hMainWnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)LoadIconW(hInst
, MAKEINTRESOURCEW(IDI_TASKMANAGER
)));
540 /* Initialize the Windows Common Controls DLL */
541 InitCommonControls();
543 /* Get the minimum window sizes */
544 GetWindowRect(hWnd
, &rc
);
545 nMinimumWidth
= (rc
.right
- rc
.left
);
546 nMinimumHeight
= (rc
.bottom
- rc
.top
);
548 /* Create the status bar */
549 hStatusWnd
= CreateStatusWindow(WS_VISIBLE
|WS_CHILD
|WS_CLIPSIBLINGS
|SBT_NOBORDERS
, L
"", hWnd
, STATUS_WINDOW
);
553 /* Create the status bar panes */
554 nParts
[0] = STATUS_SIZE1
;
555 nParts
[1] = STATUS_SIZE2
;
556 nParts
[2] = STATUS_SIZE3
;
557 SendMessageW(hStatusWnd
, SB_SETPARTS
, 3, (LPARAM
) (LPINT
) nParts
);
559 /* Create tab pages */
560 hTabWnd
= GetDlgItem(hWnd
, IDC_TAB
);
562 hApplicationPage
= CreateDialogW(hInst
, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE
), hWnd
, ApplicationPageWndProc
); EnableDialogTheme(hApplicationPage
);
563 hProcessPage
= CreateDialogW(hInst
, MAKEINTRESOURCEW(IDD_PROCESS_PAGE
), hWnd
, ProcessPageWndProc
); EnableDialogTheme(hProcessPage
);
564 hPerformancePage
= CreateDialogW(hInst
, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE
), hWnd
, PerformancePageWndProc
); EnableDialogTheme(hPerformancePage
);
566 hApplicationPage
= CreateDialogW(hInst
, MAKEINTRESOURCEW(IDD_APPLICATION_PAGE
), hTabWnd
, ApplicationPageWndProc
); EnableDialogTheme(hApplicationPage
);
567 hProcessPage
= CreateDialogW(hInst
, MAKEINTRESOURCEW(IDD_PROCESS_PAGE
), hTabWnd
, ProcessPageWndProc
); EnableDialogTheme(hProcessPage
);
568 hPerformancePage
= CreateDialogW(hInst
, MAKEINTRESOURCEW(IDD_PERFORMANCE_PAGE
), hTabWnd
, PerformancePageWndProc
); EnableDialogTheme(hPerformancePage
);
572 LoadStringW(hInst
, IDS_TAB_APPS
, szTemp
, 256);
573 memset(&item
, 0, sizeof(TCITEM
));
574 item
.mask
= TCIF_TEXT
;
575 item
.pszText
= szTemp
;
576 (void)TabCtrl_InsertItem(hTabWnd
, 0, &item
);
577 LoadStringW(hInst
, IDS_TAB_PROCESSES
, szTemp
, 256);
578 memset(&item
, 0, sizeof(TCITEM
));
579 item
.mask
= TCIF_TEXT
;
580 item
.pszText
= szTemp
;
581 (void)TabCtrl_InsertItem(hTabWnd
, 1, &item
);
582 LoadStringW(hInst
, IDS_TAB_PERFORMANCE
, szTemp
, 256);
583 memset(&item
, 0, sizeof(TCITEM
));
584 item
.mask
= TCIF_TEXT
;
585 item
.pszText
= szTemp
;
586 (void)TabCtrl_InsertItem(hTabWnd
, 2, &item
);
588 /* Size everything correctly */
589 GetClientRect(hWnd
, &rc
);
590 nOldWidth
= rc
.right
;
591 nOldHeight
= rc
.bottom
;
592 /* nOldStartX = rc.left; */
593 /*nOldStartY = rc.top; */
595 #define PAGE_OFFSET_LEFT 17
596 #define PAGE_OFFSET_TOP 72
597 #define PAGE_OFFSET_WIDTH (PAGE_OFFSET_LEFT*2)
598 #define PAGE_OFFSET_HEIGHT (PAGE_OFFSET_TOP+32)
600 if ((TaskManagerSettings
.Left
!= 0) ||
601 (TaskManagerSettings
.Top
!= 0) ||
602 (TaskManagerSettings
.Right
!= 0) ||
603 (TaskManagerSettings
.Bottom
!= 0))
605 MoveWindow(hWnd
, TaskManagerSettings
.Left
, TaskManagerSettings
.Top
, TaskManagerSettings
.Right
- TaskManagerSettings
.Left
, TaskManagerSettings
.Bottom
- TaskManagerSettings
.Top
, TRUE
);
606 #ifdef __GNUC__TEST__
607 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
);
608 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
);
609 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
);
612 if (TaskManagerSettings
.Maximized
)
613 ShowWindow(hWnd
, SW_MAXIMIZE
);
615 /* Set the always on top style */
616 hMenu
= GetMenu(hWnd
);
617 hEditMenu
= GetSubMenu(hMenu
, 1);
618 hViewMenu
= GetSubMenu(hMenu
, 2);
619 hUpdateSpeedMenu
= GetSubMenu(hViewMenu
, 1);
620 hCPUHistoryMenu
= GetSubMenu(hViewMenu
, 7);
622 /* Check or uncheck the always on top menu item */
623 if (TaskManagerSettings
.AlwaysOnTop
) {
624 CheckMenuItem(hEditMenu
, ID_OPTIONS_ALWAYSONTOP
, MF_BYCOMMAND
|MF_CHECKED
);
625 SetWindowPos(hWnd
, HWND_TOPMOST
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
);
627 CheckMenuItem(hEditMenu
, ID_OPTIONS_ALWAYSONTOP
, MF_BYCOMMAND
|MF_UNCHECKED
);
628 SetWindowPos(hWnd
, HWND_NOTOPMOST
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
);
631 /* Check or uncheck the minimize on use menu item */
632 if (TaskManagerSettings
.MinimizeOnUse
)
633 CheckMenuItem(hEditMenu
, ID_OPTIONS_MINIMIZEONUSE
, MF_BYCOMMAND
|MF_CHECKED
);
635 CheckMenuItem(hEditMenu
, ID_OPTIONS_MINIMIZEONUSE
, MF_BYCOMMAND
|MF_UNCHECKED
);
637 /* Check or uncheck the hide when minimized menu item */
638 if (TaskManagerSettings
.HideWhenMinimized
)
639 CheckMenuItem(hEditMenu
, ID_OPTIONS_HIDEWHENMINIMIZED
, MF_BYCOMMAND
|MF_CHECKED
);
641 CheckMenuItem(hEditMenu
, ID_OPTIONS_HIDEWHENMINIMIZED
, MF_BYCOMMAND
|MF_UNCHECKED
);
643 /* Check or uncheck the show 16-bit tasks menu item */
644 if (TaskManagerSettings
.Show16BitTasks
)
645 CheckMenuItem(hEditMenu
, ID_OPTIONS_SHOW16BITTASKS
, MF_BYCOMMAND
|MF_CHECKED
);
647 CheckMenuItem(hEditMenu
, ID_OPTIONS_SHOW16BITTASKS
, MF_BYCOMMAND
|MF_UNCHECKED
);
649 /* Set the view mode */
650 CheckMenuRadioItem(hViewMenu
, ID_VIEW_LARGE
, ID_VIEW_DETAILS
, TaskManagerSettings
.ViewMode
, MF_BYCOMMAND
);
652 if (TaskManagerSettings
.ShowKernelTimes
)
653 CheckMenuItem(hViewMenu
, ID_VIEW_SHOWKERNELTIMES
, MF_BYCOMMAND
|MF_CHECKED
);
655 CheckMenuItem(hViewMenu
, ID_VIEW_SHOWKERNELTIMES
, MF_BYCOMMAND
|MF_UNCHECKED
);
657 CheckMenuRadioItem(hUpdateSpeedMenu
, ID_VIEW_UPDATESPEED_HIGH
, ID_VIEW_UPDATESPEED_PAUSED
, TaskManagerSettings
.UpdateSpeed
, MF_BYCOMMAND
);
659 if (TaskManagerSettings
.CPUHistory_OneGraphPerCPU
)
660 CheckMenuRadioItem(hCPUHistoryMenu
, ID_VIEW_CPUHISTORY_ONEGRAPHALL
, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU
, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU
, MF_BYCOMMAND
);
662 CheckMenuRadioItem(hCPUHistoryMenu
, ID_VIEW_CPUHISTORY_ONEGRAPHALL
, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU
, ID_VIEW_CPUHISTORY_ONEGRAPHALL
, MF_BYCOMMAND
);
664 nActivePage
= TaskManagerSettings
.ActiveTabPage
;
665 TabCtrl_SetCurFocus
/*Sel*/(hTabWnd
, 0);
666 TabCtrl_SetCurFocus
/*Sel*/(hTabWnd
, 1);
667 TabCtrl_SetCurFocus
/*Sel*/(hTabWnd
, 2);
668 TabCtrl_SetCurFocus
/*Sel*/(hTabWnd
, nActivePage
);
670 /* Setup update speed */
671 SetUpdateSpeed(hWnd
);
674 * Refresh the performance data
675 * Sample it twice so we can establish
676 * the delta values & cpu usage
681 RefreshApplicationPage();
682 RefreshProcessPage();
683 RefreshPerformancePage();
685 TrayIcon_ShellAddTrayIcon();
691 * This function handles all the moving events for the application
692 * It moves every child window that needs moving
694 void OnMove( WPARAM nType
, int cx
, int cy
)
696 #ifdef __GNUC__TEST__
697 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
);
698 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
);
699 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
);
704 * This function handles all the sizing events for the application
705 * It re-sizes every window, and child window that needs re-sizing
707 void OnSize( WPARAM nType
, int cx
, int cy
)
714 if (nType
== SIZE_MINIMIZED
)
716 if(TaskManagerSettings
.HideWhenMinimized
)
718 ShowWindow(hMainWnd
, SW_HIDE
);
723 nXDifference
= cx
- nOldWidth
;
724 nYDifference
= cy
- nOldHeight
;
728 /* Update the status bar size */
729 GetWindowRect(hStatusWnd
, &rc
);
730 SendMessageW(hStatusWnd
, WM_SIZE
, nType
, MAKELPARAM(cx
,rc
.bottom
- rc
.top
));
732 /* Update the status bar pane sizes */
733 nParts
[0] = bInMenuLoop
? -1 : STATUS_SIZE1
;
734 nParts
[1] = STATUS_SIZE2
;
736 SendMessageW(hStatusWnd
, SB_SETPARTS
, bInMenuLoop
? 1 : 3, (LPARAM
) (LPINT
) nParts
);
738 /* Resize the tab control */
739 GetWindowRect(hTabWnd
, &rc
);
740 cx
= (rc
.right
- rc
.left
) + nXDifference
;
741 cy
= (rc
.bottom
- rc
.top
) + nYDifference
;
742 SetWindowPos(hTabWnd
, NULL
, 0, 0, cx
, cy
, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOMOVE
|SWP_NOZORDER
);
744 /* Resize the application page */
745 GetWindowRect(hApplicationPage
, &rc
);
746 cx
= (rc
.right
- rc
.left
) + nXDifference
;
747 cy
= (rc
.bottom
- rc
.top
) + nYDifference
;
748 SetWindowPos(hApplicationPage
, NULL
, 0, 0, cx
, cy
, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOMOVE
|SWP_NOZORDER
);
750 /* Resize the process page */
751 GetWindowRect(hProcessPage
, &rc
);
752 cx
= (rc
.right
- rc
.left
) + nXDifference
;
753 cy
= (rc
.bottom
- rc
.top
) + nYDifference
;
754 SetWindowPos(hProcessPage
, NULL
, 0, 0, cx
, cy
, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOMOVE
|SWP_NOZORDER
);
756 /* Resize the performance page */
757 GetWindowRect(hPerformancePage
, &rc
);
758 cx
= (rc
.right
- rc
.left
) + nXDifference
;
759 cy
= (rc
.bottom
- rc
.top
) + nYDifference
;
760 SetWindowPos(hPerformancePage
, NULL
, 0, 0, cx
, cy
, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOMOVE
|SWP_NOZORDER
);
763 void LoadSettings(void)
766 WCHAR szSubKey
[] = L
"Software\\ReactOS\\TaskManager";
770 /* Window size & position settings */
771 TaskManagerSettings
.Maximized
= FALSE
;
772 TaskManagerSettings
.Left
= 0;
773 TaskManagerSettings
.Top
= 0;
774 TaskManagerSettings
.Right
= 0;
775 TaskManagerSettings
.Bottom
= 0;
778 TaskManagerSettings
.ActiveTabPage
= 0;
780 /* Options menu settings */
781 TaskManagerSettings
.AlwaysOnTop
= FALSE
;
782 TaskManagerSettings
.MinimizeOnUse
= TRUE
;
783 TaskManagerSettings
.HideWhenMinimized
= TRUE
;
784 TaskManagerSettings
.Show16BitTasks
= TRUE
;
786 /* Update speed settings */
787 TaskManagerSettings
.UpdateSpeed
= ID_VIEW_UPDATESPEED_NORMAL
;
789 /* Applications page settings */
790 TaskManagerSettings
.ViewMode
= ID_VIEW_DETAILS
;
792 /* Processes page settings */
793 TaskManagerSettings
.ShowProcessesFromAllUsers
= FALSE
; /* Server-only? */
795 for (i
= 0; i
< COLUMN_NMAX
; i
++) {
796 TaskManagerSettings
.Columns
[i
] = ColumnPresets
[i
].bDefaults
;
797 TaskManagerSettings
.ColumnOrderArray
[i
] = i
;
798 TaskManagerSettings
.ColumnSizeArray
[i
] = ColumnPresets
[i
].size
;
801 TaskManagerSettings
.SortColumn
= COLUMN_IMAGENAME
;
802 TaskManagerSettings
.SortAscending
= TRUE
;
804 /* Performance page settings */
805 TaskManagerSettings
.CPUHistory_OneGraphPerCPU
= TRUE
;
806 TaskManagerSettings
.ShowKernelTimes
= FALSE
;
809 if (RegOpenKeyExW(HKEY_CURRENT_USER
, szSubKey
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
811 /* Read the settings */
812 dwSize
= sizeof(TASKMANAGER_SETTINGS
);
813 RegQueryValueExW(hKey
, L
"Preferences", NULL
, NULL
, (LPBYTE
)&TaskManagerSettings
, &dwSize
);
816 * ATM, the 'ImageName' column is always visible
817 * (and grayed in configuration dialog)
818 * This will avoid troubles if the registry gets corrupted.
820 TaskManagerSettings
.Column_ImageName
= TRUE
;
826 void SaveSettings(void)
829 WCHAR szSubKey
[] = L
"Software\\ReactOS\\TaskManager";
831 /* Open (or create) the key */
832 if (RegCreateKeyExW(HKEY_CURRENT_USER
, szSubKey
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hKey
, NULL
) != ERROR_SUCCESS
)
834 /* Save the settings */
835 RegSetValueExW(hKey
, L
"Preferences", 0, REG_BINARY
, (LPBYTE
)&TaskManagerSettings
, sizeof(TASKMANAGER_SETTINGS
));
840 void TaskManager_OnRestoreMainWindow(void)
842 //HMENU hMenu, hOptionsMenu;
845 //hMenu = GetMenu(hMainWnd);
846 //hOptionsMenu = GetSubMenu(hMenu, OPTIONS_MENU_INDEX);
847 OnTop
= ((GetWindowLongPtrW(hMainWnd
, GWL_EXSTYLE
) & WS_EX_TOPMOST
) != 0);
850 SetForegroundWindow(hMainWnd
);
851 SetWindowPos(hMainWnd
, (OnTop
? HWND_TOPMOST
: HWND_TOP
), 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
| SWP_SHOWWINDOW
);
854 void TaskManager_OnEnterMenuLoop(HWND hWnd
)
858 /* Update the status bar pane sizes */
860 SendMessageW(hStatusWnd
, SB_SETPARTS
, 1, (LPARAM
) (LPINT
)&nParts
);
862 SendMessageW(hStatusWnd
, SB_SETTEXT
, (WPARAM
)0, (LPARAM
)L
"");
865 void TaskManager_OnExitMenuLoop(HWND hWnd
)
870 WCHAR szCpuUsage
[256], szProcesses
[256];
872 LoadStringW(hInst
, IDS_STATUS_CPUUSAGE
, szCpuUsage
, 256);
873 LoadStringW(hInst
, IDS_STATUS_PROCESSES
, szProcesses
, 256);
876 /* Update the status bar pane sizes */
877 GetClientRect(hWnd
, &rc
);
878 nParts
[0] = STATUS_SIZE1
;
879 nParts
[1] = STATUS_SIZE2
;
880 nParts
[2] = rc
.right
;
881 SendMessageW(hStatusWnd
, SB_SETPARTS
, 3, (LPARAM
) (LPINT
) nParts
);
882 SendMessageW(hStatusWnd
, SB_SETTEXT
, 0, (LPARAM
)L
"");
883 wsprintfW(text
, szCpuUsage
, PerfDataGetProcessorUsage());
884 SendMessageW(hStatusWnd
, SB_SETTEXT
, 1, (LPARAM
)text
);
885 wsprintfW(text
, szProcesses
, PerfDataGetProcessCount());
886 SendMessageW(hStatusWnd
, SB_SETTEXT
, 0, (LPARAM
)text
);
889 void TaskManager_OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
894 if (LoadStringW(hInst
, nItemID
, str
, 100)) {
895 /* load appropriate string */
897 /* first newline terminates actual string */
898 lpsz
= wcschr(lpsz
, '\n');
902 SendMessageW(hStatusWnd
, SB_SETTEXT
, 0, (LPARAM
)str
);
905 void TaskManager_OnViewUpdateSpeed(DWORD dwSpeed
)
909 HMENU hUpdateSpeedMenu
;
911 hMenu
= GetMenu(hMainWnd
);
912 hViewMenu
= GetSubMenu(hMenu
, 2);
913 hUpdateSpeedMenu
= GetSubMenu(hViewMenu
, 1);
915 TaskManagerSettings
.UpdateSpeed
= dwSpeed
;
916 CheckMenuRadioItem(hUpdateSpeedMenu
, ID_VIEW_UPDATESPEED_HIGH
, ID_VIEW_UPDATESPEED_PAUSED
, dwSpeed
, MF_BYCOMMAND
);
918 KillTimer(hMainWnd
, 1);
920 SetUpdateSpeed(hMainWnd
);
923 void TaskManager_OnTabWndSelChange(void)
933 hMenu
= GetMenu(hMainWnd
);
934 hViewMenu
= GetSubMenu(hMenu
, 2);
935 hOptionsMenu
= GetSubMenu(hMenu
, 1);
936 TaskManagerSettings
.ActiveTabPage
= TabCtrl_GetCurSel(hTabWnd
);
937 for (i
= GetMenuItemCount(hViewMenu
) - 1; i
> 2; i
--) {
938 hSubMenu
= GetSubMenu(hViewMenu
, i
);
940 DestroyMenu(hSubMenu
);
941 RemoveMenu(hViewMenu
, i
, MF_BYPOSITION
);
943 RemoveMenu(hOptionsMenu
, 3, MF_BYPOSITION
);
944 switch (TaskManagerSettings
.ActiveTabPage
) {
946 ShowWindow(hApplicationPage
, SW_SHOW
);
947 ShowWindow(hProcessPage
, SW_HIDE
);
948 ShowWindow(hPerformancePage
, SW_HIDE
);
949 BringWindowToTop(hApplicationPage
);
951 LoadStringW(hInst
, IDS_MENU_LARGEICONS
, szTemp
, 256);
952 AppendMenuW(hViewMenu
, MF_STRING
, ID_VIEW_LARGE
, szTemp
);
954 LoadStringW(hInst
, IDS_MENU_SMALLICONS
, szTemp
, 256);
955 AppendMenuW(hViewMenu
, MF_STRING
, ID_VIEW_SMALL
, szTemp
);
957 LoadStringW(hInst
, IDS_MENU_DETAILS
, szTemp
, 256);
958 AppendMenuW(hViewMenu
, MF_STRING
, ID_VIEW_DETAILS
, szTemp
);
960 if (GetMenuItemCount(hMenu
) <= 4) {
961 hSubMenu
= LoadMenuW(hInst
, MAKEINTRESOURCEW(IDR_WINDOWSMENU
));
963 LoadStringW(hInst
, IDS_MENU_WINDOWS
, szTemp
, 256);
964 InsertMenuW(hMenu
, 3, MF_BYPOSITION
|MF_POPUP
, (UINT_PTR
) hSubMenu
, szTemp
);
966 DrawMenuBar(hMainWnd
);
968 CheckMenuRadioItem(hViewMenu
, ID_VIEW_LARGE
, ID_VIEW_DETAILS
, TaskManagerSettings
.ViewMode
, MF_BYCOMMAND
);
971 * Give the application list control focus
973 SetFocus(hApplicationPageListCtrl
);
977 ShowWindow(hApplicationPage
, SW_HIDE
);
978 ShowWindow(hProcessPage
, SW_SHOW
);
979 ShowWindow(hPerformancePage
, SW_HIDE
);
980 BringWindowToTop(hProcessPage
);
982 LoadStringW(hInst
, IDS_MENU_SELECTCOLUMNS
, szTemp
, 256);
983 AppendMenuW(hViewMenu
, MF_STRING
, ID_VIEW_SELECTCOLUMNS
, szTemp
);
985 LoadStringW(hInst
, IDS_MENU_16BITTASK
, szTemp
, 256);
986 AppendMenuW(hOptionsMenu
, MF_STRING
, ID_OPTIONS_SHOW16BITTASKS
, szTemp
);
988 if (TaskManagerSettings
.Show16BitTasks
)
989 CheckMenuItem(hOptionsMenu
, ID_OPTIONS_SHOW16BITTASKS
, MF_BYCOMMAND
|MF_CHECKED
);
990 if (GetMenuItemCount(hMenu
) > 4)
992 DeleteMenu(hMenu
, 3, MF_BYPOSITION
);
993 DrawMenuBar(hMainWnd
);
996 * Give the process list control focus
998 SetFocus(hProcessPageListCtrl
);
1002 ShowWindow(hApplicationPage
, SW_HIDE
);
1003 ShowWindow(hProcessPage
, SW_HIDE
);
1004 ShowWindow(hPerformancePage
, SW_SHOW
);
1005 BringWindowToTop(hPerformancePage
);
1006 if (GetMenuItemCount(hMenu
) > 4) {
1007 DeleteMenu(hMenu
, 3, MF_BYPOSITION
);
1008 DrawMenuBar(hMainWnd
);
1011 GetSystemInfo(&sysInfo
);
1013 /* Hide CPU graph options on single CPU systems */
1014 if (sysInfo
.dwNumberOfProcessors
> 1)
1016 hSubMenu
= CreatePopupMenu();
1018 LoadStringW(hInst
, IDS_MENU_ONEGRAPHALLCPUS
, szTemp
, 256);
1019 AppendMenuW(hSubMenu
, MF_STRING
, ID_VIEW_CPUHISTORY_ONEGRAPHALL
, szTemp
);
1021 LoadStringW(hInst
, IDS_MENU_ONEGRAPHPERCPU
, szTemp
, 256);
1022 AppendMenuW(hSubMenu
, MF_STRING
, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU
, szTemp
);
1024 LoadStringW(hInst
, IDS_MENU_CPUHISTORY
, szTemp
, 256);
1025 AppendMenuW(hViewMenu
, MF_STRING
|MF_POPUP
, (UINT_PTR
) hSubMenu
, szTemp
);
1027 if (TaskManagerSettings
.CPUHistory_OneGraphPerCPU
)
1028 CheckMenuRadioItem(hSubMenu
, ID_VIEW_CPUHISTORY_ONEGRAPHALL
, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU
, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU
, MF_BYCOMMAND
);
1030 CheckMenuRadioItem(hSubMenu
, ID_VIEW_CPUHISTORY_ONEGRAPHALL
, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU
, ID_VIEW_CPUHISTORY_ONEGRAPHALL
, MF_BYCOMMAND
);
1033 LoadStringW(hInst
, IDS_MENU_SHOWKERNELTIMES
, szTemp
, 256);
1034 AppendMenuW(hViewMenu
, MF_STRING
, ID_VIEW_SHOWKERNELTIMES
, szTemp
);
1036 if (TaskManagerSettings
.ShowKernelTimes
)
1037 CheckMenuItem(hViewMenu
, ID_VIEW_SHOWKERNELTIMES
, MF_BYCOMMAND
|MF_CHECKED
);
1039 CheckMenuItem(hViewMenu
, ID_VIEW_SHOWKERNELTIMES
, MF_BYCOMMAND
|MF_UNCHECKED
);
1042 * Give the tab control focus
1049 LPWSTR
GetLastErrorText(LPWSTR lpszBuf
, DWORD dwSize
)
1052 LPWSTR lpszTemp
= NULL
;
1054 dwRet
= FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
|FORMAT_MESSAGE_ARGUMENT_ARRAY
,
1062 /* supplied buffer is not long enough */
1063 if (!dwRet
|| ( (long)dwSize
< (long)dwRet
+14)) {
1066 lpszTemp
[lstrlenW(lpszTemp
)-2] = L
'\0'; /*remove cr and newline character */
1067 wsprintfW(lpszBuf
, L
"%s (0x%x)", lpszTemp
, (int)GetLastError());
1070 LocalFree((HLOCAL
)lpszTemp
);
1075 DWORD
EndLocalThread(HANDLE
*hThread
, DWORD dwThread
)
1077 DWORD dwExitCodeThread
= 0;
1079 if (*hThread
!= NULL
) {
1080 PostThreadMessage(dwThread
,WM_QUIT
,0,0);
1084 if (WAIT_OBJECT_0
== WaitForSingleObject(*hThread
, 500))
1086 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) {
1087 TranslateMessage(&msg
);
1088 DispatchMessage(&msg
);
1091 GetExitCodeThread(*hThread
, &dwExitCodeThread
);
1092 CloseHandle(*hThread
);
1095 return dwExitCodeThread
;