* Sync with recent trunk (r52637).
[reactos.git] / base / applications / taskmgr / taskmgr.c
index f11413a..ad91758 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  ReactOS Task Manager
  *
- * TaskMgr.c : Defines the entry point for the application.
+ * taskmgr.c : Defines the entry point for the application.
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
  *                2005         Klemens Friedl <frik85@reactos.at>
@@ -18,7 +18,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <precomp.h>
@@ -51,6 +51,31 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
     HANDLE hProcess;
     HANDLE hToken;
     TOKEN_PRIVILEGES tkp;
+    HANDLE hMutex;
+
+    /* check wether we're already running or not */
+    hMutex = CreateMutexW(NULL, TRUE, L"taskmgrros");
+    if (hMutex && GetLastError() == ERROR_ALREADY_EXISTS)
+    {
+        /* Restore existing taskmanager and bring window to front */
+        /* Relies on the fact that the application title string and window title are the same */
+        HWND hTaskMgr;
+        TCHAR szTaskmgr[128];
+
+        LoadString(hInst, IDS_APP_TITLE, szTaskmgr, sizeof(szTaskmgr)/sizeof(TCHAR));
+        hTaskMgr = FindWindow(NULL, szTaskmgr);
+
+        if (hTaskMgr != NULL)
+        {
+            SendMessage(hTaskMgr, WM_SYSCOMMAND, SC_RESTORE, 0);
+            SetForegroundWindow(hTaskMgr);
+        }
+        return 0;
+    }
+    else if (!hMutex)
+    {
+        return 1;
+    }
 
     /* Initialize global variables */
     hInst = hInstance;
@@ -97,10 +122,12 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
 INT_PTR CALLBACK
 TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 {
+#if 0
     HDC              hdc;
     PAINTSTRUCT      ps;
-    LPRECT           pRC;
     RECT             rc;
+#endif
+    LPRECT           pRC;
     int              idctrl;
     LPNMHDR          pnmh;
     WINDOWPLACEMENT  wp;
@@ -242,7 +269,7 @@ TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 
             GetCursorPos(&pt);
 
-            OnTop = ((GetWindowLongW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
+            OnTop = ((GetWindowLongPtrW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
 
             hMenu = LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_TRAY_POPUP));
             hPopupMenu = GetSubMenu(hMenu, 0);
@@ -259,6 +286,9 @@ TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
             if(OnTop)
             {
               CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_CHECKED);
+            } else
+            {
+              CheckMenuItem(hPopupMenu, ID_OPTIONS_ALWAYSONTOP, MF_BYCOMMAND | MF_UNCHECKED);
             }
 
             SetForegroundWindow(hMainWnd);
@@ -283,7 +313,7 @@ TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
             TaskManager_OnTabWndSelChange();
         }
         break;
-
+#if 0
     case WM_NCPAINT:
         hdc = GetDC(hDlg);
         GetClientRect(hDlg, &rc);
@@ -297,7 +327,7 @@ TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
         Draw3dRect(hdc, rc.left, rc.top, rc.right, rc.top + 2, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
         EndPaint(hDlg, &ps);
         break;
-
+#endif
     case WM_SIZING:
         /* Make sure the user is sizing the dialog */
         /* in an acceptable range */
@@ -366,6 +396,12 @@ TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     case WM_MENUSELECT:
         TaskManager_OnMenuSelect(hDlg, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
         break;
+    case WM_SYSCOLORCHANGE:
+        /* Forward WM_SYSCOLORCHANGE to common controls */
+        SendMessage(hApplicationPageListCtrl, WM_SYSCOLORCHANGE, 0, 0);
+        SendMessage(hProcessPageListCtrl, WM_SYSCOLORCHANGE, 0, 0);
+        SendMessage(hProcessPageHeaderCtrl, WM_SYSCOLORCHANGE, 0, 0);
+        break;
     }
 
     return 0;
@@ -448,9 +484,9 @@ BOOL OnCreate(HWND hWnd)
         return FALSE;
 
     /* Create the status bar panes */
-    nParts[0] = 100;
-    nParts[1] = 210;
-    nParts[2] = 400;
+    nParts[0] = STATUS_SIZE1;
+    nParts[1] = STATUS_SIZE2;
+    nParts[2] = STATUS_SIZE3;
     SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts);
 
     /* Create tab pages */
@@ -624,11 +660,11 @@ void OnSize( WPARAM nType, int cx, int cy )
 
     /* Update the status bar size */
     GetWindowRect(hStatusWnd, &rc);
-    SendMessageW(hStatusWnd, WM_SIZE, nType, MAKELPARAM(cx, cy + (rc.bottom - rc.top)));
+    SendMessageW(hStatusWnd, WM_SIZE, nType, MAKELPARAM(cx,rc.bottom - rc.top));
 
     /* Update the status bar pane sizes */
-    nParts[0] = bInMenuLoop ? -1 : 100;
-    nParts[1] = 210;
+    nParts[0] = bInMenuLoop ? -1 : STATUS_SIZE1;
+    nParts[1] = STATUS_SIZE2;
     nParts[2] = cx;
     SendMessageW(hStatusWnd, SB_SETPARTS, bInMenuLoop ? 1 : 3, (LPARAM) (LPINT) nParts);
 
@@ -695,7 +731,7 @@ void LoadSettings(void)
         TaskManagerSettings.ColumnSizeArray[i] = ColumnPresets[i].size;
     }
 
