// ProcessInfoDlg.cpp : implementation file
//
#include "stdafx.h"
#include "InformationDlg.h"
#include "TaskManagerExDll.h"
#include "Localization.h"
#include "AboutExtension.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE( CInformationDlgThread, CWinThread )
BOOL CInformationDlgThread::InitInstance()
{
SetThreadNativeLanguage();
CInformationDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
PostQuitMessage( 0 ); // quit thread gracefully
return TRUE;
// return FALSE; // return error to quit thread
}
BOOL CInformationDlgThread::Initialize( DWORD pID, WPARAM command )
{
m_processID = pID;
m_command = command;
return TRUE;
}
CInformationDlgThread* CInformationDlgThread::Start( DWORD pID, WPARAM command )
{
CInformationDlgThread* _this = (CInformationDlgThread*)::AfxBeginThread(
RUNTIME_CLASS(CInformationDlgThread),
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED );
_this->Initialize( pID, command );
_this->ResumeThread();
return _this;
}
/////////////////////////////////////////////////////////////////////////////
// CInformationDlg dialog
CInformationDlg::CInformationDlg(CWnd* pParent /*=NULL*/)
: CDialog(CInformationDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CInformationDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_OldClientSize = CSize(0,0);
}
void CInformationDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CInformationDlg)
DDX_Control(pDX, IDC_EXIT, m_wndExit);
DDX_Control(pDX, IDC_INFO, m_wndInfo);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CInformationDlg, CDialog)
//{{AFX_MSG_MAP(CInformationDlg)
ON_WM_CLOSE()
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_EXIT, OnExit)
ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
ON_WM_HELPINFO()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_GETMINMAXINFO()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInformationDlg message handlers
void CInformationDlg::OnClose()
{
CDialog::OnClose();
}
void CInformationDlg::OnDestroy()
{
CDialog::OnDestroy();
m_Font.DeleteObject();
}
void CInformationDlg::OnOK()
{
// CDialog::OnOK();
// OnRefresh();
}
void CInformationDlg::OnCancel()
{
CDialog::OnCancel();
}
void CInformationDlg::OnExit()
{
EndDialog( IDOK );
}
/////////////////////////////////////////////////////////////////////////////
BOOL CInformationDlg::PreTranslateMessage(MSG* pMsg)
{
// CG: The following block was added by the ToolTips component.
{
// Let the ToolTip process this message.
m_tooltip.RelayEvent(pMsg);
}
return CDialog::PreTranslateMessage(pMsg);
}
/////////////////////////////////////////////////////////////////////////////
BOOL CInformationDlg::OnHelpInfo(HELPINFO* pHelpInfo)
{
pHelpInfo = pHelpInfo;
CAboutExtensionThread::Start();
return TRUE;
//return CDialog::OnHelpInfo(pHelpInfo);
}
/////////////////////////////////////////////////////////////////////////////
int CInformationDlg::DoModal()
{
// load resource as necessary
if( m_lpszTemplateName != NULL && m_lpDialogTemplate == NULL )
{
m_lpDialogTemplate = LocLoadDialog( m_lpszTemplateName );
m_lpszTemplateName = NULL;
}
return CDialog::DoModal();
}
/////////////////////////////////////////////////////////////////////////////
void CInformationDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if( ::IsWindow( m_wndInfo.m_hWnd ) )
{
CRect r;
m_wndInfo.GetWindowRect( &r );
ScreenToClient( &r );
r.right += cx - m_OldClientSize.cx;
r.bottom += cy - m_OldClientSize.cy;
m_wndInfo.MoveWindow( &r );
}
if( ::IsWindow( m_wndExit.m_hWnd ) )
{
CRect r;
m_wndExit.GetWindowRect( &r );
ScreenToClient( &r );
r += CPoint( cx - m_OldClientSize.cx, 0 );
m_wndExit.MoveWindow( &r );
m_wndExit.RedrawWindow();
}
m_OldClientSize.cx = cx;
m_OldClientSize.cy = cy;
}
/////////////////////////////////////////////////////////////////////////////
void CInformationDlg::OnGetMinMaxInfo( MINMAXINFO* pMinMaxInfo )
{
CDialog::OnGetMinMaxInfo( pMinMaxInfo );
pMinMaxInfo->ptMinTrackSize = CPoint( 300, 200 );
}
/////////////////////////////////////////////////////////////////////////////
BOOL CInformationDlg::OnInitDialog()
{
CInformationDlgThread* pThread = (CInformationDlgThread*)AfxGetThread();
CDialog::OnInitDialog();
SetIcon( theApp.hMainIconBig, TRUE );
SetIcon( theApp.hMainIconSmall, FALSE );
// SetClassLong( this->GetSafeHwnd(), GCL_HICON, (long)theApp.hMainIconBig ); // this changes icon for any dialog in the process!
// SetClassLong( this->GetSafeHwnd(), GCL_HICONSM, (long)theApp.hMainIconSmall ); // this changes icon for any dialog in the process!
m_Font.CreateFont(16, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0,
_T("Courier New") );
const int iCharTabStop = 4;
const int iDlgTabStop = (iCharTabStop*32+3)/6; // Only for 16x "Courier New"!
m_wndInfo.SetTabStops( iDlgTabStop );
m_wndInfo.SetFont( &m_Font );
// CG: The following block was added by the ToolTips component.
{
// Create the ToolTip control.
m_tooltip.Create(this);
m_tooltip.Activate(TRUE);
m_tooltip.AddTool( GetDlgItem(IDC_EXIT), LocLoadString(IDC_INFO_EXIT) );
m_tooltip.AddTool( GetDlgItem(IDC_REFRESH ), LocLoadString(IDC_INFO_REFRESH) );
// TODO: Use one of the following forms to add controls:
// m_tooltip.AddTool(GetDlgItem(IDC_<name>), <string-table-id>);
// m_tooltip.AddTool(GetDlgItem(IDC_<name>), "<text>");
}
CString strCaption = _T("Unknown");
switch( pThread->m_command )
{
case ID_PROCESSES_INFO:
{
TCHAR szFileName[MAX_PATH] = _T("");
GetProcessExecutableName( pThread->m_processID, szFileName, SIZEOF_ARRAY(szFileName) );
CString s = szFileName;
int pos = s.ReverseFind( _T('\\') );
strCaption.Format( _T("PID = %d(0x%X) - %s - "),
pThread->m_processID, pThread->m_processID, s.Mid(pos+1) );
}
break;
}
switch( pThread->m_command )
{
case ID_PROCESSES_INFO:
strCaption += LocLoadString(IDS_INFORMATION_RPOCESS);
break;
}
SetWindowText( strCaption );
OnRefresh();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
/////////////////////////////////////////////////////////////////////////////
void CInformationDlg::OnRefresh()
{
CInformationDlgThread* pThread = (CInformationDlgThread*)AfxGetThread();
int x = m_wndInfo.GetScrollPos( SB_HORZ );
int y = m_wndInfo.GetScrollPos( SB_VERT );
int iCharWidth = 1;
{
CDC dc;
dc.CreateCompatibleDC( GetDC() );
CFont* pOldFont = dc.SelectObject( &m_Font );
iCharWidth = dc.GetTextExtent( _T(" ") ).cx;
dc.SelectObject( pOldFont );
dc.DeleteDC();
}
CString strInformation;
BOOL res = FALSE;
switch( pThread->m_command )
{
case ID_PROCESSES_INFO:
{
res = GetProcessInformation( strInformation );
}
break;
}
strInformation.Replace( _T("\n"), _T("\r\n") );
m_wndInfo.SetWindowText( strInformation );
m_wndInfo.LineScroll( y, x/iCharWidth );
}
/////////////////////////////////////////////////////////////////////////////
struct FTIME
{
FTIME()
{
li.QuadPart = 0;
}
FTIME( const FILETIME& ft )
{
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
}
FTIME( const LONGLONG& l64 )
{
li.QuadPart = l64;
}
FTIME( const LARGE_INTEGER& li2 )
{
li.QuadPart = li2.QuadPart;
}
operator FILETIME()
{
FILETIME ft;
ft.dwLowDateTime = li.LowPart;
ft.dwHighDateTime = li.HighPart;
return ft;
}
operator LONGLONG()
{
return li.QuadPart;
}
operator LARGE_INTEGER()
{
return li;
}
LARGE_INTEGER li;
};
CString GetPeriod( LONGLONG l64 ) // IN: FILETIME
{
CString s;
LONGLONG milliseconds = l64/10000;
DWORD hours = (DWORD) milliseconds / (3600 * 1000);
DWORD min = (DWORD) (milliseconds / (60 * 1000)) % 60;
DWORD sec = (DWORD) (milliseconds / (1000)) % 60;
DWORD ms = (DWORD) milliseconds % 1000;
s.Format( _T("%d:%02d:%02d.%03d"), hours, min, sec, ms );
return s;
}
/////////////////////////////////////////////////////////////////////////////
BOOL CInformationDlg::GetProcessInformation( CString& info )
{
CInformationDlgThread* pThread = (CInformationDlgThread*)AfxGetThread();
info.Empty();
// Get teh process list
SystemProcessInformation spi( pThread->m_processID, TRUE, TRUE );
DWORD pID;
SystemProcessInformation::PROCESS_INFO pi;
ZeroMemory( &pi, sizeof(pi) );
// Iterating through the processes and get the module list
for ( POSITION pos = spi.m_ProcessInfos.GetStartPosition(); pos != NULL; )
{
spi.m_ProcessInfos.GetNextAssoc( pos, pID, pi );
break; // I hope there is only one process with PID == m_processId 8-)
}
CString d;
TCHAR szBuf[MAX_PATH] = _T("");
CTime t;
SYSTEMTIME st;
GetLocalTime( &st );
FILETIME ft;
SystemTimeToFileTime( &st, &ft );
FILETIME ft2;
GetSystemTimeAsFileTime( &ft2 );
FTIME time1 = ft;
FTIME time2 = ft2;
FTIME ftCreation;
FTIME ftKernel;
FTIME ftUser;
#pragma message (WARNING "Lots of hardcoded strings!")
d.Format( _T("Process \"%ls\" (PID = %d) information:\n"), pi.spi.ProcessName.Buffer, pi.processId );
info += d;
d.Format( _T("=================================================\n\n") );
info += d;
d.Format( _T("Exe image name:\t\t\t\"%s\"\n"), pi.szExe );
info += d;
SystemMemoryMapInformation::FileFromAddress( pThread->m_processID, NULL, szBuf, SIZEOF_ARRAY(szBuf) );
d.Format( _T("Exe file:\t\t\t\t\"%s\"\n"), szBuf );
info += d;
GetProcessExecutableName( pi.spi.InheritedFromProcessId, szBuf, SIZEOF_ARRAY(szBuf) );
d.Format( _T("Parent process:\t\t\tPID = %d, \"%s\"\n"), pi.spi.InheritedFromProcessId, szBuf );
info += d;
d.Format( _T("Base priority:\t\t\t%d; priority boost: %s\n"), pi.spi.BasePriority,
(pi.bDisablePriorityBoost ? _T("Disabled") : _T("Enabled") ) );
info += d;
d.Format( _T("CPU affinity mask:\t\t0x%X; system CPU affinity mask: 0x%X\n"),
pi.dwProcessAffinity, pi.dwSystemAffinity );
info += d;
d.Format( _T("Image version:\t\t\t%d.%d\n"),
HIWORD(pi.dwVersion), LOWORD(pi.dwVersion) );
info += d;
d.Format( _T("Working set:\t\t\t%d, min = %d, max = %d\n"),
pi.pmc.WorkingSetSize, pi.minWorkSet, pi.maxWorkSet );
info += d;
//////////////////////////////////////////////////////////////////////////
/*
ftCreation = pi.spi.CreateTime;
ftKernel = pi.spi.KernelTime.QuadPart * 10;
ftUser = pi.spi.UserTime.QuadPart * 10;
if( ftCreation != 0 )
{
t = (FILETIME)ftCreation;
d.Format( _T("Process create time:\t%s\n"), t.Format( _T("%#c") ) );
info += d;
d.Format( _T("Process age:\t\t\t%s\n"), GetPeriod(time2 - ftCreation) );
info += d;
}
d.Format( _T("Process kernel time:\t%s\n"), GetPeriod(ftKernel) );
info += d;
d.Format( _T("Process user time:\t\t%s\n"), GetPeriod(ftUser) );
info += d;
d.Format( _T("Process kernel + user time:\t%s\n"), GetPeriod(ftKernel + ftUser) );
info += d;
//*/
//////////////////////////////////////////////////////////////////////////
ftCreation = pi.ftCreation;
ftKernel = pi.ftKernel;
ftKernel = ftKernel * 10;
ftUser = pi.ftUser;
ftUser = ftUser * 10;
if( ftCreation != 0 )
{
t = (FILETIME)ftCreation;
d.Format( _T("Process create time:\t%s\n"), t.Format( _T("%#c") ) );
info += d;
d.Format( _T("Process age:\t\t\t%s\n"), GetPeriod(time2 - ftCreation) );
info += d;
}
d.Format( _T("Process kernel time:\t%s\n"), GetPeriod(ftKernel) );
info += d;
d.Format( _T("Process user time:\t\t%s\n"), GetPeriod(ftUser) );
info += d;
d.Format( _T("Process kernel + user time:\t%s\n"), GetPeriod(ftKernel + ftUser) );
info += d;
//////////////////////////////////////////////////////////////////////////
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
void CInformationDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
if( cxIcon == 16 && cyIcon == 16 )
{
dc.DrawIcon( x, y, theApp.hMainIconSmall );
}
else
{
dc.DrawIcon( x, y, theApp.hMainIconSmall );
}
}
else
{
CDialog::OnPaint();
}
}
/////////////////////////////////////////////////////////////////////////////