windows-nt/Source/XPSP1/NT/shell/applets/taskmgr/pages.h
2020-09-26 16:20:57 +08:00

668 lines
20 KiB
C++

//+-------------------------------------------------------------------------
//
// TaskMan - NT TaskManager
// Copyright (C) Microsoft
//
// File: pages.h
//
// History: Nov-10-95 DavePl Created
//
//--------------------------------------------------------------------------
// CPage class
//
// Each of our tabs is represented by an instance of a class derived
// from the CPage class. This way, the main window can call a standard
// set of methods (size, paint, etc) on each page without concern about
// the particular functionality each page provides.
class CPage
{
public:
// Sent when page is being created
virtual HRESULT Initialize(HWND hwndParent) PURE;
// Sent when page is being displayed
virtual HRESULT Activate() PURE;
// Sent when page is being hidden
virtual void Deactivate() PURE;
// Send when page is being shut down
virtual HRESULT Destroy() PURE;
// Returns the title of the page for use on the tab control
virtual void GetTitle(LPTSTR pszText, size_t bufsize) PURE;
// Returns the handle to the page's main dialog
virtual HWND GetPageWindow() PURE;
// Sent when a timer event (update display) occurs
virtual void TimerEvent() PURE;
};
#define CPU_PENS 8
#define CUSTOM_PENS 1
#define NUM_PENS (CPU_PENS + CUSTOM_PENS)
typedef struct tagGRAPH
{
HWND hwndFrame;
HWND hwndGraph;
}
GRAPH, *PGRAPH;
enum ADAPTER_HISTORY
{
BYTES_SENT_UTIL = 0,
BYTES_RECEIVED_UTIL = 1
};
extern "C"
{
// IPHLPAPI does not have this function defines in the header file
// kind of a private undocumented function.
//
DWORD
NhGetInterfaceNameFromDeviceGuid(
IN GUID *pGuid,
OUT PWCHAR pwszBuffer,
IN OUT PULONG pulBufferSize,
IN BOOL bCache,
IN BOOL bRefresh
);
}
#define MAX_ADAPTERS 32
#define GUID_STR_LENGTH 38
typedef struct tagADAPTER_INFOEX
{
MIB_IFROW ifRowStartStats;
MIB_IFROW ifRowStats[2];
ULONG ulHistory[2][HIST_SIZE];
ULONGLONG ullLinkspeed;
BOOLEAN bAdjustLinkSpeed;
WCHAR wszDesc[MAXLEN_IFDESCR];
WCHAR wszConnectionName[MAXLEN_IFDESCR];
WCHAR wszGuid[GUID_STR_LENGTH + 1];
ULONGLONG ullLastTickCount;
ULONGLONG ullTickCountDiff;
DWORD dwScale;
}
ADAPTER_INFOEX, *PADAPTER_INFOEX, **PPADAPTER_INFOEX;
class CAdapter
{
public:
CAdapter();
HRESULT Update(BOOLEAN & bAdapterListChange);
LPWSTR GetAdapterText(DWORD dwAdapter, NETCOLUMNID nStatValue);
ULONGLONG GetAdapterStat(DWORD dwAdapter, NETCOLUMNID nStatValue, BOOL bAccumulative = FALSE);
HRESULT Reset();
ULONG *GetAdapterHistory(DWORD dwAdapter, ADAPTER_HISTORY nHistoryType);
DWORD GetScale(DWORD dwAdapter);
void SetScale(DWORD dwAdapter, DWORD dwScale);
void RefreshConnectionNames();
DWORD GetNumberOfAdapters();
~CAdapter();
private:
HRESULT RefreshAdapterTable();
HRESULT InitializeAdapter(PPADAPTER_INFOEX ppaiAdapterStats, PIP_ADAPTER_INDEX_MAP pAdapterDescription);
void AdjustLinkSpeed(PADAPTER_INFOEX pAdapterInfo);
HRESULT GetConnectionName(LPWSTR pwszAdapterGuid, LPWSTR pwszConnectionName);
BOOLEAN AdvanceAdapterHistory(DWORD dwAdapter);
private:
PIP_INTERFACE_INFO m_pifTable;
PPADAPTER_INFOEX m_ppaiAdapterStats;
DWORD m_dwAdapterCount;
BOOLEAN m_bToggle;
DWORD m_dwLastReportedNumberOfAdapters;
};
// CNetworkPage
//
// Class describing the network page
//
class CNetPage : public CPage
{
public:
CNetPage();
HRESULT Initialize(HWND hwndParent);
DWORD GetNumberOfGraphs();
HRESULT SetupColumns();
void ScrollGraphs(WPARAM wParam, LPARAM lParam);
void SaveColumnWidths();
//void RestoreColumnWidths();
void RememberColumnOrder(HWND hwndList);
void RestoreColumnOrder(HWND hwndList);
void PickColumns();
HRESULT Activate();
void Deactivate();
void DrawAdapterGraph(LPDRAWITEMSTRUCT lpdi, UINT iPane);
void SizeNetPage();
void TimerEvent();
void UpdateGraphs();
void Reset();
void Refresh();
HWND GetPageWindow()
{
return m_hPage;
}
~CNetPage();
private:
DWORD GraphsPerPage(DWORD dwHeight, DWORD dwAdapterCount);
void SizeGraph(HDWP hdwp, GRAPH *pGraph, RECT *pRect, RECT *pDimRect);
void HideGraph(HDWP hdwp, GRAPH *pGraph);
HRESULT UpdatePage();
void CreatePens();
void ReleasePens();
void CalcNetTime(BOOL fUpdateHistory);
DWORD DrawGraph(LPRECT prc, HPEN hPen, DWORD dwZoom, ULONG *pHistory, ULONG *pHistory2 = NULL);
HRESULT CreateMemoryBitmaps(int x, int y);
void FreeMemoryBitmaps();
HRESULT Destroy();
void GetTitle(LPTSTR pszText, size_t bufsize);
void ReleaseScaleFont();
void CreateScaleFont(HDC hdc);
ULONG DrawAdapterGraphPaper(HDC hdcGraph, RECT * prcGraph, int Width, DWORD dwZoom);
INT DrawScale(HDC hdcGraph, RECT *prcGraph, DWORD dwZoom);
WCHAR * CommaNumber(ULONGLONG ullValue, WCHAR *pwsz, int cchNumber);
WCHAR * SimplifyNumber(ULONGLONG ullValue, WCHAR *psz);
WCHAR * FloatToString(ULONGLONG ulValue, WCHAR *psz, BOOLEAN bDisplayDecimal = FALSE);
private:
CAdapter m_Adapter;
HWND m_hPage; // Handle to this page's dlg
HWND m_hwndTabs; // Parent window
HDC m_hdcGraph; // Inmemory dc for cpu hist
HBITMAP m_hbmpGraph; // Inmemory bmp for cpu hist
HPEN m_hPens[3]; // Our box of crayons
RECT m_rcGraph;
BOOL m_bReset;
BOOL m_bPageActive; // Tells the class if the Network tab is active (i.e. the user is looking at it)
// If the tab is not active we will not collect network data unless the user selects
// the menu option to do so. (We same some CPU usage then. .
HFONT m_hScaleFont;
LONG m_lScaleFontHeight;
LONG m_lScaleWidth;
private:
HRESULT CreateGraphs(DWORD dwGraphsRequired);
void DestroyGraphs();
DWORD GetFirstVisibleAdapter();
void LabelGraphs();
private:
PGRAPH m_pGraph;
DWORD m_dwGraphCount;
DWORD m_dwFirstVisibleAdapter;
DWORD m_dwGraphsPerPage;
HWND m_hScrollBar;
HWND m_hListView;
HWND m_hNoAdapterText;
};
// CPerfPage
//
// Class describing the performance page
class CPerfPage : public CPage
{
HWND m_hPage; // Handle to this page's dlg
HWND m_hwndTabs; // Parent window
HBITMAP m_hStripUnlit; // Digits bitmap
HBITMAP m_hStripLitRed; // Digits bitmap
HBITMAP m_hStripLit; // Digits bitmap
HDC m_hdcGraph; // Inmemory dc for cpu hist
HBITMAP m_hbmpGraph; // Inmemory bmp for cpu hist
HPEN m_hPens[NUM_PENS]; // Our box of crayons
RECT m_rcGraph;
public:
CPerfPage()
{
ZeroMemory((LPVOID) m_hPens, sizeof(m_hPens));
}
virtual ~CPerfPage()
{
};
HRESULT Initialize(HWND hwndParent);
HRESULT Activate();
void Deactivate();
HRESULT Destroy();
void GetTitle(LPTSTR pszText, size_t bufsize);
void SizePerfPage();
void TimerEvent();
HWND GetPageWindow()
{
return m_hPage;
}
void DrawCPUGraph(LPDRAWITEMSTRUCT lpdi, UINT iPane);
void DrawMEMGraph(LPDRAWITEMSTRUCT lpdi);
void DrawCPUDigits(LPDRAWITEMSTRUCT lpdi);
void DrawMEMMeter(LPDRAWITEMSTRUCT lpdi);
void UpdateCPUHistory();
void FreeMemoryBitmaps();
HRESULT CreateMemoryBitmaps(int x, int y);
void SetTimer(HWND hwnd, UINT milliseconds);
void CreatePens();
void ReleasePens();
void UpdateGraphs();
int TextToLegend(HDC hDC, int xPos, int yPos, LPCTSTR szCPUName);
};
// CSysInfo
//
// Some misc global info about the system
class CSysInfo
{
public:
// These fields MUST all be DWORDS because we manually index into
// them individually in procperf.cpp
DWORD m_cHandles;
DWORD m_cThreads;
DWORD m_cProcesses;
DWORD m_dwPhysicalMemory;
DWORD m_dwPhysAvail;
DWORD m_dwFileCache;
DWORD m_dwKernelPaged;
DWORD m_dwKernelNP;
DWORD m_dwKernelTotal;
DWORD m_dwCommitTotal;
DWORD m_dwCommitLimit;
DWORD m_dwCommitPeak;
CSysInfo()
{
ZeroMemory(this, sizeof(CSysInfo));
}
};
// CProcessPage
//
// Class describing the process list page
class CPtrArray; // Forward reference
class CProcInfo;
class CProcPage : public CPage
{
HWND m_hPage; // Handle to this page's dlg
HWND m_hwndTabs; // Parent window
CPtrArray * m_pProcArray; // Ptr array of running processes
LPVOID m_pvBuffer; // Buffer for NtQuerySystemInfo
size_t m_cbBuffer; // Size of the above buffer, in bytes
CSysInfo m_SysInfo;
BOOL m_fPaused; // Updates paused (during trackpopupmenu)
LPTSTR m_pszDebugger; // Debugger command in registry
public:
HRESULT Initialize(HWND hwndParent);
HRESULT Activate();
void Deactivate();
HRESULT Destroy();
void GetTitle(LPTSTR pszText, size_t bufsize);
void TimerEvent();
HWND GetPageWindow()
{
return m_hPage;
}
void PickColumns();
void SaveColumnWidths();
void SizeProcPage();
HRESULT SetupColumns();
HRESULT UpdateProcInfoArray();
HRESULT UpdateProcListview();
HRESULT GetProcessInfo();
INT HandleProcPageNotify(HWND, LPNMHDR);
void HandleProcListContextMenu(INT xPos, INT yPos);
CProcInfo * GetSelectedProcess();
//void HandleWMCOMMAND(INT id);
void HandleWMCOMMAND( WORD , HWND );
BOOL IsSystemProcess(DWORD pid, CProcInfo * pProcInfo);
BOOL KillProcess(DWORD pid, BOOL bBatch = FALSE);
BOOL KillAllChildren(DWORD dwTaskPid, DWORD pid, BYTE* pbBuffer, LARGE_INTEGER CreateTime);
BOOL SetPriority(CProcInfo * pProc, DWORD idCmd);
BOOL AttachDebugger(DWORD pid);
UINT QuickConfirm(UINT idTitle, UINT idBody);
BOOL SetAffinity(DWORD pid);
typedef struct _TASK_LIST {
DWORD dwProcessId;
DWORD dwInheritedFromProcessId;
ULARGE_INTEGER CreateTime;
BOOL flags;
} TASK_LIST, *PTASK_LIST;
BOOL RecursiveKill(DWORD pid);
BYTE* GetTaskListEx();
// Constructor
CProcPage()
{
m_hPage = NULL;
m_hwndTabs = NULL;
m_pProcArray = NULL;
m_pvBuffer = NULL;
m_cbBuffer = 0;
m_fPaused = FALSE;
m_pszDebugger = NULL;
}
virtual ~CProcPage();
// The dialog proc needs to be able to set the m_hPage member, so
// make it a friend
friend INT_PTR CALLBACK ProcPageProc(
HWND hwnd, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
// The WOW task callback proc needs to be able to get m_pProcArray,
// so make it a friend.
friend BOOL WINAPI WowTaskCallback(
DWORD dwThreadId,
WORD hMod16,
WORD hTask16,
PSZ pszModName,
PSZ pszFileName,
LPARAM lparam
);
private:
void Int64ToCommaSepString(LONGLONG n, LPTSTR pszOut, int cchOut);
void Int64ToCommaSepKString(LONGLONG n, LPTSTR pszOut, int cchOut);
void RememberColumnOrder(HWND hwndList);
void RestoreColumnOrder(HWND hwndList);
};
class TASK_LIST_ENUM; // Forward ref
// THREADPARAM
//
// Uses as a communication struct between task page and its worker thread
class THREADPARAM
{
public:
WINSTAENUMPROC m_lpEnumFunc;
LPARAM m_lParam;
HANDLE m_hEventChild;
HANDLE m_hEventParent;
BOOL m_fThreadExit;
BOOL m_fSuccess;
THREADPARAM::THREADPARAM()
{
ZeroMemory(this, sizeof(THREADPARAM));
}
};
// CTaskPage
//
// Class describing the task manager page
class CTaskPage : public CPage
{
private:
HWND m_hPage; // Handle to this page's dlg
HWND m_hwndTabs; // Parent window
CPtrArray * m_pTaskArray; // Array of active tasks
BOOL m_fPaused; // BOOL, is display refresh paused for menu
HIMAGELIST m_himlSmall; // Image lists
HIMAGELIST m_himlLarge;
VIEWMODE m_vmViewMode; // Large or small icon mode
UINT m_cSelected; // Count of items selected
THREADPARAM m_tp;
HANDLE m_hEventChild;
HANDLE m_hEventParent;
HANDLE m_hThread;
typedef struct _open_failures_
{
TCHAR *_pszWindowStationName;
TCHAR *_pszDesktopName;
struct _open_failures_ *_pofNext;
} OPEN_FAILURE, *LPOPEN_FAILURE;
OPEN_FAILURE *m_pofFailures;
protected:
void RemoveAllTasks();
HRESULT LoadDefaultIcons();
public:
CTaskPage()
{
m_hPage = NULL;
m_hwndTabs = NULL;
m_fPaused = FALSE;
m_pTaskArray = NULL;
m_himlSmall = NULL;
m_himlLarge = NULL;
m_hEventChild = NULL;
m_hEventParent = NULL;
m_hThread = NULL;
m_vmViewMode = g_Options.m_vmViewMode;
m_cSelected = 0;
m_pofFailures = NULL;
}
virtual ~CTaskPage();
HRESULT Initialize(HWND hwndParent);
HRESULT Activate();
void Deactivate();
HRESULT Destroy();
void GetTitle(LPTSTR pszText, size_t bufsize);
void TimerEvent();
HWND GetPageWindow()
{
return m_hPage;
}
void SizeTaskPage();
HRESULT SetupColumns();
void GetRunningTasks(TASK_LIST_ENUM * te);
void HandleWMCOMMAND(INT id);
HRESULT UpdateTaskListview();
INT HandleTaskPageNotify(HWND hWnd, LPNMHDR pnmhdr);
void HandleTaskListContextMenu(INT xPos, INT yPos);
BOOL CreateNewDesktop();
CPtrArray * GetSelectedTasks();
void UpdateUIState();
HWND * GetHWNDS(BOOL fSelectedOnly, DWORD * pdwCount);
void EnsureWindowsNotMinimized(HWND aHwnds[], DWORD dwCount);
BOOL HasAlreadyOpenFailed(TCHAR *pszWindowStationName, TCHAR *pszDesktopName);
void SetOpenFailed(TCHAR *pszWindowStationName, TCHAR *pszDesktopName);
void FreeOpenFailures(void);
BOOL DoEnumWindowStations(WINSTAENUMPROC lpEnumFunc, LPARAM lParam);
void OnSettingsChange();
void Pause()
{
m_fPaused = TRUE;
}
void Unpause()
{
m_fPaused = FALSE;
}
// The dialog proc needs to be able to set the m_hPage member, so
// make it a friend
friend INT_PTR CALLBACK TaskPageProc(
HWND hwnd, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
// The enum callback needs to get at our imagelists as it encounters
// new tasls, so it can add their icons to the lists
friend BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
};
// TASK_LIST_ENUM
//
// Object passed around during window enumeration
class TASK_LIST_ENUM
{
public:
CPtrArray * m_pTasks;
LPTSTR lpWinsta;
LPTSTR lpDesk;
LARGE_INTEGER uPassCount;
CTaskPage * m_pPage;
TASK_LIST_ENUM()
{
ZeroMemory(this, sizeof(TASK_LIST_ENUM));
}
};
typedef TASK_LIST_ENUM *PTASK_LIST_ENUM;
// CUserPage
//
// Class describing the task manager page
class CUserPage : public CPage
{
private:
HWND m_hPage; // Handle to this page's dlg
HWND m_hwndTabs; // Parent window
CPtrArray * m_pUserArray; // Array of active users
BOOL m_fPaused; // BOOL, is display refresh paused for menu
UINT m_cSelected; // Count of items selected
HIMAGELIST m_himlUsers; // Image list for user icons
UINT m_iUserIcon;
UINT m_iCurrentUserIcon;
THREADPARAM m_tp;
HANDLE m_hEventChild;
HANDLE m_hEventParent;
HANDLE m_hThread;
protected:
void RemoveAllUsers();
HRESULT LoadDefaultIcons();
public:
CUserPage()
{
m_hPage = NULL;
m_hwndTabs = NULL;
m_fPaused = FALSE;
m_pUserArray = NULL;
m_hEventChild = NULL;
m_hEventParent = NULL;
m_hThread = NULL;
m_cSelected = 0;
m_himlUsers = NULL;
m_iUserIcon = 0;
m_iCurrentUserIcon = 0;
}
virtual ~CUserPage();
HRESULT Initialize(HWND hwndParent);
HRESULT Activate();
void Deactivate();
HRESULT Destroy();
void GetTitle(LPTSTR pszText, size_t bufsize);
void TimerEvent();
void OnInitDialog(HWND hPage);
HWND GetPageWindow()
{
return m_hPage;
}
void SizeUserPage();
HRESULT SetupColumns();
void GetRunningUsers(TASK_LIST_ENUM * te);
void HandleWMCOMMAND(INT id);
HRESULT UpdateUserListview();
INT HandleUserPageNotify(HWND hWnd, LPNMHDR pnmhdr);
void HandleUserListContextMenu(INT xPos, INT yPos);
CPtrArray * GetSelectedUsers();
void UpdateUIState();
HWND * GetHWNDS(BOOL fSelectedOnly, DWORD * pdwCount);
void EnsureWindowsNotMinimized(HWND aHwnds[], DWORD dwCount);
BOOL DoEnumWindowStations(WINSTAENUMPROC lpEnumFunc, LPARAM lParam);
void OnSettingsChange();
void Pause()
{
m_fPaused = TRUE;
}
void Unpause()
{
m_fPaused = FALSE;
}
};
INT_PTR CALLBACK UserPageProc(
HWND hwnd, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);