cheat-engine/Cheat Engine/ProcessWindowUnit.pas
2020-02-09 20:32:40 +01:00

946 lines
24 KiB
ObjectPascal
Executable File

unit ProcessWindowUnit;
{$MODE Delphi}
interface
uses
{$ifdef darwin}
macport,
{$endif}
{$ifdef windows}
jwawindows, windows,
{$endif}
LCLIntf, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ExtCtrls, CEFuncProc,CEDebugger, ComCtrls, ImgList,
Filehandler, Menus, LResources,{tlhelp32,}{$ifdef windows}vmxfunctions,{$endif} NewKernelHandler,
debugHelper{, KIcon}, commonTypeDefs, math;
type tprocesslistlong = class(tthread)
private
processcount: integer;
process: array[0..9] of string;
procedure drawprocesses;
public
processlist: tlistbox;
procedure execute; override;
end;
type
{ TProcessWindow }
TProcessWindow = class(TForm)
btnNetwork: TButton;
btnAttachDebugger: TButton;
CancelButton: TButton;
FontDialog1: TFontDialog;
plImageList: TImageList;
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
MenuItem2: TMenuItem;
MenuItem3: TMenuItem;
miConvertPIDToDecimal: TMenuItem;
miRefresh: TMenuItem;
miCreateProcess: TMenuItem;
miOpenFile: TMenuItem;
N2: TMenuItem;
miChangeFont: TMenuItem;
miSkipSystemProcesses: TMenuItem;
MenuItem4: TMenuItem;
MenuItem5: TMenuItem;
N1: TMenuItem;
miProcessListLong: TMenuItem;
miOwnProcessesOnly: TMenuItem;
OKButton: TButton;
Panel1: TPanel;
OpenDialog1: TOpenDialog;
OpenDialog2: TOpenDialog;
Panel3: TPanel;
Panel5: TPanel;
PopupMenu1: TPopupMenu;
InputPIDmanually1: TMenuItem;
Filter1: TMenuItem;
ProcessList: TListBox;
miShowInvisibleItems: TMenuItem;
TabHeader: TTabControl;
Timer1: TTimer;
procedure btnNetworkClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure CancelButtonClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure MenuItem5Click(Sender: TObject);
procedure miProcessListLongClick(Sender: TObject);
procedure miChangeFontClick(Sender: TObject);
procedure miOwnProcessesOnlyClick(Sender: TObject);
procedure miRefreshClick(Sender: TObject);
procedure OKButtonClick(Sender: TObject);
procedure btnProcesslistClick(Sender: TObject);
procedure btnWindowListClick(Sender: TObject);
procedure btnCreateThreadClick(Sender: TObject);
procedure btnAttachDebuggerClick(Sender: TObject);
procedure btnOpenFileClick(Sender: TObject);
procedure InputPIDmanually1Click(Sender: TObject);
procedure Filter1Click(Sender: TObject);
procedure btnProcessWatchClick(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure btnProcessListLongClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure PopupMenu1Popup(Sender: TObject);
procedure ProcessListDrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
procedure FormShow(Sender: TObject);
procedure ProcessListKeyPress(Sender: TObject; var Key: char);
procedure miShowInvisibleItemsClick(Sender: TObject);
procedure TabHeaderChange(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
currentchar: integer;
wantedheight: integer;
ffilter: string;
processlistlong: tprocesslistlong;
procedure refreshlist;
procedure setbuttons;
procedure SetFilter(filter:string);
property filter:string read ffilter write setfilter;
procedure filterlist;
public
{ Public declarations }
procedure PWOP(ProcessIDString:string);
published
property TabControl1: TTabControl read TabHeader;
end;
var
ProcessWindow: TProcessWindow;
commonProcessesList: tstringlist;
implementation
uses MainUnit, formsettingsunit, advancedoptionsunit,frmProcessWatcherUnit,
memorybrowserformunit{$ifdef windows}, networkConfig{$endif}, ProcessHandlerUnit, processlist, globals,
registry, fontSaveLoadRegistry, frmOpenFileAsProcessDialogUnit;
resourcestring
rsIsnTAValidProcessID = '%s isn''t a valid processID';
rsPhysicalMemory = 'Physical Memory';
rsYouCanOnlyLoadEXEFiles = 'You can only load EXE files';
rsCreateProcess = 'Create Process';
rsOptionalLaunchParameters = 'Optional launch parameters';
rsAttachdebuggerornot = 'Are you sure you want to attach the debugger and not just open this process? (You can later on always attach the debugger)';
rsPleaseSelectAnotherProcess = 'Please select another process';
rsFirstSelectAProcess = 'First select a process!';
rsManualPID = 'Manual PID';
rsEnterTheProcessID = 'Enter the ProcessID';
rsFilter = 'Filter';
rsWhatAreYouLookingFor = 'What are you looking for?';
rsScanningClickToStop = 'Scanning (Click to stop)';
rsProcessListLong = 'Process List(long)';
rsProcessList = 'Process List';
rsApplications='Applications';
rsProcesses='Processes';
rsWindows='Windows';
var errortrace: integer;
procedure TProcessListLong.drawprocesses;
var i: integer;
begin
if not terminated then
begin
processlist.Items.BeginUpdate;
for i:=0 to processcount-1 do
processlist.Items.Add(process[i]);
processlist.Items.EndUpdate;
processcount:=0;
end;
end;
procedure TProcessListLong.execute;
var i: dword;
h: thandle;
x: pchar;
modulename:string;
begin
{$ifdef windows}
i:=0;
while not terminated and (i<$FFFFFFFF) do
begin
h:=windows.OpenProcess(ifthen(GetSystemType<=6,$1f0fff, process_all_access),false,i);
if h<>0 then
begin
modulename:=getProcessnameFromProcessID(i);
process[processcount]:=inttohex(i,8)+'-'+modulename;
inc(processcount);
if processcount>=10 then
synchronize(drawprocesses);
closehandle(h);
end;
if ((i mod 4096)=0) then
if processcount>0 then synchronize(drawprocesses);
inc(i);
end;
if processcount>0 then synchronize(drawprocesses);
{$endif}
end;
procedure loadCommonProcessesList;
var
s: string;
i,j: integer;
begin
s:=cheatenginedir+'commonProcessesList.txt';
if FileExists(s) then //if the list exists
begin
if commonProcessesList=nil then commonProcessesList:=tstringlist.create;
try
commonProcessesList.LoadFromFile(s{$if FPC_FULLVERSION >= 030200}, true{$endif});
for i:=commonProcessesList.Count-1 downto 0 do
begin
j:=pos('#', commonProcessesList[i]);
if j>0 then commonProcessesList[i]:=copy(commonProcessesList[i], 1, j-1);
commonProcessesList[i]:=uppercase(trim(commonProcessesList[i]));
if commonProcessesList[i]='' then commonProcessesList.Delete(i);
end;
except
end;
end;
end;
function isInCommonProcessesList(processname: string): boolean;
var
i:integer;
begin
if commonProcessesList=nil then exit(false);
for i:=0 to commonProcessesList.Count-1 do
if commonProcessesList[i]=uppercase(copy(processname,10)) then exit(true);
result:=false;
end;
procedure TProcessWindow.filterlist;
var
i:integer;
pli: PProcessListInfo;
s: string;
begin
if (filter='') and (miSkipSystemProcesses.checked=false) and (commonProcessesList=nil) then exit;
ffilter:=uppercase(ffilter);
i:=0;
while i<processlist.Items.Count do
begin
pli:=PProcessListInfo(processlist.items.Objects[i]);
if ((ffilter<>'') and (pos(ffilter,uppercase(processlist.Items[i]))=0)) or ((pli<>nil) and miSkipSystemProcesses.checked and pli^.issystemprocess) or
isInCommonProcessesList(processlist.Items[i]) then
begin
if pli<>nil then
begin
if pli^.processIcon>0 then
begin
if pli^.processID<>GetCurrentProcessId then
DestroyIcon(pli^.processIcon);
pli^.processIcon:=0;
end;
freememandnil(pli);
end;
processlist.Items.Delete(i);
end
else
inc(i);
end;
end;
procedure TProcesswindow.SetFilter(filter:string);
begin
ffilter:=filter;
refreshlist;
end;
procedure TProcessWindow.CancelButtonClick(Sender: TObject);
begin
mainform.canceled:=true;
//ProcessWindow.close;
ModalResult:=mrCancel;
end;
procedure TProcessWindow.FormCreate(Sender: TObject);
var
x: array of integer;
reg: tregistry;
begin
{$ifdef darwin}
//tabheader is bugged
ProcessList.Parent:=self;
ProcessList.AnchorSideTop:=TabHeader.AnchorSideTop;
ProcessList.AnchorSideLeft:=TabHeader.AnchorSideLeft;
ProcessList.AnchorSideRight:=TabHeader.AnchorSideRight;
ProcessList.AnchorSideBottom:=TabHeader.AnchorSideBottom;
ProcessList.Anchors:=TabHeader.Anchors;
TabHeader.TabIndex:=1;
TabHeader.Visible:=false;
{$endif}
{$ifdef windows}
TabHeader.Tabs[0]:=rsApplications;
TabHeader.Tabs[1]:=rsProcesses;
TabHeader.Tabs[2]:=rsWindows;
setlength(x,0);
if LoadFormPosition(self,x) then
begin
autosize:=false;
if length(x)>0 then
TabHeader.TabIndex:=x[0];
if length(x)>1 then
begin
miOwnProcessesOnly.checked:=x[1]<>0;
ProcessesCurrentUserOnly:=x[1]<>0;
end;
if length(x)>2 then
miSkipSystemProcesses.checked:=x[2]<>0;
end
else
refreshlist;
reg:=tregistry.create;
try
if reg.OpenKey('\Software\Cheat Engine\Process Window\Font',false) then
LoadFontFromRegistry(processlist.Font, reg);
finally
reg.free;
end;
{$endif}
end;
procedure TProcessWindow.FormDestroy(Sender: TObject);
var x: array of integer;
begin
setlength(x,3);
x[0]:=TabHeader.TabIndex;
x[1]:=ifthen(miOwnProcessesOnly.checked,1,0);
x[2]:=ifthen(miSkipSystemProcesses.checked,1,0);
SaveFormPosition(self,x);
end;
procedure TProcessWindow.MenuItem5Click(Sender: TObject);
begin
end;
procedure TProcessWindow.miProcessListLongClick(Sender: TObject);
begin
btnProcessListLongClick(nil);
end;
procedure TProcessWindow.miChangeFontClick(Sender: TObject);
var reg: tregistry;
begin
fontdialog1.font.assign(processlist.font);
if fontdialog1.execute then
begin
//apply settings
processlist.font.assign(FontDialog1.Font);
//processlist.Canvas.Refresh;
Timer1Timer(timer1);
processlist.Repaint;
reg:=tregistry.create;
try
if reg.OpenKey('\Software\Cheat Engine\Process Window\Font',true) then
SaveFontToRegistry(FontDialog1.Font, reg);
finally
reg.free;
end;
end;
end;
procedure TProcessWindow.miOwnProcessesOnlyClick(Sender: TObject);
begin
ProcessesCurrentUserOnly:=miOwnProcessesOnly.checked;
refreshlist;
end;
procedure TProcessWindow.miRefreshClick(Sender: TObject);
begin
refreshList;
end;
procedure TProcessWindow.btnNetworkClick(Sender: TObject);
begin
{$ifdef windows}
if frmNetworkConfig=nil then
frmNetworkConfig:=tfrmNetworkConfig.create(self);
if frmNetworkConfig.ShowModal=mrok then
begin
if TabHeader.TabIndex=1 then
refreshlist
else
TabHeader.Tabindex:=1;
end;
{$endif}
end;
procedure TProcessWindow.Button1Click(Sender: TObject);
begin
end;
procedure TProcessWindow.setbuttons;
begin
end;
procedure TProcessWindow.PWOP(ProcessIDString:string);
var i:integer;
begin
val('$'+ProcessIDString,ProcessHandler.processid,i);
if i<>0 then raise exception.Create(Format(rsIsnTAValidProcessID, [processidstring]));
if Processhandle<>0 then
begin
if (processhandle<>0) and (processhandle<>INVALID_HANDLE_VALUE) and (processhandle<>$FFFFFFFF) then
CloseHandle(ProcessHandle);
ProcessHandler.ProcessHandle:=0;
end;
with mainform do
begin
if GetSystemType>=4 then
begin
cbSpeedhack.checked:=false;
cbSpeedhack.Enabled:=true;
cbunrandomizer.Checked:=false;
cbunrandomizer.Enabled:=true;
end;
end;
{$ifdef windows}
if (processid<>0) and (UseFileAsMemory or Usephysical or usephysicaldbvm) then
begin
//swap back to processmemory
UseFileAsMemory:=false;
Usephysical:=false;
usephysicaldbvm:=false;
if formsettings.cbKernelOpenProcess.checked then
UseDBKOpenProcess
else
DONTUseDBKOpenProcess;
if formsettings.cbKernelQueryMemoryRegion.checked then
UseDBKQueryMemoryRegion
else
DONTUseDBKQueryMemoryRegion;
if formsettings.cbKernelReadWriteProcessMemory.checked then
UseDBKReadWriteMemory
else
DONTUseDBKReadWriteMemory;
end;
{$endif}
Open_Process;
ProcessSelected:=true;
{$ifdef windows}
if (processid=0) and ((formsettings.cbKernelReadWriteProcessMemory.checked) or (dbvm_version>=$ce000004)) then
begin
ProcessHandler.processid:=$FFFFFFFF;
if dbvm_version>=$ce000004 then
DBKPhysicalMemoryDBVM
else
DBKPhysicalMemory;
ProcessHandler.ProcessHandle:=$FFFFFFFF;
end
else
begin
if usephysical or usephysicaldbvm then
DBKProcessMemory;
end;
{$endif}
end;
procedure TProcessWindow.OKButtonClick(Sender: TObject);
var ProcessIDString: String;
begin
//Outputdebugstring('OK button click');
if Processlist.ItemIndex>-1 then
begin
unpause;
DetachIfPossible;
ProcessIDString:=copy(ProcessList.Items[Processlist.ItemIndex], 1, pos('-',ProcessList.Items[Processlist.ItemIndex])-1);
PWOP(ProcessIDString);
if TabHeader.TabIndex=0 then
MainForm.ProcessLabel.caption:=ProcessIDString+'-'+extractfilename(getProcessPathFromProcessID(processid))
else
MainForm.ProcessLabel.caption:=ProcessList.Items[Processlist.ItemIndex];
Modalresult:=MROK;
//ProcessWindow.close;
end;
//outputdebugstring('After ok click handler');
end;
//button1click specific:
procedure TProcessWindow.btnProcesslistClick(Sender: TObject);
begin
end;
procedure TProcessWindow.btnWindowListClick(Sender: TObject);
begin
//miSkipSystemProcesses.visible:=false;
end;
procedure TProcessWindow.btnCreateThreadClick(Sender: TObject);
var parameters: string;
begin
if Opendialog1.Execute then
begin
if Uppercase(extractfileext(opendialog1.FileName))<>'.EXE' then raise Exception.Create(rsYouCanOnlyLoadEXEFiles);
parameters:='';
if not InputQuery(rsCreateProcess, rsOptionalLaunchParameters, parameters) then exit;
unpause;
detachIfPossible;
Debuggerthread:=TDebuggerThread.MyCreate2(opendialog1.FileName, parameters);
if not Debuggerthread.running then exit;
mainForm.ProcessLabel.caption:=IntToHex(processid,8)+'-'+ExtractFileName(opendialog1.FileName);
mainform.debugproc:=true;
memorybrowser.show;
modalresult:=mrOk;
end;
end;
procedure TProcessWindow.btnAttachDebuggerClick(Sender: TObject);
var ProcessIDString: String;
i: Integer;
begin
if Processlist.ItemIndex>-1 then
begin
if MessageDlg(rsAttachdebuggerornot, mtConfirmation, [mbyes, mbno], 0)=mryes then
begin
unpause;
DetachIfPossible;
ProcessIDString:='';
i:=1;
while ProcessList.Items[Processlist.ItemIndex][i]<>'-' do
begin
ProcessIDString:=ProcessIDString+ProcessList.Items[Processlist.ItemIndex][i];
inc(i);
end;
val('$'+ProcessIDString,ProcessHandler.processid,i);
if Processhandle<>0 then
begin
CloseHandle(ProcessHandle);
ProcessHandler.ProcessHandle:=0;
end;
if processid=GetCurrentProcessId then raise exception.create(rsPleaseSelectAnotherProcess);
Debuggerthread:=TDebuggerThread.MyCreate2(processid);
mainform.ProcessLabel.Caption:=ProcessList.Items[Processlist.ItemIndex];
ProcessSelected:=true;
mainform.debugproc:=true;
modalresult:=mrOK;
end
end else showmessage(rsFirstSelectAProcess);
end;
procedure TProcessWindow.btnOpenFileClick(Sender: TObject);
begin
{$ifdef windows}
if opendialog2.execute then
begin
if frmOpenFileAsProcessDialog=nil then
frmOpenFileAsProcessDialog:=tfrmOpenFileAsProcessDialog.create(self);
if frmOpenFileAsProcessDialog.showmodal=mrok then
begin
DBKFileAsMemory(opendialog2.filename, frmOpenFileAsProcessDialog.startaddress);
processselected:=true;
ProcessHandler.ProcessHandle:=QWORD(-2);
MainForm.ProcessLabel.caption:=extractfilename(opendialog2.FileName);
MainForm.miSaveFile.visible:=true;
ProcessHandler.processid:=$FFFFFFFF;
Processhandler.is64Bit:=frmOpenFileAsProcessDialog.rb64.checked;
modalresult:=mrok;
end;
end;
{$endif}
end;
procedure TProcessWindow.InputPIDmanually1Click(Sender: TObject);
var pid: string;
begin
pid:='0';
if InputQuery(rsManualPID, rsEnterTheProcessID+':', pid) then
begin
unpause;
DetachIfPossible;
pwop(pid);
MainForm.ProcessLabel.caption:=pid;
modalresult:=mrok;
end;
end;
procedure TProcessWindow.Filter1Click(Sender: TObject);
var fltr: string;
begin
fltr:=filter;
if inputquery(rsFilter, rsWhatAreYouLookingFor, fltr) then
filter:=fltr;
end;
procedure TProcessWindow.btnProcessWatchClick(Sender: TObject);
begin
if frmprocesswatcher=nil then
frmprocesswatcher:=tfrmprocesswatcher.Create(mainform);
frmprocesswatcher.show;
modalresult:=mrcancel;
end;
procedure TProcessWindow.FormResize(Sender: TObject);
begin
//reset the button positions
// setbuttons;
end;
procedure TProcessWindow.btnProcessListLongClick(Sender: TObject);
begin
if processlistlong=nil then
begin
processlist.Clear;
miProcessListLong.Caption:=rsScanningClickToStop;
processlistlong:=tprocesslistlong.create(true);
processlistlong.processlist:=processlist;
processlistlong.start;
end
else
begin
miProcessListLong.Caption:=rsProcessListLong;
processlistlong.terminate;
processlistlong.WaitFor;
processlistlong.Free;
processlistlong:=nil;
end;
end;
procedure TProcessWindow.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
if processlistlong<>nil then
begin
processlistlong.terminate;
processlistlong.WaitFor;
processlistlong.Free;
processlistlong:=nil;
miProcessListLong.Caption:=rsProcessListLong;
end;
end;
procedure TProcessWindow.PopupMenu1Popup(Sender: TObject);
begin
miShowInvisibleItems.visible:=tabheader.TabIndex=2;
end;
procedure TProcessWindow.ProcessListDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
i: integer;
t: string;
sep: integer;
pids: string;
pid: dword;
begin
wantedheight:=ProcessList.canvas.TextHeight('QqJjWwSs')+3;
{i:=ProcessList.canvas.TextHeight('QqJjWwSs')+3;
if processlist.itemheight<i then ProcessList.ItemHeight:=i; }
processlist.Canvas.FillRect(rect);
{
i:=ProcessList.canvas.TextHeight('QqJjWwSs')+3;
if processlist.itemheight<i then ProcessList.ItemHeight:=i;}
t:=processlist.Items[index];
if miConvertPIDToDecimal.checked then
begin
sep:=pos('-',t);
if sep<>0 then
begin
try
pids:=copy(t,1,sep-1);
pid:=strtoint('$'+pids);
t:=format('%.8d',[pid])+copy(t,sep);
except
end;
end;
end;
processlist.Canvas.TextOut(rect.Left+rect.Bottom-rect.Top+3,rect.Top,t);
{$ifdef windows}
if (processlist.Items.Objects[index]<>nil) and (PProcessListInfo(processlist.Items.Objects[index])^.processIcon>0) then
DrawIconEx(processlist.Canvas.Handle, rect.left, rect.Top, PProcessListInfo(processlist.Items.Objects[index])^.processIcon, rect.Bottom-rect.Top,rect.Bottom-rect.Top,0,0,DI_NORMAL);
{$endif}
end;
procedure TProcessWindow.FormShow(Sender: TObject);
begin
OKButton.Constraints.MinHeight:=trunc(1.2*btnAttachDebugger.height);
CancelButton.Constraints.MinHeight:=OKButton.Constraints.MinHeight;
loadCommonProcessesList;
errortrace:=100;
try
errortrace:=101;
processlist.canvas.Refresh;
errortrace:=102;
ProcessList.ItemHeight:=max(processlist.canvas.TextHeight('QqJjWwSs')+3, canvas.TextHeight('QqJjWwSs')+3);
errortrace:=103;
currentchar:=1;
errortrace:=104;
refreshlist;
errortrace:=105;
if autosize then
begin
autosize:=false;
//first run or no saving positions
clientwidth:=max(clientwidth, canvas.TextWidth(' XXXXXXXX - XXXXXXXXXXXXXXXXXXXXXX '));
height:=mainform.Height-(mainform.height div 3);
position:=poDesigned;
position:=poMainFormCenter;
end;
errortrace:=106;
processlist.SetFocus;
except
on e:exception do
raise exception.create('FormShow exception ('+e.message+') at section '+inttostr(errortrace));
end;
end;
procedure TProcessWindow.ProcessListKeyPress(Sender: TObject; var Key: char);
begin
if key=#8 then
filter:=copy(filter, 1, length(filter)-1)
else
if key in [chr(32)..chr(128)] then
filter:=filter+key;
end;
procedure TProcessWindow.RefreshList;
var
i: integer;
oldselectionindex: integer;
oldselection: string;
found: boolean;
begin
processlist.Items.BeginUpdate;
try
oldselectionindex:=processlist.ItemIndex;
if oldselectionindex<>-1 then
oldselection:=processlist.Items[oldselectionIndex];
case TabHeader.TabIndex of
0:
begin
{$ifdef windows}
getwindowlist2(processlist.Items);
miSkipSystemProcesses.enabled:=true;
{$endif}
end;
1:
begin
getprocesslist(processlist.items);
miSkipSystemProcesses.enabled:=true;
end;
2:
begin
{$ifdef windows}
GetWindowList(processlist.Items, miShowInvisibleItems.Checked);
miSkipSystemProcesses.enabled:=false;
processlist.ItemIndex:=processlist.Items.Count-1;
{$endif}
end;
end;
filterlist;
if oldselectionindex=-1 then
begin
processlist.ItemIndex:=processlist.Items.Count-1; //go to the end
end
else
begin
i:=processlist.Items.IndexOf(oldselection);
if i>=0 then
begin
processlist.ItemIndex:=i;
end
else
begin
//strip out the processid part and search for a entry with the appropriate processname (e.g restarted game)
oldselection:=copy(oldselection,pos('-',oldselection)+1,length(oldselection));
found:=false;
for i:=0 to processlist.Items.Count-1 do
if pos(oldselection, processlist.items[i])>0 then
begin
processlist.ItemIndex:=i;
found:=true;
break;
end;
if not found then
processlist.ItemIndex:=processlist.Items.Count-1;
end;
end;
if filter<>'' then
caption:=rsProcessList+' : *'+filter+'*'
else
caption:=rsProcessList;
{$ifdef windows}
if formsettings.cbKernelReadWriteProcessMemory.checked or (dbvm_version>=$ce000004) then //driver is active
begin
processlist.Items.Insert(0, '00000000-['+rsPhysicalMemory+']');
end;
{$endif}
finally
processlist.items.EndUpdate;
end;
end;
procedure TProcessWindow.miShowInvisibleItemsClick(Sender: TObject);
begin
refreshList;
end;
procedure TProcessWindow.TabHeaderChange(Sender: TObject);
begin
refreshList;
end;
procedure TProcessWindow.Timer1Timer(Sender: TObject);
begin
try
if processlist.itemheight<>wantedheight then
begin
ProcessList.ItemHeight:=wantedheight;
processlist.canvas.Refresh;
processlist.Repaint;
end;
except
timer1.enabled:=false;
showmessage('timer issue');
end;
end;
initialization
{$i ProcessWindowUnit.lrs}
end.