* Sync with recent trunk (r52637).
[reactos.git] / base / applications / taskmgr / procpage.c
index 4c3b636..5276906 100644 (file)
@@ -28,7 +28,6 @@
 
 typedef struct
 {
-    ULONG Index;
     ULONG ProcessId;
 } PROCESS_PAGE_LIST_ITEM, *LPPROCESS_PAGE_LIST_ITEM;
 
@@ -41,7 +40,10 @@ HWND hProcessPageShowAllProcessesButton;/* Process Show All Processes checkbox *
 
 static int  nProcessPageWidth;
 static int  nProcessPageHeight;
-static HANDLE  hProcessPageEvent = NULL;    /* When this event becomes signaled then we refresh the process list */
+#ifdef RUN_PROC_PAGE
+static HANDLE   hProcessThread = NULL;
+static DWORD    dwProcessThread;
+#endif
 
 int CALLBACK    ProcessPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
 void AddProcess(ULONG Index);
@@ -54,6 +56,27 @@ BOOL PerfDataGetText(ULONG Index, ULONG ColumnIndex, LPTSTR lpText, int nMaxCoun
 DWORD WINAPI ProcessPageRefreshThread(void *lpParameter);
 int ProcessRunning(ULONG ProcessId);
 
+int ProcGetIndexByProcessId(DWORD dwProcessId)
+{
+    int     i;
+    LVITEM  item;
+    LPPROCESS_PAGE_LIST_ITEM pData;
+
+    for (i=0; i<ListView_GetItemCount(hProcessPageListCtrl); i++)
+    {
+        memset(&item, 0, sizeof(LV_ITEM));
+        item.mask = LVIF_PARAM;
+        item.iItem = i;
+        (void)ListView_GetItem(hProcessPageListCtrl, &item);
+        pData = (LPPROCESS_PAGE_LIST_ITEM)item.lParam;
+        if (pData->ProcessId == dwProcessId)
+        {
+            return i;
+        }
+    }
+    return 0;
+}
+
 DWORD GetSelectedProcessId(void)
 {
     int     Index;
@@ -71,7 +94,7 @@ DWORD GetSelectedProcessId(void)
         (void)ListView_GetItem(hProcessPageListCtrl, &lvitem);
 
         if (lvitem.lParam)
-            return PerfDataGetProcessId(((LPPROCESS_PAGE_LIST_ITEM)lvitem.lParam)->Index);
+            return ((LPPROCESS_PAGE_LIST_ITEM)lvitem.lParam)->ProcessId;
     }
 
     return 0;
@@ -84,7 +107,6 @@ ProcessPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     int     nXDifference;
     int     nYDifference;
     int     cx, cy;
-    HANDLE  hRefreshThread = NULL;
 
     switch (message) {
     case WM_INITDIALOG:
@@ -119,19 +141,19 @@ ProcessPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
          */
         OldProcessListWndProc = (WNDPROC)(LONG_PTR) SetWindowLongPtrW(hProcessPageListCtrl, GWL_WNDPROC, (LONG_PTR)ProcessListWndProc);
 
+#ifdef RUN_PROC_PAGE
         /* Start our refresh thread */
-        hRefreshThread = CreateThread(NULL, 0, ProcessPageRefreshThread, NULL, 0, NULL);
-
+        hProcessThread = CreateThread(NULL, 0, ProcessPageRefreshThread, NULL, 0, &dwProcessThread);
+#endif
         return TRUE;
 
     case WM_DESTROY:
         /* Close the event handle, this will make the */
         /* refresh thread exit when the wait fails */
-        CloseHandle(hProcessPageEvent);
-        CloseHandle(hRefreshThread);
-
+#ifdef RUN_PROC_PAGE
+        EndLocalThread(&hProcessThread, dwProcessThread);
+#endif
         SaveColumnSettings();
-
         break;
 
     case WM_COMMAND:
@@ -174,13 +196,16 @@ ProcessPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
         cy = rc.top + nYDifference;
         SetWindowPos(hProcessPageShowAllProcessesButton, NULL, cx, cy, 0, 0, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);
         InvalidateRect(hProcessPageShowAllProcessesButton, NULL, TRUE);
-
         break;
 
     case WM_NOTIFY:
-
         ProcessPageOnNotify(wParam, lParam);
         break;
+
+    case WM_KEYDOWN:
+        if (wParam == VK_DELETE)
+            ProcessPage_OnEndProcess();
+        break;
     }
 
     return 0;
@@ -219,7 +244,7 @@ void ProcessPageOnNotify(WPARAM wParam, LPARAM lParam)
                 break;
 
             pData = (LPPROCESS_PAGE_LIST_ITEM)pnmdi->item.lParam;
-            Index = pData->Index;
+            Index = PerfDataGetProcessIndex(pData->ProcessId);
             ColumnIndex = pnmdi->item.iSubItem;
 
             PerfDataGetText(Index, ColumnIndex, pnmdi->item.pszText, pnmdi->item.cchTextMax);
@@ -231,6 +256,12 @@ void ProcessPageOnNotify(WPARAM wParam, LPARAM lParam)
             ProcessPageShowContextMenu(GetSelectedProcessId());
             break;
 
+        case LVN_KEYDOWN:
+
+            if (((LPNMLVKEYDOWN)lParam)->wVKey == VK_DELETE)
+                ProcessPage_OnEndProcess();
+            break;
+
         }
     }
     else if (pnmh->hwndFrom == hProcessPageHeaderCtrl)
