2011-07-04 19:52:53 +00:00
unit ProcessWindowUnit;
{$MODE Delphi}
interface
uses
2019-12-18 12:07:17 +01:00
{$ifdef darwin}
macport,
{$endif}
{$ifdef windows}
jwawindows, windows,
{$endif}
LCLIntf, Messages, SysUtils, Classes, Graphics, Controls,
2017-04-16 19:55:21 +02:00
Forms, Dialogs, StdCtrls, ExtCtrls, CEFuncProc, CEDebugger, ComCtrls, ImgList,
2019-12-18 12:07:17 +01:00
Filehandler, Menus, LResources, {tlhelp32,} {$ifdef windows} vmxfunctions, {$endif} NewKernelHandler,
2021-09-30 22:35:38 +02:00
debugHelper{, KIcon} , commonTypeDefs, math, lcltype, syncobjs, Contnrs, betterControls;
2011-07-04 19:52:53 +00:00
2020-03-05 15:43:20 +01:00
type
TProcesslistlong = class( tthread)
private
processcount: integer ;
process: array [ 0 .. 9 ] of string ;
procedure drawprocesses;
public
processlist: tlistbox;
procedure execute; override ;
end ;
2020-03-24 11:32:08 +01:00
{$ifdef windows}
2020-03-05 15:43:20 +01:00
TIconFetchEntry= record
processid: dword;
winhandle: hwnd; //optional
index : integer ;
icon: HIcon; //gets filled in
end ;
PIconFetchEntry= ^ TIconFetchEntry;
TIconFetchThread = class( TThread)
private
hasData: TEvent;
requestsList: TList; //just the PID
requestsListCS: TCriticalSection;
resolvedList: TList; //PID and HICON record
resolvedListCS: TCriticalSection;
procedure getIcon( e: PIconFetchEntry) ;
public
function queueIconFetch( processid: dword; winhandle: hwnd; index : integer ) : hicon; overload ;
function queueIconFetch( processid: dword; index : integer ) : hicon; overload ;
procedure reset;
procedure execute; override ;
constructor create;
destructor destroy; override ;
end ;
2020-03-24 11:32:08 +01:00
{$endif}
2011-07-04 19:52:53 +00:00
type
2011-07-26 02:43:02 +00:00
{ TProcessWindow }
2011-07-04 19:52:53 +00:00
TProcessWindow = class( TForm)
2011-07-26 02:43:02 +00:00
btnNetwork: TButton;
2019-06-21 09:09:34 +02:00
btnAttachDebugger: TButton;
2016-08-19 03:20:12 +02:00
CancelButton: TButton;
2017-04-13 21:17:39 +02:00
FontDialog1: TFontDialog;
2020-03-05 15:43:20 +01:00
TabHeader: TPageControl;
2019-06-07 13:53:04 +02:00
plImageList: TImageList;
2017-04-13 21:17:39 +02:00
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
2019-04-07 07:52:21 +02:00
MenuItem2: TMenuItem;
MenuItem3: TMenuItem;
2019-04-07 21:57:08 +02:00
miConvertPIDToDecimal: TMenuItem;
2019-04-07 07:52:21 +02:00
miRefresh: TMenuItem;
2017-04-13 21:17:39 +02:00
miCreateProcess: TMenuItem;
miOpenFile: TMenuItem;
N2: TMenuItem;
miChangeFont: TMenuItem;
MenuItem4: TMenuItem;
MenuItem5: TMenuItem;
N1: TMenuItem;
miProcessListLong: TMenuItem;
2013-04-22 21:03:14 +00:00
miOwnProcessesOnly: TMenuItem;
2016-08-19 03:20:12 +02:00
OKButton: TButton;
2011-07-04 19:52:53 +00:00
Panel1: TPanel;
OpenDialog1: TOpenDialog;
OpenDialog2: TOpenDialog;
2017-04-13 21:17:39 +02:00
Panel3: TPanel;
Panel5: TPanel;
2011-07-04 19:52:53 +00:00
PopupMenu1: TPopupMenu;
InputPIDmanually1: TMenuItem;
Filter1: TMenuItem;
2017-04-13 21:17:39 +02:00
ProcessList: TListBox;
miShowInvisibleItems: TMenuItem;
2020-03-05 15:43:20 +01:00
tsApplications: TTabSheet;
tsProcesses: TTabSheet;
tsWindows: TTabSheet;
2017-04-14 22:53:59 +02:00
Timer1: TTimer;
2011-07-26 02:43:02 +00:00
procedure btnNetworkClick( Sender: TObject) ;
2017-04-13 21:17:39 +02:00
procedure Button1Click( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
procedure CancelButtonClick( Sender: TObject) ;
2017-04-13 21:17:39 +02:00
procedure FormCreate( Sender: TObject) ;
procedure FormDestroy( Sender: TObject) ;
procedure MenuItem5Click( Sender: TObject) ;
procedure miProcessListLongClick( Sender: TObject) ;
procedure miChangeFontClick( Sender: TObject) ;
2013-04-22 21:03:14 +00:00
procedure miOwnProcessesOnlyClick( Sender: TObject) ;
2019-04-07 07:52:21 +02:00
procedure miRefreshClick( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
procedure OKButtonClick( Sender: TObject) ;
2011-07-26 02:43:02 +00:00
procedure btnProcesslistClick( Sender: TObject) ;
procedure btnWindowListClick( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
procedure btnCreateThreadClick( Sender: TObject) ;
2019-06-21 09:09:34 +02:00
procedure btnAttachDebuggerClick( Sender: TObject) ;
2012-01-09 05:11:09 +00:00
procedure btnOpenFileClick( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
procedure InputPIDmanually1Click( Sender: TObject) ;
procedure Filter1Click( Sender: TObject) ;
2011-07-26 02:43:02 +00:00
procedure btnProcessWatchClick( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
procedure FormResize( Sender: TObject) ;
procedure btnProcessListLongClick( Sender: TObject) ;
procedure FormClose( Sender: TObject; var Action: TCloseAction) ;
2013-04-22 21:03:14 +00:00
procedure PopupMenu1Popup( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
procedure ProcessListDrawItem( Control: TWinControl; Index : Integer ;
Rect: TRect; State: TOwnerDrawState) ;
procedure FormShow( Sender: TObject) ;
2013-08-24 18:59:29 +00:00
procedure ProcessListKeyPress( Sender: TObject; var Key: char ) ;
2017-04-13 21:17:39 +02:00
procedure miShowInvisibleItemsClick( Sender: TObject) ;
2018-10-15 16:14:01 +02:00
procedure TabHeaderChange( Sender: TObject) ;
2020-03-05 15:43:20 +01:00
procedure TabHeaderResize( Sender: TObject) ;
2017-04-14 22:53:59 +02:00
procedure Timer1Timer( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
private
{ Private declarations }
currentchar: integer ;
2017-04-14 22:53:59 +02:00
wantedheight: integer ;
2011-07-04 19:52:53 +00:00
ffilter: string ;
2020-03-05 15:43:20 +01:00
2020-03-24 11:32:08 +01:00
{$ifdef windows}
2020-03-05 15:43:20 +01:00
IconFetchThread: TIconFetchThread;
2020-03-24 11:32:08 +01:00
{$endif}
2011-07-04 19:52:53 +00:00
processlistlong: tprocesslistlong;
2017-04-13 21:17:39 +02:00
procedure refreshlist;
2011-07-04 19:52:53 +00:00
procedure setbuttons;
procedure SetFilter( filter: string ) ;
property filter: string read ffilter write setfilter;
procedure filterlist;
2020-03-24 11:32:08 +01:00
{$ifdef windows}
2020-03-05 15:43:20 +01:00
procedure iconFetchedEvent( sender: TObject; processid: dword; index : integer ; icon: hicon) ;
2020-03-24 11:32:08 +01:00
{$endif}
2011-07-04 19:52:53 +00:00
public
{ Public declarations }
procedure PWOP( ProcessIDString: string ) ;
2018-10-15 16:14:01 +02:00
published
2020-03-05 15:43:20 +01:00
property TabControl1: TPageControl read TabHeader;
2011-07-04 19:52:53 +00:00
end ;
var
ProcessWindow: TProcessWindow;
2017-05-01 18:56:31 +02:00
commonProcessesList: tstringlist;
2011-07-04 19:52:53 +00:00
implementation
2011-07-26 02:43:02 +00:00
uses MainUnit, formsettingsunit, advancedoptionsunit, frmProcessWatcherUnit,
2022-09-27 16:31:24 +02:00
memorybrowserformunit, networkConfig, ProcessHandlerUnit, processlist, globals,
2023-10-20 17:32:15 +02:00
registry, fontSaveLoadRegistry, frmOpenFileAsProcessDialogUnit,
networkInterfaceApi, MainUnit2, DebuggerInterfaceAPIWrapper, gdbserverconnectdialog,
GDBServerDebuggerInterface, plugin;
2011-07-04 19:52:53 +00:00
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)' ;
2014-05-26 08:27:04 +00:00
rsProcessList = 'Process List' ;
2011-07-04 19:52:53 +00:00
2017-07-07 15:21:38 +02:00
rsApplications= 'Applications' ;
rsProcesses= 'Processes' ;
rsWindows= 'Windows' ;
2017-04-14 19:17:32 +02:00
var errortrace: integer ;
2020-03-05 15:43:20 +01:00
{$IFDEF windows}
function SendMessageTimeout( hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM; fuFlags, uTimeout: UINT; var lpdwResult: ptruint) : LRESULT; stdcall ; external 'user32' name 'SendMessageTimeoutA' ;
2020-03-24 11:32:08 +01:00
2020-03-05 15:43:20 +01:00
procedure TIconFetchThread. getIcon( e: PIconFetchEntry) ;
var
s: string ;
HI : HICON;
tempptruint: ptruint;
begin
HI : = 0 ;
if e^ . winhandle< > 0 then
begin
if SendMessageTimeout( e^ . winhandle, WM_GETICON, ICON_SMALL, 0 , SMTO_ABORTIFHUNG, 2 0 0 , tempptruint ) < > 0 then
begin
HI : = tempptruint;
if HI = 0 then
begin
if SendMessageTimeout( e^ . winhandle, WM_GETICON, ICON_SMALL2, 0 , SMTO_ABORTIFHUNG, 1 0 0 , tempptruint ) < > 0 then
HI : = tempptruint;
if HI = 0 then
if SendMessageTimeout( e^ . winhandle, WM_GETICON, ICON_BIG, 0 , SMTO_ABORTIFHUNG, 5 0 , tempptruint ) < > 0 then
HI : = tempptruint;
end ;
end ;
end ;
if HI = 0 then
begin
s: = GetFirstModuleName( e^ . processid) ;
HI : = ExtractIcon( hinstance, pchar( s) , 0 ) ;
end ;
if HI< > 0 then
e^ . icon: = HI
else
e^ . icon: = HWND( - 1 ) ;
resolvedListCS. Enter;
resolvedList. Add( e) ;
resolvedListCS. Leave;
end ;
procedure TIconFetchThread. execute;
var
wr: TWaitResult;
listnotempty: boolean ;
e: PIconFetchEntry;
pid: dword;
begin
2022-07-22 22:50:06 +02:00
NameThreadForDebugging( 'TIconFetchThread' , ThreadID) ;
2020-03-05 15:43:20 +01:00
while not terminated do
begin
wr: = hasdata. WaitFor( 1 0 0 0 ) ;
if terminated then exit;
if wr= wrSignaled then
begin
listnotempty: = true ;
while listnotempty do
begin
//fetch an item from the list
requestsListCS. enter;
e: = requestsList. last;
if e< > nil then
requestsList. Delete( requestsList. Count- 1 ) ;
listnotempty: = requestsList. Count> 0 ;
requestsListCS. leave;
//get the icon for this PID and then call the IconFetchedEvent
if e< > nil then
getIcon( e) ;
end ;
end
else
if wr< > wrTimeout then break;
end ;
end ;
function TIconFetchThread. QueueIconFetch( processid: dword; winhandle: hwnd; index : integer ) : HIcon;
{
Queues an processid and window for processing
Changes the priority on request
Returns the icon if it has already been processed
}
var
found: boolean ;
i: integer ;
e: PIconFetchEntry;
begin
//first check if already in the list
result : = 0 ;
found: = false ;
requestsListCS. enter;
for i: = 0 to requestsList. count- 1 do
begin
e: = requestsList[ i] ;
if ( e^ . processid= processid) and ( e^ . index = index ) and ( e^ . winhandle= winhandle) then
begin
found: = true ;
requestsList. Delete( i) ;
requestsList. Add( e) ;
break;
end ;
end ;
requestsListCS. leave;
if not found then
begin
//check if in the resolve queue, and if so, return it now
resolvedListCS. enter;
for i: = 0 to resolvedList. count- 1 do
begin
e: = resolvedList[ i] ;
if ( e^ . processid= processid) and ( e^ . index = index ) and ( e^ . winhandle= winhandle) then
begin
resolvedlist. Delete( i) ;
result : = e^ . icon;
found: = true ;
break;
end ;
end ;
resolvedListCS. leave;
end ;
if not found then
begin
getmem( e, sizeof( TIconFetchEntry) ) ;
e^ . processid: = processid;
e^ . winhandle: = winhandle;
e^ . index : = index ;
e^ . icon: = 0 ;
requestsListCS. enter;
requestsList. Add( e) ;
requestsListCS. leave;
hasData. SetEvent;
end ;
end ;
function TIconFetchThread. QueueIconFetch( processid: dword; index : integer ) : HIcon;
begin
result : = QueueIconFetch( processid, 0 , index ) ;
end ;
procedure TIconFetchThread. reset;
var i: integer ;
begin
RemoveQueuedEvents( self) ;
resolvedListCS. enter;
for i: = 0 to resolvedList. Count- 1 do
if resolvedList[ i] < > nil then
freemem( resolvedList[ i] ) ;
resolvedList. Clear;
resolvedListCS. leave;
requestsListCS. enter;
for i: = 0 to requestsList. Count- 1 do
if requestsList[ i] < > nil then
freemem( requestsList[ i] ) ;
requestsList. clear;
requestsListCS. leave;
end ;
constructor TIconFetchThread. create;
begin
hasData: = TEvent. create( nil , false , false , '' ) ;
requestsList: = Tlist. create;
requestsListCS: = TCriticalSection. Create;
resolvedList: = TList. create;
resolvedListCS: = TCriticalSection. create;
inherited create( false ) ;
end ;
destructor TIconFetchThread. Destroy;
begin
terminate;
hasdata. SetEvent;
waitfor;
reset;
hasdata. free;
requestsList. Free;
requestsListCS. free;
resolvedList. free;
resolvedListCS. free;
inherited destroy;
end ;
2020-03-24 11:32:08 +01:00
{$ENDIF}
2020-03-05 15:43:20 +01:00
2011-07-04 19:52:53 +00:00
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
2019-12-18 12:07:17 +01:00
{$ifdef windows}
2011-07-04 19:52:53 +00:00
i: = 0 ;
while not terminated and ( i< $FFFFFFFF ) do
begin
2020-02-09 20:32:40 +01:00
h: = windows. OpenProcess( ifthen( GetSystemType< = 6 , $1f0fff , process_all_access) , false , i) ;
2011-07-04 19:52:53 +00:00
if h< > 0 then
begin
modulename: = getProcessnameFromProcessID( i) ;
process[ processcount] : = inttohex( i, 8 ) + '-' + modulename;
inc( processcount) ;
if processcount> = 1 0 then
synchronize( drawprocesses) ;
closehandle( h) ;
end ;
if ( ( i mod 4 0 9 6 ) = 0 ) then
if processcount> 0 then synchronize( drawprocesses) ;
inc( i) ;
end ;
if processcount> 0 then synchronize( drawprocesses) ;
2019-12-18 12:07:17 +01:00
{$endif}
2011-07-04 19:52:53 +00:00
end ;
2017-05-01 18:56:31 +02:00
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
2019-12-18 12:07:17 +01:00
commonProcessesList. LoadFromFile( s{$if FPC_FULLVERSION >= 030200} , true {$endif} ) ;
2017-05-01 18:56:31 +02:00
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 ;
2019-12-18 12:07:17 +01:00
2017-05-01 18:56:31 +02:00
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, 1 0 ) ) then exit( true ) ;
result : = false ;
end ;
2011-07-04 19:52:53 +00:00
procedure TProcessWindow. filterlist;
2017-04-12 11:34:30 +02:00
var
i: integer ;
2022-09-27 16:31:24 +02:00
{$IFDEF WINDOWS}
2017-04-12 11:34:30 +02:00
pli: PProcessListInfo;
2022-09-27 16:31:24 +02:00
{$ENDIF}
2017-04-12 11:34:30 +02:00
s: string ;
2011-07-04 19:52:53 +00:00
begin
2020-03-06 11:20:07 +01:00
if ( filter= '' ) and ( commonProcessesList= nil ) then exit;
2017-04-12 11:34:30 +02:00
ffilter: = uppercase( ffilter) ;
2011-07-04 19:52:53 +00:00
i: = 0 ;
while i< processlist. Items. Count do
begin
2022-09-27 16:31:24 +02:00
{$IFDEF WINDOWS}
2017-04-12 11:34:30 +02:00
pli: = PProcessListInfo( processlist. items. Objects[ i] ) ;
2022-09-27 16:31:24 +02:00
{$ENDIF}
2017-04-12 11:34:30 +02:00
2020-03-07 11:28:58 +01:00
if ( ( ffilter< > '' ) and ( pos( ffilter, uppercase( processlist. Items[ i] ) ) = 0 ) ) or isInCommonProcessesList( processlist. Items[ i] ) then
2017-04-12 11:34:30 +02:00
begin
2022-09-27 16:31:24 +02:00
{$IFDEF WINDOWS}
2017-04-12 11:34:30 +02:00
if pli< > nil then
begin
if pli^ . processIcon> 0 then
2017-04-14 23:19:16 +02:00
begin
if pli^ . processID< > GetCurrentProcessId then
DestroyIcon( pli^ . processIcon) ;
pli^ . processIcon: = 0 ;
end ;
2017-04-12 11:34:30 +02:00
2018-06-12 20:23:45 +02:00
freememandnil( pli) ;
2017-04-12 11:34:30 +02:00
end ;
2022-09-27 16:31:24 +02:00
{$ENDIF}
2017-04-12 11:34:30 +02:00
processlist. Items. Delete( i) ;
end
2011-07-04 19:52:53 +00:00
else
inc( i) ;
end ;
end ;
procedure TProcesswindow. SetFilter( filter: string ) ;
begin
ffilter: = filter;
2017-04-13 21:17:39 +02:00
refreshlist;
2011-07-04 19:52:53 +00:00
end ;
procedure TProcessWindow. CancelButtonClick( Sender: TObject) ;
begin
mainform. canceled: = true ;
//ProcessWindow.close;
ModalResult: = mrCancel;
end ;
2020-03-24 11:32:08 +01:00
{$ifdef windows}
2020-03-05 15:43:20 +01:00
procedure TProcessWindow. iconFetchedEvent( sender: TObject; processid: dword; index : integer ; icon: hicon) ;
var
i: integer ;
pli: PProcessListInfo;
begin
if ( index > = 0 ) and ( index< processlist. items. count) then
begin
pli: = PProcessListInfo( processlist. Items. Objects[ index ] ) ;
if pli< > nil then
begin
if pli^ . processID= processid then //making sure the list didn't change
begin
if pli^ . processIcon= 0 then
begin
pli^ . processIcon: = icon;
end
else
begin
if ( icon< > 0 ) and ( icon< > HWND( - 1 ) ) and ( processid< > getcurrentprocessid) then
begin
DestroyIcon( icon) ; //not needed anymore (duplicates shouldn't happen...)
end ;
end ;
end ;
end ;
end ;
end ;
2020-03-24 11:32:08 +01:00
{$endif}
2017-04-13 21:17:39 +02:00
procedure TProcessWindow. FormCreate( Sender: TObject) ;
var
x: array of integer ;
reg: tregistry;
begin
2020-03-24 11:32:08 +01:00
2019-12-18 12:07:17 +01:00
{$ifdef darwin}
2020-03-28 15:09:12 +01:00
{ ProcessList. AnchorSideTop: = ProcessWindow. AnchorSideTop;
2019-12-18 12:07:17 +01:00
ProcessList. AnchorSideLeft: = TabHeader. AnchorSideLeft;
ProcessList. AnchorSideRight: = TabHeader. AnchorSideRight;
ProcessList. AnchorSideBottom: = TabHeader. AnchorSideBottom;
ProcessList. Anchors: = TabHeader. Anchors;
TabHeader. TabIndex: = 1 ;
2020-03-28 15:09:12 +01:00
TabHeader. Visible: = false ; }
tsWindows. TabVisible: = false ;
tsWindows. Visible: = false ;
2019-12-18 12:07:17 +01:00
{$endif}
2022-07-22 22:50:06 +02:00
2019-12-18 12:07:17 +01:00
{$ifdef windows}
2020-03-24 11:32:08 +01:00
IconFetchThread: = TIconFetchThread. create;
2020-03-28 15:09:12 +01:00
{$endif}
2020-03-05 15:43:20 +01:00
tsApplications. Caption: = rsApplications;
tsProcesses. Caption: = rsProcesses;
tsWindows. Caption: = rsWindows;
2019-12-18 12:07:17 +01:00
2017-04-13 21:17:39 +02:00
setlength( x, 0 ) ;
if LoadFormPosition( self, x) then
begin
autosize: = false ;
2017-04-16 19:55:21 +02:00
if length( x) > 0 then
2018-10-15 16:14:01 +02:00
TabHeader. TabIndex: = x[ 0 ] ;
2017-04-16 19:55:21 +02:00
if length( x) > 1 then
2017-07-12 01:22:02 +02:00
begin
miOwnProcessesOnly. checked: = x[ 1 ] < > 0 ;
ProcessesCurrentUserOnly: = x[ 1 ] < > 0 ;
end ;
2017-04-13 21:17:39 +02:00
end
else
refreshlist;
reg: = tregistry. create;
try
2021-11-16 20:58:25 +01:00
if reg. OpenKey( '\Software\' + strCheatEngine+ '\Process Window\Font' + darkmodestring, false ) then
2020-12-11 03:13:58 +01:00
LoadFontFromRegistry( processlist. Font, reg)
else
processlist. font. color: = colorset. FontColor;
2017-04-13 21:17:39 +02:00
finally
reg. free;
end ;
2023-10-20 17:32:15 +02:00
if formSettings. cbUseGDBServer. checked then
btnNetwork. Caption: = 'Connect to GDB' ;
2017-04-13 21:17:39 +02:00
end ;
procedure TProcessWindow. FormDestroy( Sender: TObject) ;
2018-06-11 15:36:17 +02:00
var x: array of integer ;
2017-04-13 21:17:39 +02:00
begin
2018-06-11 15:36:17 +02:00
setlength( x, 3 ) ;
2018-10-15 16:14:01 +02:00
x[ 0 ] : = TabHeader. TabIndex;
2018-06-11 15:36:17 +02:00
x[ 1 ] : = ifthen( miOwnProcessesOnly. checked, 1 , 0 ) ;
SaveFormPosition( self, x) ;
2017-04-13 21:17:39 +02:00
end ;
procedure TProcessWindow. MenuItem5Click( Sender: TObject) ;
begin
end ;
procedure TProcessWindow. miProcessListLongClick( Sender: TObject) ;
2017-04-12 11:34:30 +02:00
begin
2017-04-13 21:17:39 +02:00
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) ;
2017-04-14 22:53:59 +02:00
//processlist.Canvas.Refresh;
Timer1Timer( timer1) ;
2017-04-13 21:17:39 +02:00
processlist. Repaint;
reg: = tregistry. create;
try
2021-11-16 20:58:25 +01:00
if reg. OpenKey( '\Software\' + strCheatEngine+ '\Process Window\Font' + darkmodestring, true ) then
2017-04-13 21:17:39 +02:00
SaveFontToRegistry( FontDialog1. Font, reg) ;
finally
reg. free;
end ;
end ;
2017-04-12 11:34:30 +02:00
end ;
2013-04-22 21:03:14 +00:00
procedure TProcessWindow. miOwnProcessesOnlyClick( Sender: TObject) ;
begin
ProcessesCurrentUserOnly: = miOwnProcessesOnly. checked;
2017-04-13 21:17:39 +02:00
refreshlist;
2013-04-22 21:03:14 +00:00
end ;
2019-04-07 07:52:21 +02:00
procedure TProcessWindow. miRefreshClick( Sender: TObject) ;
begin
refreshList;
end ;
2011-07-26 02:43:02 +00:00
procedure TProcessWindow. btnNetworkClick( Sender: TObject) ;
2023-10-20 17:32:15 +02:00
var
host: string ;
port: word ;
2011-07-26 02:43:02 +00:00
begin
2023-10-20 17:32:15 +02:00
if formsettings. cbUseGDBServer. checked then
2017-04-13 21:17:39 +02:00
begin
2023-10-20 17:32:15 +02:00
if MessageDlg( 'Connecting to GDB using this option instead of attaching the debugger to the native process will force the use of GDB read and write memory functions which is a lot slower, and you will not have access to local symbol info and some other tools you may be used to. Are you sure?' , mtWarning, [ mbyes, mbno] , 0 ) < > mryes then exit;
GDBReadProcessMemory: = true ;
GDBWriteProcessMemory: = true ;
2023-11-13 01:47:23 +01:00
SkipVirtualProtectEx: = true ;
2023-10-20 17:32:15 +02:00
outputdebugstring( 'Using GDBServer debugger interface' ) ;
if CurrentDebuggerInterface< > nil then
freeandnil( CurrentDebuggerInterface) ;
2021-09-28 18:47:05 +02:00
2023-10-20 17:32:15 +02:00
if formsettings. cbLaunchGDBServer. Checked then
begin
port: = strtoint( formsettings. edtGDBPort. Text ) ;
CurrentDebuggerInterface: = TGDBServerDebuggerInterface. createAndConnect( formsettings. edtGDBServerCommand. Text , 'localhost' , port) ;
end
2017-04-13 21:17:39 +02:00
else
2021-09-28 18:47:05 +02:00
begin
2023-10-20 17:32:15 +02:00
//spawn a dialog asking
if getGDBHostAndPort( host, port) then
CurrentDebuggerInterface: = TGDBServerDebuggerInterface. connectToExistingServer( host, port) ;
end ;
if CurrentDebuggerInterface< > nil then
begin
tabheader. ShowTabs: = false ;
TabHeaderResize( nil ) ;
if TabHeader. TabIndex< > 1 then
TabHeader. Tabindex: = 1 ;
2021-09-28 18:47:05 +02:00
refreshlist;
2023-10-20 17:32:15 +02:00
processlist. SetFocus;
btnAttachDebugger. Visible: = false ;
if processlist. Count= 0 then
begin
//this is a processless system
MainForm. ProcessLabel. caption: = 'Remote System' ;
processhandler. processid: = $FFFFFFFE ;
processhandler. processhandle: = - 2 ;
startdebuggerifneeded( false ) ;
onAPIPointerChange: = TGDBServerDebuggerInterface( currentdebuggerinterface) . OnApiPointerChange;
onAPIPointerChange( nil ) ;
modalresult: = mrok;
end ;
end ;
end
else
begin
if frmNetworkConfig= nil then
frmNetworkConfig: = tfrmNetworkConfig. create( self) ;
if frmNetworkConfig. ShowModal= mrok then
begin
tabheader. ShowTabs: = false ;
TabHeaderResize( nil ) ;
if TabHeader. TabIndex< > 1 then
TabHeader. Tabindex: = 1 ;
refreshlist;
processlist. SetFocus;
2021-09-28 18:47:05 +02:00
end ;
2022-11-13 09:14:43 +01:00
2017-04-13 21:17:39 +02:00
end ;
end ;
procedure TProcessWindow. Button1Click( Sender: TObject) ;
begin
2011-07-26 02:43:02 +00:00
end ;
2011-07-04 19:52:53 +00:00
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
ProcessHandler. ProcessHandle: = 0 ;
with mainform do
begin
if GetSystemType> = 4 then
begin
cbSpeedhack. checked: = false ;
cbSpeedhack. Enabled: = true ;
cbunrandomizer. Checked: = false ;
cbunrandomizer. Enabled: = true ;
end ;
end ;
2019-08-18 09:20:25 +02:00
2019-12-18 12:07:17 +01:00
{$ifdef windows}
2019-08-18 09:20:25 +02:00
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 ;
2019-12-18 12:07:17 +01:00
{$endif}
2011-07-04 19:52:53 +00:00
2023-10-20 17:32:15 +02:00
if ( CurrentDebuggerInterface< > nil ) and ( CurrentDebuggerInterface is TGDBServerDebuggerInterface) then
begin
//use the currently selected processid for startdebuggerifneeded (for the vAttach packet)
processhandler. processhandle: = - 2 ;
startdebuggerifneeded( false ) ;
onAPIPointerChange: = TGDBServerDebuggerInterface( currentdebuggerinterface) . OnApiPointerChange;
onAPIPointerChange( nil ) ;
processhandler. processid: = $fffffffe ; //the processid is not needed anymore
end
else
Open_Process;
2011-07-04 19:52:53 +00:00
2023-08-25 08:48:13 +02:00
if ProcessHandle= 0 then
begin
if not runningAsAdmin then
begin
raise exception. Create( 'Failed opening process. Likely due to lack of admin rights' ) ;
end ;
end ;
2011-07-04 19:52:53 +00:00
ProcessSelected: = true ;
2019-12-18 12:07:17 +01:00
{$ifdef windows}
2011-07-04 19:52:53 +00:00
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
2011-07-26 02:43:02 +00:00
begin
if usephysical or usephysicaldbvm then
DBKProcessMemory;
end ;
2019-12-18 12:07:17 +01:00
{$endif}
2011-07-04 19:52:53 +00:00
end ;
procedure TProcessWindow. OKButtonClick( Sender: TObject) ;
var ProcessIDString: String ;
begin
2023-08-25 08:48:13 +02:00
try
Outputdebugstring( 'OK button click' ) ;
if Processlist. ItemIndex> - 1 then
begin
unpause;
DetachIfPossible;
2011-07-04 19:52:53 +00:00
2023-08-25 08:48:13 +02:00
ProcessIDString: = copy( ProcessList. Items[ Processlist. ItemIndex] , 1 , pos( '-' , ProcessList. Items[ Processlist. ItemIndex] ) - 1 ) ;
2011-07-04 19:52:53 +00:00
2023-10-20 17:32:15 +02:00
Outputdebugstring( 'calling PWOP' ) ;
2023-08-25 08:48:13 +02:00
PWOP( ProcessIDString) ;
2017-04-16 19:30:00 +02:00
2020-07-13 12:18:06 +02:00
2023-08-25 08:48:13 +02:00
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 ;
2011-07-04 19:52:53 +00:00
2023-08-25 08:48:13 +02:00
except
on e: exception do
MessageDlg( e. Message , mtError, [ mbok] , 0 ) ;
end ;
2014-04-13 19:20:12 +00:00
//outputdebugstring('After ok click handler');
2011-07-04 19:52:53 +00:00
end ;
//button1click specific:
2011-07-26 02:43:02 +00:00
procedure TProcessWindow. btnProcesslistClick( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
begin
2017-04-12 11:34:30 +02:00
2011-07-04 19:52:53 +00:00
end ;
2011-07-26 02:43:02 +00:00
procedure TProcessWindow. btnWindowListClick( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
begin
2017-04-13 21:17:39 +02:00
//miSkipSystemProcesses.visible:=false;
2017-04-12 11:34:30 +02:00
2011-07-04 19:52:53 +00:00
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 ;
2019-06-21 09:09:34 +02:00
procedure TProcessWindow. btnAttachDebuggerClick( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
var ProcessIDString: String ;
i: Integer ;
2021-03-11 07:37:44 -08:00
oldpid, newpid: dword;
2022-06-01 13:10:34 +02:00
starttime: qword;
2011-07-04 19:52:53 +00:00
begin
2021-03-11 07:37:44 -08:00
oldpid: = processid;
2011-07-04 19:52:53 +00:00
if Processlist. ItemIndex> - 1 then
begin
if MessageDlg( rsAttachdebuggerornot, mtConfirmation, [ mbyes, mbno] , 0 ) = mryes then
begin
2022-06-01 13:10:34 +02:00
2011-07-04 19:52:53 +00:00
unpause;
DetachIfPossible;
ProcessIDString: = '' ;
i: = 1 ;
while ProcessList. Items[ Processlist. ItemIndex] [ i] < > '-' do
begin
ProcessIDString: = ProcessIDString+ ProcessList. Items[ Processlist. ItemIndex] [ i] ;
inc( i) ;
end ;
2021-03-11 07:37:44 -08:00
val( '$' + ProcessIDString, newpid, i) ;
2011-07-04 19:52:53 +00:00
2021-03-11 07:37:44 -08:00
if ( Processhandle< > 0 ) and ( oldpid< > newpid) then
2011-07-04 19:52:53 +00:00
begin
CloseHandle( ProcessHandle) ;
ProcessHandler. ProcessHandle: = 0 ;
end ;
2020-09-02 10:00:47 +02:00
try
if processid= GetCurrentProcessId then raise exception. create( rsPleaseSelectAnotherProcess) ;
2011-07-04 19:52:53 +00:00
2022-06-01 13:10:34 +02:00
starttime: = GetTickCount64;
2021-03-11 07:37:44 -08:00
Debuggerthread: = TDebuggerThread. MyCreate2( newpid) ;
2022-06-01 13:10:34 +02:00
2020-09-02 10:00:47 +02:00
except
on e: exception do
begin
debuggerthread: = nil ;
MessageDlg( e. message , mtError, [ mbok] , 0 ) ;
exit;
end ;
end ;
2011-07-04 19:52:53 +00:00
2022-06-01 13:10:34 +02:00
OutputDebugString( 'Debugger attach time=' + ( GetTickCount64- starttime) . ToString) ;
2011-07-04 19:52:53 +00:00
mainform. ProcessLabel. Caption: = ProcessList. Items[ Processlist. ItemIndex] ;
ProcessSelected: = true ;
mainform. debugproc: = true ;
modalresult: = mrOK;
end
end else showmessage( rsFirstSelectAProcess) ;
end ;
2012-01-09 05:11:09 +00:00
procedure TProcessWindow. btnOpenFileClick( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
begin
2021-03-28 22:09:07 +02:00
{$ifdef windows}
2011-07-04 19:52:53 +00:00
if opendialog2. execute then
begin
2018-07-31 18:29:22 +02:00
if frmOpenFileAsProcessDialog= nil then
frmOpenFileAsProcessDialog: = tfrmOpenFileAsProcessDialog. create( self) ;
2011-07-04 19:52:53 +00:00
2018-07-31 18:29:22 +02:00
if frmOpenFileAsProcessDialog. showmodal= mrok then
begin
DBKFileAsMemory( opendialog2. filename, frmOpenFileAsProcessDialog. startaddress) ;
processselected: = true ;
2019-02-22 12:05:24 +01:00
ProcessHandler. ProcessHandle: = QWORD( - 2 ) ;
2018-07-31 18:29:22 +02:00
MainForm. ProcessLabel. caption: = extractfilename( opendialog2. FileName) ;
MainForm. miSaveFile. visible: = true ;
ProcessHandler. processid: = $FFFFFFFF ;
Processhandler. is64Bit: = frmOpenFileAsProcessDialog. rb64. checked;
modalresult: = mrok;
end ;
2011-07-04 19:52:53 +00:00
end ;
2021-03-28 22:09:07 +02:00
{$else}
MessageDlg( 'Not yet implemented' , mtError, [ mbok] , 0 ) ;
{$endif}
2011-07-04 19:52:53 +00:00
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
2017-07-12 01:22:02 +02:00
fltr: = filter;
2011-07-04 19:52:53 +00:00
if inputquery( rsFilter, rsWhatAreYouLookingFor, fltr) then
filter: = fltr;
end ;
2011-07-26 02:43:02 +00:00
procedure TProcessWindow. btnProcessWatchClick( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
begin
if frmprocesswatcher= nil then
frmprocesswatcher: = tfrmprocesswatcher. Create( mainform) ;
2018-04-13 00:25:53 +02:00
2011-07-04 19:52:53 +00:00
frmprocesswatcher. show;
modalresult: = mrcancel;
end ;
procedure TProcessWindow. FormResize( Sender: TObject) ;
begin
//reset the button positions
2017-04-13 21:17:39 +02:00
// setbuttons;
2011-07-04 19:52:53 +00:00
end ;
procedure TProcessWindow. btnProcessListLongClick( Sender: TObject) ;
begin
if processlistlong= nil then
begin
processlist. Clear;
2017-04-13 21:17:39 +02:00
miProcessListLong. Caption: = rsScanningClickToStop;
2011-07-04 19:52:53 +00:00
processlistlong: = tprocesslistlong. create( true ) ;
processlistlong. processlist: = processlist;
processlistlong. start;
end
else
begin
2017-04-13 21:17:39 +02:00
miProcessListLong. Caption: = rsProcessListLong;
2011-07-04 19:52:53 +00:00
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 ;
2017-04-13 21:17:39 +02:00
miProcessListLong. Caption: = rsProcessListLong;
2011-07-04 19:52:53 +00:00
end ;
2021-01-21 01:04:41 +01:00
position: = poDesigned;
2011-07-04 19:52:53 +00:00
end ;
2013-04-22 21:03:14 +00:00
procedure TProcessWindow. PopupMenu1Popup( Sender: TObject) ;
begin
2019-04-07 07:44:09 +02:00
miShowInvisibleItems. visible: = tabheader. TabIndex= 2 ;
2013-04-22 21:03:14 +00:00
end ;
2011-07-04 19:52:53 +00:00
procedure TProcessWindow. ProcessListDrawItem( Control: TWinControl;
Index : Integer ; Rect: TRect; State: TOwnerDrawState) ;
2019-04-07 21:57:08 +02:00
var
i: integer ;
t: string ;
sep: integer ;
pids: string ;
pid: dword;
2022-09-27 16:31:24 +02:00
{$IFDEF WINDOWS}
2020-03-05 15:43:20 +01:00
pli: PProcessListInfo;
2022-09-27 16:31:24 +02:00
{$ENDIF}
2011-07-04 19:52:53 +00:00
begin
2017-04-14 22:53:59 +02:00
wantedheight: = ProcessList. canvas. TextHeight( 'QqJjWwSs' ) + 3 ;
{ i: = ProcessList. canvas. TextHeight( 'QqJjWwSs' ) + 3 ;
if processlist. itemheight< i then ProcessList. ItemHeight: = i; }
2011-07-04 19:52:53 +00:00
processlist. Canvas. FillRect( rect) ;
2017-04-14 22:53:59 +02:00
{
2017-04-13 21:17:39 +02:00
i: = ProcessList. canvas. TextHeight( 'QqJjWwSs' ) + 3 ;
2017-04-14 22:53:59 +02:00
if processlist. itemheight< i then ProcessList. ItemHeight: = i; }
2011-07-04 19:52:53 +00:00
2017-04-13 21:17:39 +02:00
2019-04-07 21:57:08 +02:00
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) ;
2019-04-08 09:33:08 +02:00
t: = format( '%.8d' , [ pid] ) + copy( t, sep) ;
2019-04-07 21:57:08 +02:00
except
end ;
end ;
end ;
2017-04-13 21:17:39 +02:00
2021-09-30 22:35:38 +02:00
if odSelected in state then
processlist. Canvas. font. color: = clHighlightText
else
processlist. Canvas. font. color: = processlist. font. color;
2019-04-07 21:57:08 +02:00
processlist. Canvas. TextOut( rect. Left+ rect. Bottom- rect. Top+ 3 , rect. Top, t) ;
2021-09-28 18:47:05 +02:00
if getConnection< > nil then exit;
2019-12-18 12:07:17 +01:00
{$ifdef windows}
2020-03-07 11:28:58 +01:00
if getprocessicons and ( processlist. Items. Objects[ index ] < > nil ) then
2020-03-05 15:43:20 +01:00
begin
pli: = PProcessListInfo( processlist. Items. Objects[ index ] ) ;
if pli^ . processIcon= 0 then
pli^ . processIcon: = IconFetchThread. queueIconFetch( pli^ . processID, pli^ . winhandle, index ) ;
if ( pli^ . processIcon< > 0 ) and ( pli^ . processIcon< > HWND( - 1 ) ) then
DrawIconEx( processlist. Canvas. Handle, rect. left, rect. Top, pli^ . processIcon, rect. Bottom- rect. Top, rect. Bottom- rect. Top, 0 , 0 , DI_NORMAL) ;
end ;
2019-12-18 12:07:17 +01:00
{$endif}
2011-07-04 19:52:53 +00:00
end ;
procedure TProcessWindow. FormShow( Sender: TObject) ;
2020-03-05 21:05:18 +01:00
var
tr: trect;
preferedwidth: integer ;
tabwidth: integer ;
pc: integer ;
s: string ;
i: integer ;
2011-07-04 19:52:53 +00:00
begin
2021-09-28 18:47:05 +02:00
if getconnection< > nil then
tabheader. ShowTabs: = true ;
2019-12-18 12:07:17 +01:00
2019-06-21 09:09:34 +02:00
OKButton. Constraints. MinHeight: = trunc( 1.2 * btnAttachDebugger. height) ;
CancelButton. Constraints. MinHeight: = OKButton. Constraints. MinHeight;
2017-05-01 18:56:31 +02:00
loadCommonProcessesList;
2017-04-14 19:50:43 +02:00
errortrace: = 1 0 0 ;
try
errortrace: = 1 0 1 ;
processlist. canvas. Refresh;
errortrace: = 1 0 2 ;
ProcessList. ItemHeight: = max( processlist. canvas. TextHeight( 'QqJjWwSs' ) + 3 , canvas. TextHeight( 'QqJjWwSs' ) + 3 ) ;
errortrace: = 1 0 3 ;
currentchar: = 1 ;
errortrace: = 1 0 4 ;
refreshlist;
errortrace: = 1 0 5 ;
2011-07-04 19:52:53 +00:00
2017-04-16 19:24:54 +02:00
if autosize then
begin
autosize: = false ;
2019-02-03 02:04:51 +01:00
//first run or no saving positions
2020-03-05 21:05:18 +01:00
preferedwidth: = max( clientwidth, canvas. TextWidth( ' XXXXXXXX - XXXXXXXXXXXXXXXXXXXXXX ' ) ) ;
pc: = tabheader. PageCount;
tabwidth: = 0 ;
for i: = 0 to pc- 1 do
begin
tr: = tabheader. TabRect( i) ;
tabwidth: = tabwidth+ tr. Width;
end ;
tabwidth: = tabwidth+ canvas. TextWidth( ' ' ) ;
if tabwidth> preferedwidth then
preferedwidth: = tabwidth;
clientwidth: = preferedwidth;
2019-02-03 02:04:51 +01:00
height: = mainform. Height- ( mainform. height div 3 ) ;
position: = poDesigned;
position: = poMainFormCenter;
2020-03-05 21:05:18 +01:00
2017-04-16 19:24:54 +02:00
end ;
2017-04-14 19:50:43 +02:00
errortrace: = 1 0 6 ;
2017-07-19 09:42:28 +02:00
2019-12-18 12:07:17 +01:00
2017-07-19 09:42:28 +02:00
processlist. SetFocus;
2019-12-18 12:07:17 +01:00
2017-04-14 19:50:43 +02:00
except
on e: exception do
raise exception. create( 'FormShow exception (' + e. message + ') at section ' + inttostr( errortrace) ) ;
2016-08-19 03:20:12 +02:00
2017-04-14 19:50:43 +02:00
end ;
2019-12-18 12:07:17 +01:00
2011-07-04 19:52:53 +00:00
end ;
2013-08-24 18:59:29 +00:00
procedure TProcessWindow. ProcessListKeyPress( Sender: TObject; var Key: char ) ;
begin
if key= #8 then
filter: = copy( filter, 1 , length( filter) - 1 )
else
2013-10-05 23:53:52 +00:00
if key in [ chr( 3 2 ) .. chr( 1 2 8 ) ] then
2013-08-24 18:59:29 +00:00
filter: = filter+ key;
end ;
2017-04-13 21:17:39 +02:00
procedure TProcessWindow. RefreshList;
var
i: integer ;
oldselectionindex: integer ;
oldselection: string ;
found: boolean ;
2017-04-14 19:17:32 +02:00
2011-07-04 19:52:53 +00:00
begin
2020-03-24 11:32:08 +01:00
{$ifdef windows}
2020-03-05 15:43:20 +01:00
IconFetchThread. reset;
2020-03-24 11:32:08 +01:00
{$endif}
2020-03-05 15:43:20 +01:00
2017-04-16 19:47:42 +02:00
processlist. Items. BeginUpdate;
2017-04-14 19:17:32 +02:00
try
oldselectionindex: = processlist. ItemIndex;
2017-04-13 21:17:39 +02:00
2017-04-14 19:17:32 +02:00
if oldselectionindex< > - 1 then
oldselection: = processlist. Items[ oldselectionIndex] ;
2017-04-13 21:17:39 +02:00
2018-10-15 16:14:01 +02:00
case TabHeader. TabIndex of
2017-04-14 19:17:32 +02:00
0 :
begin
2019-12-18 12:07:17 +01:00
{$ifdef windows}
2017-04-14 19:17:32 +02:00
getwindowlist2( processlist. Items) ;
2020-03-28 15:09:12 +01:00
{$else}
getapplicationlist( processlist. items) ;
2019-12-18 12:07:17 +01:00
{$endif}
2017-04-14 19:17:32 +02:00
end ;
2017-04-13 21:17:39 +02:00
2017-04-14 19:17:32 +02:00
1 :
begin
getprocesslist( processlist. items) ;
end ;
2 :
begin
2019-12-18 12:07:17 +01:00
{$ifdef windows}
2017-04-14 19:17:32 +02:00
GetWindowList( processlist. Items, miShowInvisibleItems. Checked) ;
processlist. ItemIndex: = processlist. Items. Count- 1 ;
2020-03-28 15:09:12 +01:00
{$else}
getprocesslist( processlist. items) ;
2019-12-18 12:07:17 +01:00
{$endif}
2017-04-14 19:17:32 +02:00
end ;
2017-04-13 21:17:39 +02:00
end ;
2017-04-14 19:17:32 +02:00
filterlist;
2017-04-13 21:17:39 +02:00
2017-04-14 19:17:32 +02:00
if oldselectionindex= - 1 then
begin
processlist. ItemIndex: = processlist. Items. Count- 1 ; //go to the end
end
2017-04-13 21:17:39 +02:00
else
begin
2017-04-14 19:17:32 +02:00
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) ) ;
2017-04-13 21:17:39 +02:00
2017-04-14 19:17:32 +02:00
found: = false ;
2020-08-21 19:04:17 +02:00
for i: = processlist. Items. Count- 1 downto 0 do
2017-04-14 19:17:32 +02:00
if pos( oldselection, processlist. items[ i] ) > 0 then
begin
processlist. ItemIndex: = i;
found: = true ;
2017-04-13 21:17:39 +02:00
2017-04-14 19:17:32 +02:00
break;
end ;
2017-04-13 21:17:39 +02:00
2017-04-14 19:17:32 +02:00
if not found then
processlist. ItemIndex: = processlist. Items. Count- 1 ;
end ;
2017-04-13 21:17:39 +02:00
end ;
2017-07-12 01:22:02 +02:00
if filter< > '' then
caption: = rsProcessList+ ' : *' + filter+ '*'
else
caption: = rsProcessList;
2017-04-13 21:17:39 +02:00
2019-12-18 12:07:17 +01:00
{$ifdef windows}
2017-04-14 19:17:32 +02:00
if formsettings. cbKernelReadWriteProcessMemory. checked or ( dbvm_version> = $ce000004 ) then //driver is active
begin
2020-03-15 18:11:13 +01:00
if TabHeader. TabIndex< = 2 then //other script are on their own
processlist. Items. Insert( 0 , '00000000-[' + rsPhysicalMemory+ ']' ) ;
2017-04-14 19:17:32 +02:00
end ;
2019-12-18 12:07:17 +01:00
{$endif}
2017-04-13 21:17:39 +02:00
2017-04-16 19:47:42 +02:00
finally
processlist. items. EndUpdate;
2017-04-14 19:17:32 +02:00
end ;
2017-04-13 21:17:39 +02:00
end ;
procedure TProcessWindow. miShowInvisibleItemsClick( Sender: TObject) ;
begin
refreshList;
end ;
2018-10-15 16:14:01 +02:00
procedure TProcessWindow. TabHeaderChange( Sender: TObject) ;
2017-04-13 21:17:39 +02:00
begin
refreshList;
2011-07-04 19:52:53 +00:00
end ;
2020-03-05 15:43:20 +01:00
procedure TProcessWindow. TabHeaderResize( Sender: TObject) ;
var p: tpoint;
begin
p: = TabHeader. ClientToParent( point( 0 , 0 ) ) ;
2022-09-27 16:31:24 +02:00
//if TabHeader.ShowTabs=false then
// processlist.top:=tabheader.top
// else
processlist. Top: = p. Y;
2020-03-05 15:43:20 +01:00
processlist. Left: = p. X;
processlist. Width: = TabHeader. ClientWidth;
2022-09-27 16:31:24 +02:00
// if tabheader.ShowTabs=false then
processlist. Height: = TabHeader. ClientHeight
// else
// processlist.Height:=tabheader.Height;
2020-03-05 15:43:20 +01:00
end ;
2017-04-14 22:53:59 +02:00
procedure TProcessWindow. Timer1Timer( Sender: TObject) ;
2020-03-05 15:43:20 +01:00
var
i: integer ;
2020-03-24 11:32:08 +01:00
{$ifdef windows}
2020-03-05 15:43:20 +01:00
e: PIconFetchEntry;
2020-03-24 11:32:08 +01:00
{$endif}
2017-04-14 22:53:59 +02:00
begin
try
if processlist. itemheight< > wantedheight then
begin
ProcessList. ItemHeight: = wantedheight;
processlist. canvas. Refresh;
processlist. Repaint;
end ;
2020-03-05 15:43:20 +01:00
2020-03-24 11:32:08 +01:00
{$ifdef windows}
2020-03-05 15:43:20 +01:00
IconFetchThread. resolvedListCS. enter;
try
e: = nil ;
for i: = 0 to IconFetchThread. resolvedList. count- 1 do
begin
e: = PIconFetchEntry( IconFetchThread. resolvedList[ i] ) ;
iconFetchedEvent( IconFetchThread, e^ . processid, e^ . index , e^ . icon) ;
freemem( e) ;
end ;
IconFetchThread. resolvedList. clear;
finally
IconFetchThread. resolvedListCS. leave;
end ;
if e< > nil then processlist. Repaint;
2020-03-24 11:32:08 +01:00
{$endif}
2020-03-05 15:43:20 +01:00
2017-04-14 22:53:59 +02:00
except
timer1. enabled: = false ;
showmessage( 'timer issue' ) ;
end ;
end ;
2017-04-14 11:56:57 +02:00
2011-07-04 19:52:53 +00:00
initialization
{$i ProcessWindowUnit.lrs}
end .
2020-03-24 11:32:08 +01:00