-    TaskManagerSettings.SortColumn = 1;
+    TaskManagerSettings.SortColumn = COLUMN_IMAGENAME;
     TaskManagerSettings.SortAscending = TRUE;
 
     /* Performance page settings */
@@ -723,19 +759,10 @@ void LoadSettings(void)
 void SaveSettings(void)
 {
     HKEY hKey;
-    WCHAR szSubKey1[] = L"Software";
-    WCHAR szSubKey2[] = L"Software\\ReactOS";
-    WCHAR szSubKey3[] = L"Software\\ReactOS\\TaskManager";
+    WCHAR szSubKey[] = L"Software\\ReactOS\\TaskManager";
 
     /* Open (or create) the key */
-    hKey = NULL;
-    RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey1, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
-    RegCloseKey(hKey);
-    hKey = NULL;
-    RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey2, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
-    RegCloseKey(hKey);
-    hKey = NULL;
-    if (RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey3, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
+    if (RegCreateKeyExW(HKEY_CURRENT_USER, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
         return;
     /* Save the settings */
     RegSetValueExW(hKey, L"Preferences", 0, REG_BINARY, (LPBYTE)&TaskManagerSettings, sizeof(TASKMANAGER_SETTINGS));
@@ -750,7 +777,7 @@ void TaskManager_OnRestoreMainWindow(void)
 
     hMenu = GetMenu(hMainWnd);
     hOptionsMenu = GetSubMenu(hMenu, OPTIONS_MENU_INDEX);
-    OnTop = ((GetWindowLongW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
+    OnTop = ((GetWindowLongPtrW(hMainWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
 
     OpenIcon(hMainWnd);
     SetForegroundWindow(hMainWnd);
@@ -781,8 +808,8 @@ void TaskManager_OnExitMenuLoop(HWND hWnd)
     bInMenuLoop = FALSE;
     /* Update the status bar pane sizes */
     GetClientRect(hWnd, &rc);
-    nParts[0] = 100;
-    nParts[1] = 210;
+    nParts[0] = STATUS_SIZE1;
+    nParts[1] = STATUS_SIZE2;
     nParts[2] = rc.right;
     SendMessageW(hStatusWnd, SB_SETPARTS, 3, (LPARAM) (LPINT) nParts);
     SendMessageW(hStatusWnd, SB_SETTEXT, 0, (LPARAM)L"");
@@ -826,11 +853,6 @@ void TaskManager_OnViewUpdateSpeed(DWORD dwSpeed)
     SetUpdateSpeed(hMainWnd);
 }
 
-void TaskManager_OnViewRefresh(void)
-{
-    PostMessageW(hMainWnd, WM_TIMER, 0, 0);
-}
-
 void TaskManager_OnTabWndSelChange(void)
 {
     int    i;
@@ -839,6 +861,7 @@ void TaskManager_OnTabWndSelChange(void)
     HMENU  hViewMenu;
     HMENU  hSubMenu;
     WCHAR  szTemp[256];
+    SYSTEM_INFO sysInfo;
 
     hMenu = GetMenu(hMainWnd);
     hViewMenu = GetSubMenu(hMenu, 2);
@@ -917,16 +940,28 @@ void TaskManager_OnTabWndSelChange(void)
             DeleteMenu(hMenu, 3, MF_BYPOSITION);
             DrawMenuBar(hMainWnd);
         }
-        hSubMenu = CreatePopupMenu();
 
-        LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256);
-        AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp);
+        GetSystemInfo(&sysInfo);
+
+        /* Hide CPU graph options on single CPU systems */
+        if (sysInfo.dwNumberOfProcessors > 1)
+        {
+            hSubMenu = CreatePopupMenu();
 
-        LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256);
-        AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp);
+            LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256);
+            AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp);
 
-        LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256);
-        AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp);
+            LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256);
+            AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp);
+
+            LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256);
+            AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp);
+
+            if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
+                CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
+            else
+                CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
+        }
 
         LoadStringW(hInst, IDS_MENU_SHOWKERNELTIMES, szTemp, 256);
         AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, szTemp);
@@ -935,10 +970,7 @@ void TaskManager_OnTabWndSelChange(void)
             CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
         else
             CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED);
-        if (TaskManagerSettings.CPUHistory_OneGraphPerCPU)
-            CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND);
-        else
-            CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND);
+
         /*
          * Give the tab control focus
          */
@@ -972,3 +1004,27 @@ LPWSTR GetLastErrorText(LPWSTR lpszBuf, DWORD dwSize)
     }
     return lpszBuf;
 }
+
+DWORD EndLocalThread(HANDLE *hThread, DWORD dwThread)
+{
+    DWORD dwExitCodeThread = 0;
+
+    if (*hThread != NULL) {
+        PostThreadMessage(dwThread,WM_QUIT,0,0);
+        for (;;) {
+            MSG msg;
+
+            if (WAIT_OBJECT_0 == WaitForSingleObject(*hThread, 500))
+                break;
+            while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+                TranslateMessage(&msg);
+                DispatchMessage(&msg);
+            }
+        }
+        GetExitCodeThread(*hThread, &dwExitCodeThread);
+        CloseHandle(*hThread);
+        *hThread = NULL;
+    }
+    return dwExitCodeThread;
+}
+