Signed-off-by: Haoyang Chen chenhaoyang@uniontech.com --- programs/taskmgr/perfdata.c | 85 +++++++++++++++++++++++++++++++++++++ programs/taskmgr/perfdata.h | 1 + programs/taskmgr/procpage.c | 20 ++++----- 3 files changed, 94 insertions(+), 12 deletions(-)
diff --git a/programs/taskmgr/perfdata.c b/programs/taskmgr/perfdata.c index 2cbd6b01669..5adea4db595 100644 --- a/programs/taskmgr/perfdata.c +++ b/programs/taskmgr/perfdata.c @@ -29,6 +29,7 @@
#include "taskmgr.h" #include "perfdata.h" +#include "column.h"
static CRITICAL_SECTION PerfDataCriticalSection; static PPERFDATA pPerfDataOld = NULL; /* Older perf data (saved to establish delta values) */ @@ -833,3 +834,87 @@ ULONG PerfDataGetTotalThreadCount(void)
return ThreadCount; } + +static BOOL bSortAscending = TRUE; +static UINT ColumnDataHintIndex = 0; +static INT ProcessPageCompareFunc(const VOID* first, const VOID* second) +{ + PPERFDATA pPerfData1 = NULL; + PPERFDATA pPerfData2 = NULL; + + if (bSortAscending) + { + pPerfData1 = (PPERFDATA) first; + pPerfData2 = (PPERFDATA) second; + } + else + { + pPerfData2 = (PPERFDATA) first; + pPerfData1 = (PPERFDATA) second; + } + + switch (ColumnDataHintIndex) + { + case COLUMN_IMAGENAME: + return lstrcmpW(pPerfData1->ImageName, pPerfData2->ImageName); + case COLUMN_PID: + return pPerfData1->ProcessId > pPerfData2->ProcessId; + case COLUMN_USERNAME: + return lstrcmpW(pPerfData1->UserName, pPerfData2->UserName); + case COLUMN_SESSIONID: + return pPerfData1->SessionId > pPerfData2->SessionId; + case COLUMN_CPUUSAGE: + return pPerfData1->CPUUsage > pPerfData2->CPUUsage; + case COLUMN_CPUTIME: + return pPerfData1->CPUTime.QuadPart > pPerfData2->CPUTime.QuadPart; + case COLUMN_MEMORYUSAGE: + return pPerfData1->vmCounters.WorkingSetSize > pPerfData2->vmCounters.WorkingSetSize; + case COLUMN_PEAKMEMORYUSAGE: + return pPerfData1->vmCounters.PeakWorkingSetSize > pPerfData2->vmCounters.PeakWorkingSetSize; + case COLUMN_MEMORYUSAGEDELTA: + return pPerfData1->WorkingSetSizeDelta > pPerfData2->WorkingSetSizeDelta; + case COLUMN_PAGEFAULTS: + return pPerfData1->vmCounters.PageFaultCount > pPerfData2->vmCounters.PageFaultCount; + case COLUMN_PAGEFAULTSDELTA: + return pPerfData1->PageFaultCountDelta > pPerfData2->PageFaultCountDelta; + case COLUMN_VIRTUALMEMORYSIZE: + return pPerfData1->vmCounters.VirtualSize > pPerfData2->vmCounters.VirtualSize; + case COLUMN_PAGEDPOOL: + return pPerfData1->vmCounters.QuotaPagedPoolUsage > pPerfData2->vmCounters.QuotaPagedPoolUsage; + case COLUMN_NONPAGEDPOOL: + return pPerfData1->vmCounters.QuotaNonPagedPoolUsage > pPerfData2->vmCounters.QuotaNonPagedPoolUsage; + case COLUMN_BASEPRIORITY: + return pPerfData1->BasePriority > pPerfData2->BasePriority; + case COLUMN_HANDLECOUNT: + return pPerfData1->HandleCount > pPerfData2->HandleCount; + case COLUMN_THREADCOUNT: + return pPerfData1->ThreadCount > pPerfData2->ThreadCount; + case COLUMN_USEROBJECTS: + return pPerfData1->USERObjectCount > pPerfData2->USERObjectCount; + case COLUMN_GDIOBJECTS: + return pPerfData1->GDIObjectCount > pPerfData2->GDIObjectCount; + case COLUMN_IOREADS: + return pPerfData1->IOCounters.ReadOperationCount > pPerfData2->IOCounters.ReadOperationCount; + case COLUMN_IOWRITES: + return pPerfData1->IOCounters.WriteOperationCount > pPerfData2->IOCounters.WriteOperationCount; + case COLUMN_IOREADBYTES: + return pPerfData1->IOCounters.ReadTransferCount > pPerfData2->IOCounters.ReadTransferCount; + case COLUMN_IOWRITEBYTES: + return pPerfData1->IOCounters.WriteTransferCount > pPerfData2->IOCounters.WriteTransferCount; + case COLUMN_IOOTHERBYTES: + return pPerfData1->IOCounters.OtherTransferCount > pPerfData2->IOCounters.OtherTransferCount; + } + return 0; +} + +VOID PerDataSort(UINT iColumnDataHintIndex) +{ + EnterCriticalSection(&PerfDataCriticalSection); + + bSortAscending = !bSortAscending; + ColumnDataHintIndex = iColumnDataHintIndex; + + qsort(pPerfData, ProcessCount, sizeof(PERFDATA), ProcessPageCompareFunc); + + LeaveCriticalSection(&PerfDataCriticalSection); +} diff --git a/programs/taskmgr/perfdata.h b/programs/taskmgr/perfdata.h index 615e7db2a64..22d2a1bf1ea 100644 --- a/programs/taskmgr/perfdata.h +++ b/programs/taskmgr/perfdata.h @@ -110,4 +110,5 @@ ULONG PerfDataGetSystemHandleCount(void);
ULONG PerfDataGetTotalThreadCount(void);
+VOID PerDataSort(UINT iColumnDataHintIndex); #endif /* __PERFDATA_H */ diff --git a/programs/taskmgr/procpage.c b/programs/taskmgr/procpage.c index 5ea2e6b044f..b04e6c59b04 100644 --- a/programs/taskmgr/procpage.c +++ b/programs/taskmgr/procpage.c @@ -148,7 +148,7 @@ static void ProcessPageShowContextMenu(DWORD dwProcessId)
static void ProcessPageOnNotify(LPARAM lParam) { - LPNMHDR pnmh; + LPNMHEADERW pnmh; NMLVDISPINFOW* pnmdi; LVITEMW lvitem; ULONG Index, Count; @@ -159,12 +159,12 @@ static void ProcessPageOnNotify(LPARAM lParam) static const WCHAR wszFmt02D[] = {'%','0','2','d',0}; static const WCHAR wszUnitK[] = {' ','K',0};
- pnmh = (LPNMHDR) lParam; + pnmh = (LPNMHEADERW) lParam; pnmdi = (NMLVDISPINFOW*) lParam;
- if (pnmh->hwndFrom == hProcessPageListCtrl) + if (pnmh->hdr.hwndFrom == hProcessPageListCtrl) { - switch (pnmh->code) + switch (pnmh->hdr.code) { case LVN_GETDISPINFOW:
@@ -337,18 +337,14 @@ static void ProcessPageOnNotify(LPARAM lParam)
} } - else if (pnmh->hwndFrom == hProcessPageHeaderCtrl) + else if (pnmh->hdr.hwndFrom == hProcessPageHeaderCtrl) { - switch (pnmh->code) + switch (pnmh->hdr.code) { case HDN_ITEMCLICKW:
- /* - * FIXME: Fix the column sorting - * - *ListView_SortItems(hApplicationPageListCtrl, ApplicationPageCompareFunc, NULL); - *bSortAscending = !bSortAscending; - */ + PerDataSort(ColumnDataHints[pnmh->iItem]); + InvalidateRect(hProcessPageListCtrl, NULL, TRUE);
break;
On 4/6/21 12:45 PM, Haoyang Chen wrote:
+static BOOL bSortAscending = TRUE; +static UINT ColumnDataHintIndex = 0; +static INT ProcessPageCompareFunc(const VOID* first, const VOID* second)
You could probably use qsort_s() to pack that, also please fix prototype.
- switch (ColumnDataHintIndex)
- {
case COLUMN_IMAGENAME:
return lstrcmpW(pPerfData1->ImageName, pPerfData2->ImageName);
case COLUMN_PID:
return pPerfData1->ProcessId > pPerfData2->ProcessId;
case COLUMN_USERNAME:
return lstrcmpW(pPerfData1->UserName, pPerfData2->UserName);
case COLUMN_SESSIONID:
return pPerfData1->SessionId > pPerfData2->SessionId;
case COLUMN_CPUUSAGE:
return pPerfData1->CPUUsage > pPerfData2->CPUUsage;
case COLUMN_CPUTIME:
return pPerfData1->CPUTime.QuadPart > pPerfData2->CPUTime.QuadPart;
case COLUMN_MEMORYUSAGE:
return pPerfData1->vmCounters.WorkingSetSize > pPerfData2->vmCounters.WorkingSetSize;
case COLUMN_PEAKMEMORYUSAGE:
return pPerfData1->vmCounters.PeakWorkingSetSize > pPerfData2->vmCounters.PeakWorkingSetSize;
case COLUMN_MEMORYUSAGEDELTA:
return pPerfData1->WorkingSetSizeDelta > pPerfData2->WorkingSetSizeDelta;
case COLUMN_PAGEFAULTS:
return pPerfData1->vmCounters.PageFaultCount > pPerfData2->vmCounters.PageFaultCount;
case COLUMN_PAGEFAULTSDELTA:
return pPerfData1->PageFaultCountDelta > pPerfData2->PageFaultCountDelta;
case COLUMN_VIRTUALMEMORYSIZE:
return pPerfData1->vmCounters.VirtualSize > pPerfData2->vmCounters.VirtualSize;
case COLUMN_PAGEDPOOL:
return pPerfData1->vmCounters.QuotaPagedPoolUsage > pPerfData2->vmCounters.QuotaPagedPoolUsage;
case COLUMN_NONPAGEDPOOL:
return pPerfData1->vmCounters.QuotaNonPagedPoolUsage > pPerfData2->vmCounters.QuotaNonPagedPoolUsage;
case COLUMN_BASEPRIORITY:
return pPerfData1->BasePriority > pPerfData2->BasePriority;
case COLUMN_HANDLECOUNT:
return pPerfData1->HandleCount > pPerfData2->HandleCount;
case COLUMN_THREADCOUNT:
return pPerfData1->ThreadCount > pPerfData2->ThreadCount;
case COLUMN_USEROBJECTS:
return pPerfData1->USERObjectCount > pPerfData2->USERObjectCount;
case COLUMN_GDIOBJECTS:
return pPerfData1->GDIObjectCount > pPerfData2->GDIObjectCount;
case COLUMN_IOREADS:
return pPerfData1->IOCounters.ReadOperationCount > pPerfData2->IOCounters.ReadOperationCount;
case COLUMN_IOWRITES:
return pPerfData1->IOCounters.WriteOperationCount > pPerfData2->IOCounters.WriteOperationCount;
case COLUMN_IOREADBYTES:
return pPerfData1->IOCounters.ReadTransferCount > pPerfData2->IOCounters.ReadTransferCount;
case COLUMN_IOWRITEBYTES:
return pPerfData1->IOCounters.WriteTransferCount > pPerfData2->IOCounters.WriteTransferCount;
case COLUMN_IOOTHERBYTES:
return pPerfData1->IOCounters.OtherTransferCount > pPerfData2->IOCounters.OtherTransferCount;
- }
Have you tested this? I looks like it will only work correctly for string fields.
static void ProcessPageOnNotify(LPARAM lParam) {
- LPNMHDR pnmh;
- LPNMHEADERW pnmh;
This is incorrect.
- else if (pnmh->hwndFrom == hProcessPageHeaderCtrl)
- else if (pnmh->hdr.hwndFrom == hProcessPageHeaderCtrl) {
switch (pnmh->code)
switch (pnmh->hdr.code) { case HDN_ITEMCLICKW:
/*
* FIXME: Fix the column sorting
*
*ListView_SortItems(hApplicationPageListCtrl, ApplicationPageCompareFunc, NULL);
*bSortAscending = !bSortAscending;
*/
PerDataSort(ColumnDataHints[pnmh->iItem]);
InvalidateRect(hProcessPageListCtrl, NULL, TRUE); break;
Again, why do you sort only on user clicks? How should it work?