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; 
	} 
}