www.pudn.com > Process_Mo18292312142004.rar > Window.cpp
/*******************************************************
This file is part of Process Monitor.
Copyright (c) 2004 by Michel van Kerkhof, ( michel000@planet.nl http://home.wxs.nl/~wijk0550/ )
For more information consult the Readme file.
This program is free software; you can redistribute it
and/or modify it under the terms of the GNU
General Public License as published by the Free
Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU
General Public License along with this program;
if not, write to:
the Free Software Foundation, Inc.,
59 Temple Place,
Suite 330, Boston,
MA 02111-1307 USA
*******************************************************
If you like my work and you have a job for me please contact me at: michel000@planet.nl
*******************************************************/
#include "includes.h"
const char szWindowClass[] = "Process Monitor";
const char szWindowTitle[] = "Process Monitor 1.0 ";
extern char szOSVersion[200];
CWindow::CWindow()
{
SaveSubListViewOption=EXTRA_INFO;
pClipBoard=NULL;
bUpdate=true;
hTrayPopup=NULL;
hExtra=NULL;
CExtra=NULL;
CModule=NULL;
CHandle=NULL;
CProc = NULL;
m_iDataOption=MES_NORMAL;
}
/*
Function Description:
Sets Hide when minimized option if set it creates a trayicon and hides the window whem minimized
Arguments:
IN bSet, if true changes the state,
if false it only sets the popup item state
Returns:
void
*/
void CWindow::HideWhenMinimized(bool bSet)
{
if (bSet) {
//change state
if (Settings.bHideWhenMinimized) Settings.bHideWhenMinimized=false;
else Settings.bHideWhenMinimized=true;
}
HMENU hMenu=GetSubMenu(GetMenu(hMain), 1);
if (Settings.bHideWhenMinimized) SetItemState(hMenu,IDM_HIDE_MINIMIZED,true);
else SetItemState(hMenu,IDM_HIDE_MINIMIZED,false);
}
/*
Function Description:
Set menu item taskmgr checked or unchecked
if bSet is true change registry key to run when user presses ctrl+alt+del
Arguments:
IN bSet, if true Set to run as taskmgr
Returns:
void
*/
void CWindow::SetTaskMgr(bool bSet)
{
HKEY hKey=NULL;
long lRet;
DWORD dwType,dwSize,dwDisposition;
char szFileName[MAX_PATH];
char szThisFile[MAX_PATH];
int iLen;
HMENU hMenu=GetSubMenu(GetMenu(hMain), 1);
iLen=GetModuleFileName(NULL,szThisFile,sizeof(szThisFile));
try {
lRet=RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\taskmgr.exe",
0,
NULL,
REG_OPTION_NON_VOLATILE ,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition
);
if (lRet != ERROR_SUCCESS) throw(false);
dwSize=sizeof(szFileName);
lRet=RegQueryValueEx(hKey,"Debugger",NULL,&dwType,(LPBYTE)szFileName,&dwSize);
if (lRet == ERROR_SUCCESS) {
if (strcmp(szFileName,szThisFile) == 0) {
if (GetItemState(hMenu,IDM_TASKMAN) && bSet) {
RegDeleteValue(hKey,"Debugger");
throw(false);
}
else {
throw(true);
}
}
}
if (!bSet) {
throw(false);
}
if (iLen > 23 && strncmp(szOSVersion,"Win NT",6) == 0) {
ShowError(NULL,"Full Filename of ProcessMonitor is to long to replace taskmgr.\nOn Win NT the maximum Filename is 23 characters.\nPlease put Process Monitor in a other directory.");
}
lRet=RegSetValueEx(hKey,"Debugger",NULL,REG_SZ,(LPBYTE)szThisFile,strlen(szThisFile));
if (lRet == ERROR_SUCCESS) {
throw(true);
}
throw(false);
}
catch(bool bError)
{
if (hKey) RegCloseKey(hKey);
SetItemState(hMenu,IDM_TASKMAN,bError);
}
}
/*
Function Description:
Change sub view window (info, module , handle)
Arguments:
IN dwSubWindow, id of the window to show
Returns:
void
*/
void CWindow::ChangeSubWindow(DWORD dwSubWindow)
{
HMENU hMenu=GetSubMenu(GetMenu(hMain), 2);
int iMenu=0;
if (dwSubWindow == NO_INFO) {
if (Settings.SubListViewOption != NO_INFO) {
SetItemState(hMenu, IDM_SHOW_EXTRA_INFO,false);
SaveSubListViewOption=Settings.SubListViewOption;
Settings.SubListViewOption=NO_INFO;
}
else {
Settings.SubListViewOption=SaveSubListViewOption;
SetItemState(hMenu, IDM_SHOW_EXTRA_INFO,true);
}
}
else
Settings.SubListViewOption=dwSubWindow;
if (CExtra) {
delete CExtra;
CExtra = NULL;
iMenu=IDM_EXTRA_INFO;
}
if (CModule) {
delete CModule;
CModule = NULL;
iMenu=IDM_DLL_INFO;
}
if (CHandle) {
delete CHandle;
CHandle = NULL;
iMenu=IDM_HANDLES_INFO;
}
if (iMenu) SetItemState(hMenu,iMenu,false);
if (hExtra) DestroyWindow(hExtra);
hExtra=NULL;
switch (Settings.SubListViewOption)
{
case EXTRA_INFO:
CExtra = new CProcInfo(this);
hExtra=CExtra->SubTree(hMain,hInst);
iMenu=IDM_EXTRA_INFO;
break;
case MODULE_INFO:
CModule = new CModuleInfo(this);
hExtra=CModule->ModuleListView(hMain,hInst);
iMenu=IDM_DLL_INFO;
break;
case HANDLE_INFO:
CHandle = new CHandleInfo(this);
hExtra=CHandle->HandleListView(hMain,hInst);
iMenu=IDM_HANDLES_INFO;
break;
default:
iMenu=0;
break;
}
if (iMenu) {
SetItemState(hMenu,iMenu,true);
SetItemState(hMenu,IDM_SHOW_EXTRA_INFO,true);
}
SetSize();
NMHDR nmt;
nmt.hwndFrom=hProcList;
nmt.idFrom=0;
nmt.code=NM_CLICK;
Notify(hMain,NULL,(LPARAM)&nmt);
}
/*
Function Description:
Starts or stops the splitter
Arguments:
IN bStart, if true Start else stop
Returns:
void
*/
void CWindow::SplitterStart(bool bStart)
{
bSplitter=bStart;
if (bStart) SetCapture(hMain);
else ReleaseCapture();
}
/*
Function Description:
Changes size of the listviews when splitter is active
called after a WM_MOUSEMOVE message
Arguments:
Returns:
void
*/
void CWindow::SplitterSetSize()
{
if (bSplitter) {
POINT Point;
RECT Rect;
GetCursorPos(&Point);
ScreenToClient(hMain,&Point);
GetClientRect(hMain,&Rect);
double dTemp;
dTemp=(double)Point.y / (Rect.bottom-Rect.top);
if (dTemp > 0.1 && dTemp < 0.9) {
Settings.dSplitter=dTemp;
SetSize();
}
}
}
/*
Function Description:
Creates the main window, status window,trayicon
Arguments:
IN hInstance, handle to application instance
Returns:
Handle to main window
*/
HWND CWindow::CreateMainWindow(HINSTANCE hInstance)
{
hInst=hInstance;
LoadSettings();
RECT dr;
SystemParametersInfo(SPI_GETWORKAREA,0,&dr,0);
bool bMaximize=false;
/*
if size of the window is the same or bigger than maximized size
set the default size and set window to maximized
*/
if (Settings.WinRect.left <= 0 &&
Settings.WinRect.top <= 0 &&
Settings.WinRect.right >= dr.right &&
Settings.WinRect.bottom >= dr.bottom)
{
Settings.WinRect.left=(dr.right-dr.left-DEFAULT_WINSIZE_X) / 2;
Settings.WinRect.top=(dr.bottom-dr.top-DEFAULT_WINSIZE_Y) / 2;
Settings.WinRect.right=DEFAULT_WINSIZE_X;
Settings.WinRect.bottom=DEFAULT_WINSIZE_Y;
bMaximize=true;
}
WNDCLASSEX mainWnd;
mainWnd.cbClsExtra=0;
mainWnd.cbSize=sizeof(WNDCLASSEX);
mainWnd.cbWndExtra=0;
mainWnd.hbrBackground=GetSysColorBrush(COLOR_BTNFACE);
mainWnd.hCursor=LoadCursor(NULL,IDC_SIZENS);
mainWnd.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(ID_ICON_MAIN));
mainWnd.hIconSm=mainWnd.hIcon;
mainWnd.hInstance=hInstance;
mainWnd.lpfnWndProc=mainWndProc;
mainWnd.lpszMenuName=szWindowTitle;
mainWnd.lpszClassName=szWindowClass;
mainWnd.lpszMenuName=MAKEINTRESOURCE(IDM_MAIN);
mainWnd.style=CS_DBLCLKS | CS_OWNDC;
if(!RegisterClassEx(&mainWnd))
{
return NULL;
}
if ((hMain=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
szWindowClass,
szWindowClass,
WS_VISIBLE | WS_OVERLAPPEDWINDOW,
Settings.WinRect.left,
Settings.WinRect.top,
Settings.WinRect.right-Settings.WinRect.left,
Settings.WinRect.bottom-Settings.WinRect.top,
NULL,
(HMENU)NULL,
hInst, NULL)) == NULL)
{
return NULL;
}
//Create Status Window
hStatus=CreateWindowEx(0,
"msctls_statusbar32",
0,
WS_CHILD | WS_BORDER | WS_VISIBLE | SBS_SIZEGRIP,
0, 0, 0, 0,
hMain,
0,
hInst,
0
);
int iStatus[5];
iStatus[0]=75;
iStatus[1]=170;
iStatus[2]=320;
iStatus[3]=420;
iStatus[4]=-1;
SendMessage(hStatus,SB_SETPARTS,5,(WPARAM)&iStatus);
SendMessage(hStatus,SB_SETTEXT,(LPARAM)4 | 0,(WPARAM)szOSVersion);
SetSize();
//create trayicon
NOTIFYICONDATA trayIcon;
trayIcon.cbSize=sizeof(NOTIFYICONDATA);
trayIcon.hWnd=hMain;
trayIcon.uID=IDI_TRAY;
trayIcon.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;
trayIcon.uCallbackMessage=WM_SHELLICON_NOTIFY;
trayIcon.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(ID_ICON_MAIN));
strcpy(trayIcon.szTip,szWindowClass);
if (Shell_NotifyIcon(NIM_ADD,&trayIcon) == 0) {
ShowError(hMain,"Error creating trayicon");
}
SetTaskMgr(false);
HideWhenMinimized(false);
if (bMaximize) ShowWindow(hMain,SW_MAXIMIZE);
//create string for titlebar
int i=strlen(szWindowTitle);
strcpy(szTitleBar,szWindowTitle);
szTitleBar[i++]=' ';
pTitleBar=szTitleBar+i;//save a pointer to the end of the string where we can copy or time string to
//Set Timer to updata titlebar
Timers(hMain,ID_TITLEBAR_TIMER,0);
SetTimer(hMain,ID_TITLEBAR_TIMER,60000,NULL);
#ifdef CHECK_LAG
m_dwOldTickCount=GetTickCount();
SetTimer(hMain,ID_CHECK_LAG,LAG_CHECK_TIME,NULL);
#endif
return hMain;
}
/*
Function Description:
Resizes the Listview and treeview windows
called after a WM_SIZE message or when the splitter is active
Arguments:
Returns:
void
*/
void CWindow::SetSize()
{
RECT rcStatus,rc;
GetClientRect(hStatus,&rcStatus);
GetClientRect(hMain,&rc);
int i=rc.bottom-rcStatus.bottom;
if (Settings.SubListViewOption == 0) {
SetWindowPos(hProcList, NULL, 0, 0,rc.right,i, SWP_NOZORDER);
}
else {
SetWindowPos(
hProcList,
NULL,
0,
0,
rc.right,
(int)(Settings.dSplitter * (double)i),
SWP_NOZORDER
);
SetWindowPos(
hExtra,
NULL,
0,
(int)(Settings.dSplitter * (double)i)+3,
rc.right,
(int)((1 - Settings.dSplitter) * (double)i)-3,
SWP_NOZORDER
);
}
if (!bSplitter) MoveWindow(hStatus, 0, 0, 0, 0,true);
}
/*
Function Description:
Creates process listview
called after a WM_CREATE message
Arguments:
IN hWnd, Handle to owner window
Returns:
Handle to Proclistview window
*/
HWND CWindow::ProcessListView(HWND hWnd)
{
hMain=hWnd;
DWORD dwRet;
CProc = new CProcList(&dwRet,hWnd);
if (dwRet != 1) {
ShowError(hWnd,"Could not Load needed API's");
SendMessage(hWnd,WM_CLOSE,0,0);
return NULL;
}
hProcList=CreateWindowEx(
WS_EX_CLIENTEDGE,
"SysListView32",
NULL,
WS_CHILD | WS_VISIBLE | LVS_SINGLESEL | LVS_REPORT | LVS_SHOWSELALWAYS ,
0, 0,0,0,
hWnd,
0,
hInst,
NULL
);
if (!hProcList) {
return NULL;
}
//if you like colours....
//ListView_SetBkColor(hProcList,RGB(0,0,0));
//ListView_SetTextBkColor(hProcList,RGB(0,0,0));
//ListView_SetTextColor(hProcList,RGB(0,150,0));
SendMessage(
hProcList,
LVM_SETEXTENDEDLISTVIEWSTYLE,
0,
LVS_EX_FULLROWSELECT
// LVS_EX_ONECLICKACTIVATE
// LVS_EX_UNDERLINEHOT
#ifdef SHOW_GRIDLINES
| LVS_EX_GRIDLINES
#endif
);
LVCOLUMN lvc;
lvc.mask = LVCF_TEXT | LVCF_WIDTH;
lvc.pszText="Start Time";
lvc.cx=90;
SendMessage(hProcList, LVM_INSERTCOLUMN, 0,(long)&lvc);
lvc.pszText="Company Name";
lvc.cx=120;
SendMessage(hProcList, LVM_INSERTCOLUMN, 0,(long)&lvc);
lvc.pszText="Description";
lvc.cx=210;
SendMessage(hProcList, LVM_INSERTCOLUMN, 0,(long)&lvc);
lvc.pszText="Ram";
lvc.cx=55;
SendMessage(hProcList, LVM_INSERTCOLUMN, 0,(long)&lvc);
lvc.pszText="ProcessID";
lvc.cx=60;
SendMessage(hProcList, LVM_INSERTCOLUMN, 0,(long)&lvc);
lvc.pszText="CPU";
lvc.cx=40;
SendMessage(hProcList, LVM_INSERTCOLUMN, 0,(long)&lvc);
lvc.pszText="Owner";
lvc.cx=90;
SendMessage(hProcList, LVM_INSERTCOLUMN, 0,(long)&lvc);
lvc.pszText="Process";
lvc.cx=105;
SendMessage(hProcList, LVM_INSERTCOLUMN, 0,(long)&lvc);
lvc.mask = LVCF_FMT;
lvc.fmt=LVCFMT_RIGHT;
SendMessage(hProcList,LVM_SETCOLUMN,7,(long)&lvc);
SendMessage(hProcList,LVM_SETCOLUMN,4,(long)&lvc);
SendMessage(hProcList,LVM_SETCOLUMN,3,(long)&lvc);
SendMessage(hProcList,LVM_SETCOLUMN,2,(long)&lvc);
//load popups
m_hListViewPopup = LoadMenu(GetModuleHandle(NULL),MAKEINTRESOURCE(IDM_LISTVIEW_POPUP));
ChangeSubWindow(Settings.SubListViewOption);
CProc->UpdateProcList(this);
SetSpeed(0);
return hProcList;
}
/*
Function Description:
stub for SendMessage
calls SendMessage or compares strings if used with find dll
or writes data to logfile when used with save process details to file
called by ModuleList, HandleList and ProcInfo
Arguments:
IN hWnd, // handle of destination window
IN Msg, // message to send
IN wParam, // first message parameter
IN lParam // second message parameter
Returns:
return value of SendMessage
*/
LRESULT CWindow::mySendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
LRESULT Ret=1;
if (m_iDataOption == MES_NORMAL) Ret = SendMessage(hWnd,Msg,wParam,lParam);
else if (m_iDataOption == MES_LOG_TO_FILE) {
DWORD dwWritten;
if (Msg == LVM_SETITEM || Msg == LVM_INSERTITEM) {
LVITEMA *lvi=(LVITEMA *)lParam;
if (lvi->mask & LVIF_TEXT) {
if (lvi->iSubItem == 0) {
WriteFile(hLogFile,"\r\n",2,&dwWritten,NULL);
}
WriteFile(hLogFile,lvi->pszText,strlen(lvi->pszText),&dwWritten,NULL);
WriteFile(hLogFile," : ",3,&dwWritten,NULL);
}
}
else if (Msg == TVM_INSERTITEM) {
TVINSERTSTRUCTA *tv;
tv=(TVINSERTSTRUCTA *)lParam;
if (tv->item.mask & TVIF_TEXT) {
WriteFile(hLogFile,tv->item.pszText,strlen(tv->item.pszText),&dwWritten,NULL);
WriteFile(hLogFile,"\r\n",2,&dwWritten,NULL);
}
}
}
else if (m_iDataOption == MES_FIND_DLL) {
LVITEMA lvi;
memcpy((void *)&lvi,(void *)lParam,sizeof(lvi));
if (lvi.iSubItem == 0) {
CharLowerBuff(lvi.pszText,strlen(lvi.pszText));
if (lvi.mask & LVIF_TEXT && lvi.mask & LVIF_PARAM && strstr(lvi.pszText,szSearchString)) {
PROCESSLIST ProcessList;
if (CProc->GetProcessInfo(&ProcessList,lvi.lParam) == ERR_SUCCESS) {
iSearchOption=1;
LVITEMA xlvi;
xlvi.mask=LVIF_TEXT;
xlvi.pszText=ProcessList.pProcessName;
xlvi.iSubItem=0;
xlvi.iItem=0;
SendMessage(hWnd,LVM_INSERTITEM,wParam,(LPARAM)&xlvi);
char szBuf[20];
inttochar(szBuf,ProcessList.dwPID,sizeof(szBuf));
xlvi.iSubItem=1;
xlvi.pszText=szBuf;
SendMessage(hWnd,LVM_SETITEM,wParam,(LPARAM)&xlvi);
lvi.iSubItem=2;
lvi.iItem=0;
lvi.mask = LVIF_TEXT;
Ret=SendMessage(hWnd,LVM_SETITEM,wParam,(LPARAM)&lvi);
}
}
else iSearchOption=0;
}
else if (iSearchOption != 0) {
lvi.iItem=0;
lvi.iSubItem+=2;
Ret = SendMessage(hWnd,Msg,wParam,(LPARAM)&lvi);
}
}
return Ret;
}
/*
Function Description:
Starts Save Processdetails to disk
Ask's for filename
and cals LogItem
called by WM_COMMAND from popup
Arguments:
IN iItem, item number in the processlist to log or -1 to log all processes
Returns:
void
*/
void CWindow::StartLog(int iItem)
{
char szLogFile[MAX_PATH];
OPENFILENAME ofn;
memset(&ofn,0, sizeof(ofn));
*szLogFile=0;
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hMain;
ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = szLogFile;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER;
ofn.lpstrDefExt = "txt";
//ask for a filename
if(!GetSaveFileName(&ofn))
{
return;
}
hLogFile=CreateFile(szLogFile,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (!hLogFile) {
ShowError(NULL,"Could not create file");
return;
}
//set this flag to tell mySendMessage to log everything
m_iDataOption=MES_LOG_TO_FILE;
if (iItem == -1) {
//log all processes
//get number of lines
int i,iNumberItems;
iNumberItems=SendMessage(hProcList,LVM_GETITEMCOUNT,0,0);
for(i=0;iSetInfo(iItem);
delete CExtraTemp;
}
CModuleTemp = new CModuleInfo(this);
if (CModuleTemp) {
CModuleTemp->SetInfo(iItem);
delete CModuleTemp;
}
CHandleTemp = new CHandleInfo(this);
if (CHandleTemp) {
CHandleTemp->SetInfo(iItem);
delete CHandleTemp;
}
}