@@ -352,9 +383,11 @@ void ProcessPageShowContextMenu(DWORD dwProcessId)
 
 void RefreshProcessPage(void)
 {
+#ifdef RUN_PROC_PAGE
     /* Signal the event so that our refresh thread */
     /* will wake up and refresh the process page */
-    SetEvent(hProcessPageEvent);
+    PostThreadMessage(dwProcessThread, WM_TIMER, 0, 0);
+#endif
 }
 
 DWORD WINAPI ProcessPageRefreshThread(void *lpParameter)
@@ -362,34 +395,19 @@ DWORD WINAPI ProcessPageRefreshThread(void *lpParameter)
     ULONG    OldProcessorUsage = 0;
     ULONG    OldProcessCount = 0;
     WCHAR    szCpuUsage[256], szProcesses[256];
-
-    /* Create the event */
-    hProcessPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
-
-    /* If we couldn't create the event then exit the thread */
-    if (!hProcessPageEvent)
-        return 0;
+    MSG      msg;
 
     LoadStringW(hInst, IDS_STATUS_CPUUSAGE, szCpuUsage, 256);
     LoadStringW(hInst, IDS_STATUS_PROCESSES, szProcesses, 256);
 
     while (1) {
-        DWORD    dwWaitVal;
-
-        /* Wait on the event */
-        dwWaitVal = WaitForSingleObject(hProcessPageEvent, INFINITE);
-
-        /* If the wait failed then the event object must have been */
-        /* closed and the task manager is exiting so exit this thread */
-        if (dwWaitVal == WAIT_FAILED)
+        /*  Wait for an the event or application close */
+        if (GetMessage(&msg, NULL, 0, 0) <= 0)
             return 0;
 
-        if (dwWaitVal == WAIT_OBJECT_0) {
+        if (msg.message == WM_TIMER) {
             WCHAR    text[260];
 
-            /* Reset our event */
-            ResetEvent(hProcessPageEvent);
-
             UpdateProcesses();
 
             if (IsWindowVisible(hProcessPage))
@@ -414,9 +432,11 @@ void UpdateProcesses()
 {
     int i;
     ULONG l;
-    LV_ITEM    item;
+    LV_ITEM item;
     LPPROCESS_PAGE_LIST_ITEM pData;
 
+    SendMessage(hProcessPageListCtrl, WM_SETREDRAW, FALSE, 0);
+
     /* Remove old processes */
     for (i = 0; i < ListView_GetItemCount(hProcessPageListCtrl); i++)
     {
@@ -431,14 +451,23 @@ void UpdateProcesses()
             HeapFree(GetProcessHeap(), 0, pData);
         }
     }
-    for (l = 0; l < PerfDataGetProcessCount(); l++)
+
+    /* Check for difference in listview process and performance process counts */
+    if (ListView_GetItemCount(hProcessPageListCtrl) != PerfDataGetProcessCount())
     {
-        AddProcess(l);
+        /* Add new processes by checking against the current items */
+        for (l = 0; l < PerfDataGetProcessCount(); l++)
+        {
+            AddProcess(l);
+        }
     }
+
     if (TaskManagerSettings.SortColumn != -1)
     {
         (void)ListView_SortItems(hProcessPageListCtrl, ProcessPageCompareFunc, NULL);
     }
+
+    SendMessage(hProcessPageListCtrl, WM_SETREDRAW, TRUE, 0);
 }
 
 BOOL ProcessRunning(ULONG ProcessId) 
@@ -482,7 +511,7 @@ void AddProcess(ULONG Index)
         item.iItem = i;
         (void)ListView_GetItem(hProcessPageListCtrl, &item);
         pData = (LPPROCESS_PAGE_LIST_ITEM)item.lParam;
-        if (PerfDataGetProcessId(pData->Index) == pid)
+        if (pData->ProcessId == pid)
         {
             bAlreadyInList = TRUE;
             break;
@@ -491,7 +520,6 @@ void AddProcess(ULONG Index)
     if (!bAlreadyInList)  /* Add */
     {
         pData = (LPPROCESS_PAGE_LIST_ITEM)HeapAlloc(GetProcessHeap(), 0, sizeof(PROCESS_PAGE_LIST_ITEM));
-        pData->Index = Index;
         pData->ProcessId = pid;
 
         /* Add the item to the list */
@@ -686,6 +714,8 @@ int CALLBACK ProcessPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lPara
     int ret = 0;
     LPPROCESS_PAGE_LIST_ITEM Param1;
     LPPROCESS_PAGE_LIST_ITEM Param2;
+    ULONG IndexParam1;
+    ULONG IndexParam2;
     WCHAR text1[260];
     WCHAR text2[260];
     ULONG l1;
@@ -704,165 +734,167 @@ int CALLBACK ProcessPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lPara
         Param1 = (LPPROCESS_PAGE_LIST_ITEM)lParam2;
         Param2 = (LPPROCESS_PAGE_LIST_ITEM)lParam1;
     }
+    IndexParam1 = PerfDataGetProcessIndex(Param1->ProcessId);
+    IndexParam2 = PerfDataGetProcessIndex(Param2->ProcessId);
 
     if (TaskManagerSettings.SortColumn == COLUMN_IMAGENAME)
     {
-        PerfDataGetImageName(Param1->Index, text1, sizeof (text1) / sizeof (*text1));
-        PerfDataGetImageName(Param2->Index, text2, sizeof (text2) / sizeof (*text2));
+        PerfDataGetImageName(IndexParam1, text1, sizeof (text1) / sizeof (*text1));
+        PerfDataGetImageName(IndexParam2, text2, sizeof (text2) / sizeof (*text2));
         ret = _wcsicmp(text1, text2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_PID)
     {
-        l1 = PerfDataGetProcessId(Param1->Index);
-        l2 = PerfDataGetProcessId(Param2->Index);
+        l1 = Param1->ProcessId;
+        l2 = Param2->ProcessId;
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_USERNAME)
     {
-        PerfDataGetUserName(Param1->Index, text1, sizeof (text1) / sizeof (*text1));
-        PerfDataGetUserName(Param2->Index, text2, sizeof (text2) / sizeof (*text2));
+        PerfDataGetUserName(IndexParam1, text1, sizeof (text1) / sizeof (*text1));
+        PerfDataGetUserName(IndexParam2, text2, sizeof (text2) / sizeof (*text2));
         ret = _wcsicmp(text1, text2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_SESSIONID)
     {
-        l1 = PerfDataGetSessionId(Param1->Index);
-        l2 = PerfDataGetSessionId(Param2->Index);
+        l1 = PerfDataGetSessionId(IndexParam1);
+        l2 = PerfDataGetSessionId(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_CPUUSAGE)
     {
-        l1 = PerfDataGetCPUUsage(Param1->Index);
-        l2 = PerfDataGetCPUUsage(Param2->Index);
+        l1 = PerfDataGetCPUUsage(IndexParam1);
+        l2 = PerfDataGetCPUUsage(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_CPUTIME)
     {
-        time1 = PerfDataGetCPUTime(Param1->Index);
-        time2 = PerfDataGetCPUTime(Param2->Index);
+        time1 = PerfDataGetCPUTime(IndexParam1);
+        time2 = PerfDataGetCPUTime(IndexParam2);
         ret = largeintcmp(time1, time2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_MEMORYUSAGE)
     {
-        l1 = PerfDataGetWorkingSetSizeBytes(Param1->Index);
-        l2 = PerfDataGetWorkingSetSizeBytes(Param2->Index);
+        l1 = PerfDataGetWorkingSetSizeBytes(IndexParam1);
+        l2 = PerfDataGetWorkingSetSizeBytes(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_PEAKMEMORYUSAGE)
     {
-        l1 = PerfDataGetPeakWorkingSetSizeBytes(Param1->Index);
-        l2 = PerfDataGetPeakWorkingSetSizeBytes(Param2->Index);
+        l1 = PerfDataGetPeakWorkingSetSizeBytes(IndexParam1);
+        l2 = PerfDataGetPeakWorkingSetSizeBytes(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_MEMORYUSAGEDELTA)
     {
-        l1 = PerfDataGetWorkingSetSizeDelta(Param1->Index);
-        l2 = PerfDataGetWorkingSetSizeDelta(Param2->Index);
+        l1 = PerfDataGetWorkingSetSizeDelta(IndexParam1);
+        l2 = PerfDataGetWorkingSetSizeDelta(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_PAGEFAULTS)
     {
-        l1 = PerfDataGetPageFaultCount(Param1->Index);
-        l2 = PerfDataGetPageFaultCount(Param2->Index);
+        l1 = PerfDataGetPageFaultCount(IndexParam1);
+        l2 = PerfDataGetPageFaultCount(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_PAGEFAULTSDELTA)
     {
-        l1 = PerfDataGetPageFaultCountDelta(Param1->Index);
-        l2 = PerfDataGetPageFaultCountDelta(Param2->Index);
+        l1 = PerfDataGetPageFaultCountDelta(IndexParam1);
+        l2 = PerfDataGetPageFaultCountDelta(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_VIRTUALMEMORYSIZE)
     {
-        l1 = PerfDataGetVirtualMemorySizeBytes(Param1->Index);
-        l2 = PerfDataGetVirtualMemorySizeBytes(Param2->Index);
+        l1 = PerfDataGetVirtualMemorySizeBytes(IndexParam1);
+        l2 = PerfDataGetVirtualMemorySizeBytes(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_PAGEDPOOL)
     {
-        l1 = PerfDataGetPagedPoolUsagePages(Param1->Index);
-        l2 = PerfDataGetPagedPoolUsagePages(Param2->Index);
+        l1 = PerfDataGetPagedPoolUsagePages(IndexParam1);
+        l2 = PerfDataGetPagedPoolUsagePages(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_NONPAGEDPOOL)
     {
-        l1 = PerfDataGetNonPagedPoolUsagePages(Param1->Index);
-        l2 = PerfDataGetNonPagedPoolUsagePages(Param2->Index);
+        l1 = PerfDataGetNonPagedPoolUsagePages(IndexParam1);
+        l2 = PerfDataGetNonPagedPoolUsagePages(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_BASEPRIORITY)
     {
-        l1 = PerfDataGetBasePriority(Param1->Index);
-        l2 = PerfDataGetBasePriority(Param2->Index);
+        l1 = PerfDataGetBasePriority(IndexParam1);
+        l2 = PerfDataGetBasePriority(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_HANDLECOUNT)
     {
-        l1 = PerfDataGetHandleCount(Param1->Index);
-        l2 = PerfDataGetHandleCount(Param2->Index);
+        l1 = PerfDataGetHandleCount(IndexParam1);
+        l2 = PerfDataGetHandleCount(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_THREADCOUNT)
     {
-        l1 = PerfDataGetThreadCount(Param1->Index);
-        l2 = PerfDataGetThreadCount(Param2->Index);
+        l1 = PerfDataGetThreadCount(IndexParam1);
+        l2 = PerfDataGetThreadCount(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_USEROBJECTS)
     {
-        l1 = PerfDataGetUSERObjectCount(Param1->Index);
-        l2 = PerfDataGetUSERObjectCount(Param2->Index);
+        l1 = PerfDataGetUSERObjectCount(IndexParam1);
+        l2 = PerfDataGetUSERObjectCount(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_GDIOBJECTS)
     {
-        l1 = PerfDataGetGDIObjectCount(Param1->Index);
-        l2 = PerfDataGetGDIObjectCount(Param2->Index);
+        l1 = PerfDataGetGDIObjectCount(IndexParam1);
+        l2 = PerfDataGetGDIObjectCount(IndexParam2);
         ret = CMP(l1, l2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOREADS)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.ReadOperationCount;
         ull2 = iocounters2.ReadOperationCount;
         ret = CMP(ull1, ull2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOWRITES)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.WriteOperationCount;
         ull2 = iocounters2.WriteOperationCount;
         ret = CMP(ull1, ull2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOOTHER)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.OtherOperationCount;
         ull2 = iocounters2.OtherOperationCount;
         ret = CMP(ull1, ull2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOREADBYTES)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.ReadTransferCount;
         ull2 = iocounters2.ReadTransferCount;
         ret = CMP(ull1, ull2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOWRITEBYTES)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.WriteTransferCount;
         ull2 = iocounters2.WriteTransferCount;
         ret = CMP(ull1, ull2);
     }
     else if (TaskManagerSettings.SortColumn == COLUMN_IOOTHERBYTES)
     {
-        PerfDataGetIOCounters(Param1->Index, &iocounters1);
-        PerfDataGetIOCounters(Param2->Index, &iocounters2);
+        PerfDataGetIOCounters(IndexParam1, &iocounters1);
+        PerfDataGetIOCounters(IndexParam2, &iocounters2);
         ull1 = iocounters1.OtherTransferCount;
         ull2 = iocounters2.OtherTransferCount;
         ret = CMP(ull1, ull2);