Re: Need list of running Apps
- From: "Spitball" <damon.ellerbee@xxxxxxxxx>
- Date: 21 Aug 2006 07:09:42 -0700
Here is a unit I wrote a few years ago. You may find this helpful.
unit WinApiUtils;
(*
Author: Damon Ellerbee
Created: 2002
Description: This unit wraps some windows API calls, and adds some
enhancements.
This unit sould only be used with windows NT or
better.
*)
interface
uses
//---- VCL
Windows,
Forms,
Messages,
PSAPI,
Classes,
Dialogs,
SysUtils,
contnrs;
const
MAX_TITLE_LENGTH = 260;
type
TSearchType = (stMatchStart, stMatchEnd, stMatchAny);
TTermProcThread = class;
{ THandleList could be moved to another unit if it is found to be
useful in
other contexts. }
THandleList = Class(TList)
private
function Get(Index: Integer): THandle;
procedure Put(Index: Integer; const Value: THandle);
public
function Add(Item: THandle): Integer;
function Extract(Item: THandle): THandle;
function First: THandle;
function IndexOf(Item: THandle): Integer;
procedure Insert(Index: Integer; Item: THandle);
function Last: THandle;
function Remove(Item: THandle): Integer;
property Items[Index: Integer]: THandle read Get write Put;
default;
end;
{ TApiWindow is a wrapper around a windows handle to represent any
window in the system.
Use GetWindows (or a similar function) to get a list of these
objects that will
represent all windows in the system. }
TApiWindow = class(TObject)
private
fHandle: THandle;
fProcessID: Cardinal;
function GetTitle: String;
function GetProcessID: Cardinal;
function GetWindowClassName: String;
public
constructor Create(AHandle: THandle);
procedure AfterConstruction; override;
function IsVisible: Boolean;
function IsWindow: Boolean;
Property Handle: THandle read fHandle;
Property Title: String read GetTitle;
Property ProcessID: Cardinal read GetProcessID;
Property WindowClassName: String read GetWindowClassName;
end;
{ A list of TApiWindow objects }
TApiWindowList = class(TStringList)
protected
function GetItem(Index: Integer): TApiWindow;
public
function Add(aWindowInfo: TApiWindow): Integer; reintroduce;
procedure AfterConstruction; override;
procedure Clear; override;
procedure Delete(Index: Integer); override;
property Items[Index: Integer]: TApiWindow read GetItem; default;
function IndexOf(S: String; SearchType: TSearchType): Integer;
reintroduce; overload;
function IndexOfHandle(aHandle: THandle): Integer;
end;
{ TApiProcess represents a processes running in windows. This object
can be
created without associating it with a process, then when you call
AddWindow,
it will assiciate itself with the process of the windows.
AddWindow will
not allow adding windows that are not related to the same process.
This object can be created by passing a window handle. When this
is done,
it will be associeated with that window's process, and will find
all
related windows for the process. }
TApiProcess = class(TObject)
private
FApiWindows: TApiWindowList;
FExeName: String;
FHiding: Boolean;
FOnAfterTerminate: TNotifyEvent;
FOnBeforeDestroy: TNotifyEvent;
FOnBeforeTerminate: TNotifyEvent;
FOnShowHide: TNotifyEvent;
FProcessHandle: THandle;
FProcessID: Cardinal;
FVisibleWindows: THandleList;
FShowHideWindows: THandleList; //windows that can be shown and
hidden
FTermProcThread: TTermProcThread;
function GetApiWindow(Index: Integer): TApiWindow;
function GetWindowCount: Integer;
function GetVisibleWindow(Index: Integer): TApiWindow;
function GetVisibleWindowCount: Integer;
function GetExeName: String;
function GetShowHideWindow(Index: Integer): TApiWindow;
function GetShowHideWindowCount: Integer;
procedure RefreshWindows;
procedure OpenProcessHandle;
public
property ExeName: String read GetExeName;
property OnAfterTerminate: TNotifyEvent read FOnAfterTerminate
write FOnAfterTerminate;
property OnBeforeDestroy: TNotifyEvent read FOnBeforeDestroy write
FOnBeforeDestroy;
property OnBeforeTerminate: TNotifyEvent read FOnBeforeTerminate
write FOnBeforeTerminate;
property OnShowHide: TNotifyEvent read FOnShowHide write
FOnShowHide;
property ProcessID: Cardinal read FProcessID;
property Hiding: Boolean read FHiding;
property ShowHideWindowCount: Integer read GetShowHideWindowCount;
property ShowHideWindows[Index: Integer]: TApiWindow read
GetShowHideWindow;
property VisibleWindowCount: Integer read GetVisibleWindowCount;
property VisibleWindows[Index: Integer]: TApiWindow read
GetVisibleWindow;
property WindowCount: Integer read GetWindowCount;
property Windows[Index: Integer]: TApiWindow read GetApiWindow;
constructor Create; overload;
constructor Create(AWindowHandle: THandle); overload;
function AddWindow(aApiWindow: TApiWindow): Integer;
procedure Activate;
procedure BeforeDestruction; override;
procedure HideWindows;
procedure MinimizeWindows;
procedure ShowWindows;
procedure Terminate(AWaitTime: Cardinal);
function IsAlive: Boolean;
end;
{ A List of TApiProcess objects }
TApiProcessList = class(TObjectList)
protected
function GetItem(Index: Integer): TApiProcess;
public
function Add(aApiProcess: TApiProcess): Integer; reintroduce;
property Items[Index: Integer]: TApiProcess read GetItem; default;
function IndexOfProcessID(aProcessID: Cardinal): Integer;
function ItemByProcessID(aProcessID: Cardinal): TApiProcess;
end;
{ TTermProcThread is used when terminating processes }
TTermProcThread = class(TThread)
private
FProcessID: Cardinal;
FProcessHandle: THandle;
FApiWindows: TApiWindowList;
FWaitTime: Cardinal;
public
Procedure Execute; override;
constructor Create(AProcessID: Cardinal; AWindows: TApiWindowList;
AWaitTime: Cardinal); reintroduce; overload;
end;
{ Public Procedures and Functions }
{==============================================================================}
function FindWindowRE(Expression: String): TApiWindow;
function GetWindowExeName(aHandle: THandle): String;
function GetTaskbarHandle: THandle;
procedure GetProcesses(AApiProcessList: TApiProcessList;
AApiWindowList: TApiWindowList);
procedure GetWindows(AWindowList: TApiWindowList; AProcessID:
Cardinal = 0);
function GetWindowClassName(AWindowHandle: THandle): String;
function GetWindowTitle(AWindowHandle: THandle): String;
procedure GetVisibleWindows(AWindowList: TApiWindowList; AThreadID:
Cardinal = 0);
procedure HideTaskbar;
procedure ShowTaskbar;
implementation
type
{ TEnumOptions is Used internally by processes like GetWindows. This
object
is passed to the EnumWinProc callback function so that it will know
how to
deal with the window handles it is getting from the system. }
TEnumOptions = Class(TObject)
private
FApiWindowList: TApiWindowList;
FApiProcessList: TApiProcessList;
FProcessID: Cardinal;
FFilterVisibleWindows: Boolean;
public
property ApiWindowList: TApiWindowList read FApiWindowList;
property ApiProcessList: TApiProcessList read FApiProcessList;
property ProcessID: Cardinal read FProcessID;
property FilterVisibleWindows: Boolean read FFilterVisibleWindows;
Constructor Create(AApiWindowList: TApiWindowList;
AApiProcessList: TApiProcessList;
AFilterVisibleWindows: Boolean = False;
AProcessID: Cardinal = 0);
end;
const
GROW_BY = 10;
MAX_TITLE_LEN = 100;
var
{ Regular Expression Searches for windows }
REFindAllWindows: Boolean;
REWindowList: TApiWindowList;
{ Module-Level procedures }
{==============================================================================}
procedure hideTaskbar;
{ Hides the windows taskbar }
var
Handle : THandle;
begin
Handle := GetTaskbarHandle;
ShowWindow(Handle, SW_HIDE);
end;
{------------------------------------------------------------------------------}
procedure ShowTaskbar;
{ Shows the windows taskbar }
var
Handle : THandle;
begin
Handle := GetTaskbarHandle;
ShowWindow(Handle, SW_RESTORE);
end;
{------------------------------------------------------------------------------}
function GetTaskBarHandle: THandle;
{ Returns a handle to the windows taskbar }
begin
Result := FindWindow(PChar('Shell_TrayWnd'), nil);
end;
{------------------------------------------------------------------------------}
function EnumWinProc(aHandle: THandle; LPARAM: Cardinal): boolean;
stdcall;
{
This is a CALLBACK function for enumerating windows. The windows
API will
call this function for each window in the system whenever we ask to.
This function will deposit all windows into a unit array,
"WindowArray"
We use LParam to pass a pointer to a TEnumOptions object.
}
var
vAddWindow: Boolean;
vWin: TApiWindow;
vEnumOptions: TEnumOptions;
vApiProcess: TApiProcess;
vProcessID: Cardinal;
begin
vAddWindow := True;
vEnumOptions := TEnumOptions(LPARAM);
{ Allow for filtering by window visiblity }
if vEnumOptions.FilterVisibleWindows then
vAddWindow := IsWindowVisible(aHandle);
{ Allow for filtering by window process ID }
if vEnumOptions.ProcessID > 0 then
begin
GetWindowThreadProcessID(aHandle, vProcessID);
vAddWindow := vProcessID = vEnumOptions.ProcessID;
end;
if vAddWindow then
begin
vWin := TApiWindow.Create(aHandle);
if Assigned(vEnumOptions.ApiWindowList) then
vEnumOptions.ApiWindowList.Add(vWin);
if Assigned(vEnumOptions.FApiProcessList) then
begin
{ Search for the TApiProcess assicated with this window }
GetWindowThreadProcessID(aHandle, vProcessID);
vApiProcess :=
vEnumOptions.FApiProcessList.ItemByProcessID(vProcessID);
if not Assigned(vApiProcess) then
begin
vApiProcess := TApiProcess.Create;
vEnumOptions.FApiProcessList.Add(vApiProcess);
end;
vApiProcess.AddWindow(vWin);
end;
end;
//Tell the API to continue enumerating windows
result := true;
end;
{------------------------------------------------------------------------------}
function EnumWinProcRE(Handle: THandle; LPARAM: Cardinal): boolean;
stdcall;
{ This function is the enum window proc used by FindWindowRE to find
windows
that match a regular expression }
var
vKeepSearching: Boolean;
vStrLen: integer;
vWindowTitle: string;
vWindowInfo: TApiWindow;
vWindowFound: Boolean;
begin
(*
// get the window's title (we have to a PChar conversion technique
here)
SetLength(vWindowTitle, MAX_TITLE_LEN); //Required!!
//GetWindowText returns the length of the text retrieved
vStrLen := GetWindowText(Handle, pchar(vWindowTitle), MAX_TITLE_LEN);
SetLength(vWindowTitle, vStrLen);
// add this window to the list -- if it matches the regular
expression.
vWindowFound := RE.Exec(vWindowTitle);
if vWindowFound then
begin
vWindowInfo := TApiWindow.Create(Handle);
REWindowList.Add(vWindowInfo);
{ Only keep searching if we want to find all mathing windows }
vKeepSearching := REFindAllWindows;
end
else
{ Always continue searching when we didn't find a match }
vKeepSearching := True;
//Tell the API to if we want to continue enumerating windows
result := vKeepSearching;
*)
end;
{------------------------------------------------------------------------------}
function FindWindowRE(Expression: String): TApiWindow;
{ Finds a window using a regular expression }
begin
(*
Result := nil; //Assume we don't find anything
{ Search for the windows using EnumWindows and a callback function }
REFindAllWindows := False; //Tell callback we only want one window
REWindowList.Clear;
RE.Expression := Expression;
EnumWindows(@WinApiUtils.EnumWinProcRE, 0);
{ we are done searching for windows, return the first one from the
list if
we found anything. }
if REWindowList.Count > 0 then
Result := REWindowList[0]
*)
end;
{------------------------------------------------------------------------------}
function GetWindowExeName(aHandle: THandle): String;
{ Returns the full path and file name of the executeable that started
the window.
This function is only valid for windows NT, 2000, and greater }
var
vStrLen: Integer;
vProcessID: Cardinal;
vProcessHandle: THandle;
begin
GetWindowThreadProcessID(AHandle, vProcessID);
vProcessHandle := OpenProcess(
PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, vProcessID);
SetLength(Result, 250);
vStrLen := GetModuleFileNameEx(vProcessHandle, 0, PChar(Result),
250);
SetLength(Result, vStrLen);
end;
{$HINTS OFF} // prevent "Value assigned to 'variable_name' never used."
hint.
{------------------------------------------------------------------------------}
procedure GetProcesses(AApiProcessList: TApiProcessList;
AApiWindowList: TApiWindowList);
{ Enumerates processes and windows currently running in the system.
Either
AApiProcessList or AApiWindowList can be nil if you don't want to
fill it.
These lists will be passed to the enumeration callback via a
TEnumOptions
object.}
var
vEnumOptions: TEnumOptions;
vEnumSuccess: boolean;
begin
//Ask windows to give a list via a callback function
if not Assigned(AApiProcessList) then
Raise Exception.Create('Parameter AAProcessList can not be nil.');
vEnumOptions := TEnumOptions.Create(AApiWindowList, AApiProcessList,
False, 0);
try
vEnumSuccess := EnumWindows(@WinApiUtils.EnumWinProc,
Integer(vEnumOptions));
Assert(vEnumSuccess , 'Window Enumeration Failed!');
finally
vEnumOptions.Free;
end;
end;
{$HINTS ON}
{$HINTS OFF} // prevent "Value assigned to 'variable_name' never used."
hint.
{------------------------------------------------------------------------------}
procedure GetWindows(AWindowList: TApiWindowList; AProcessID: Cardinal
= 0);
{ This procedure calls the windows API to get information on all
top-level
windows and adds TApiWindow objects to AWindowList. AWindowList will
not
be cleared before adding objects to it. This procedure will not
enumerate
child windows.
If AThreadID is non-zero, this procedure enumerates all top-level
windows
that belong to that thread.
The local function EnumWinProc does most of the *real* work.}
var
vEnumOptions: TEnumOptions;
vEnumSuccess: boolean;
begin
//Ask windows to give a list via a callback function
vEnumOptions := TEnumOptions.Create(AWindowList, Nil, False,
AProcessID);
try
vEnumSuccess := EnumWindows(@WinApiUtils.EnumWinProc,
Integer(vEnumOptions));
Assert(vEnumSuccess , 'Window Enumeration Failed!');
finally
vEnumOptions.Free;
end;
end;
{$HINTS ON}
{------------------------------------------------------------------------------}
function GetWindowClassName(AWindowHandle: THandle): String;
var
vStrLen: Integer;
begin
Result := '';
//if IsWindow(AWindowHandle) then
//begin
SetLength(Result, 260);
vStrLen := RealGetWindowClass(AWindowHandle, PChar(Result), 260);
SetLength(Result, vStrLen);
//end;
end;
{------------------------------------------------------------------------------}
function GetWindowTitle(AWindowHandle: THandle): String;
var
vStrLen: Integer;
begin
Result := '';
SetLength(Result, 260);
vStrLen := GetWindowText(AWindowHandle, PChar(Result), 260);
SetLength(Result, vStrLen);
end;
{------------------------------------------------------------------------------}
procedure GetVisibleWindows(AWindowList: TApiWindowList; AThreadID:
Cardinal = 0);
{ This procedure will fill AWindowList with top-level windows that are
currently visible. }
var
i: integer;
begin
{ First, get all top-level windows }
GetWindows(AWindowList, AThreadID);
{ Now we will remove hidden windows from the WindowArray. We will
iterate from
last to first so that we can delete objects without impacting the
iteration. }
for i := AWindowList.Count -1 downto 0 do
if not isWindowVisible(AWindowList[i].Handle) then
AWindowList.Delete(i)
end;
{ TApiWindowList }
{==============================================================================}
function TApiWindowList.Add(aWindowInfo: TApiWindow): Integer;
begin
Result := Inherited AddObject(aWindowInfo.Title, aWindowInfo);
end;
{------------------------------------------------------------------------------}
procedure TApiWindowList.AfterConstruction;
begin
inherited;
Sorted := True;
CaseSensitive := False;
Duplicates := dupAccept;
end;
{------------------------------------------------------------------------------}
procedure TApiWindowList.Clear;
var
i: Integer;
begin
for i := 0 to Count -1 do
Objects[i].Free;
inherited;
end;
{------------------------------------------------------------------------------}
procedure TApiWindowList.Delete(Index: Integer);
begin
Objects[Index].Free;
inherited;
end;
{------------------------------------------------------------------------------}
function TApiWindowList.GetItem(Index: Integer): TApiWindow;
begin
Result := TApiWindow(Objects[Index]);
end;
{------------------------------------------------------------------------------}
function TApiWindowList.IndexOf(S: String; SearchType: TSearchType):
Integer;
{ Finds an index using search options }
function MatchStart(KeyStr, SearchText: String): Boolean;
var
S: String;
begin
S := Copy(SearchText, 0, Length(KeyStr));
Result := CompareText(KeyStr, S) = 0;
end;
function MatchEnd(KeyStr, SearchText: String): Boolean;
var
S: String;
begin
S := Copy(SearchText, Length(SearchText) - Length(KeyStr) -1,
Length(KeyStr));
Result := CompareText(KeyStr, S) = 0;
end;
function MatchAny(KeyStr, SearchText: String): Boolean;
begin
Result := Pos(UpperCase(KeyStr), UpperCase(SearchText)) > 0;
end;
var
i: Integer;
vFoundMatch: Boolean;
begin
Result := -1;
vFoundMatch := False;
for i := 0 to Count -1 do
begin
Case SearchType of
stMatchStart: vFoundMatch := MatchStart(S, Strings[i]);
stMatchEnd: vFoundMatch := MatchEnd(S, Strings[i]);
stMatchAny: vFoundMatch := MatchAny(S, Strings[i]);
end;
if vFoundMatch then
begin
Result := i;
Break;
end;
end;
end;
{------------------------------------------------------------------------------}
function TApiWindowList.IndexOfHandle(aHandle: THandle): Integer;
var
i: Integer;
begin
i := 0;
Result := -1;
while (i < Count) and (Result = -1) do
begin
if Items[i].Handle = aHandle then
Result := i;
Inc(i);
end;
end;
{ TApiWindow }
{==============================================================================}
procedure TApiWindow.AfterConstruction;
begin
inherited;
FProcessID := 0;
end;
{------------------------------------------------------------------------------}
constructor TApiWindow.Create(AHandle: THandle);
begin
FHandle := AHandle;
end;
{------------------------------------------------------------------------------}
function TApiWindow.GetProcessID: Cardinal;
begin
GetWindowThreadProcessID(FHandle, Result);
end;
{------------------------------------------------------------------------------}
function TApiWindow.GetTitle: String;
var
vStrLen: Integer;
begin
SetLength(Result, MAX_TITLE_LENGTH);
vStrLen := GetWindowText(FHandle, PChar(Result), MAX_TITLE_LENGTH);
SetLength(Result, vStrLen);
end;
{------------------------------------------------------------------------------}
function TApiWindow.GetWindowClassName: String;
const
cMaxCount = 50;
var
vLength: Integer;
begin
SetLength(Result, cMaxCount);
vLength := GetClassName(self.Handle, PAnsiChar(Result), cMaxCount);
SetLength(Result, vLength);
end;
{------------------------------------------------------------------------------}
function TApiWindow.IsVisible: Boolean;
begin
Result := IsWindowVisible(FHandle);
end;
{------------------------------------------------------------------------------}
function TApiWindow.IsWindow: Boolean;
begin
Result := Windows.IsWindow(FHandle);
end;
{ TApiProcess }
{==============================================================================}
procedure TApiProcess.Activate;
begin
if not FHiding then
if VisibleWindowCount > 0 then
ShowWindow(VisibleWindows[VisibleWindowCount-1].Handle,
SW_RESTORE);
end;
{------------------------------------------------------------------------------}
function TApiProcess.AddWindow(aApiWindow: TApiWindow): Integer;
begin
Result := -1; //Assume Failure
{ If this is the first window, assign FProcessID }
if FProcessID = 0 then
Begin
FProcessID := aApiWindow.ProcessID;
OpenProcessHandle;
end;
{ Only allow adding windows with the same process ID }
if aApiWindow.ProcessID = FProcessID then
begin
Result := FApiWindows.Add(aApiWindow);
if IsWindowVisible(aApiWindow.Handle) then
begin
FVisibleWindows.Add(aApiWindow.Handle);
FShowHideWindows.Add(aApiWindow.Handle);
end;
end;
end;
{------------------------------------------------------------------------------}
procedure TApiProcess.BeforeDestruction;
begin
if Assigned(FOnBeforeDestroy) then
FOnBeforeDestroy(Self);
FApiWindows.Free;
FVisibleWindows.Free;
inherited;
end;
{------------------------------------------------------------------------------}
constructor TApiProcess.Create(AWindowHandle: THandle);
var
i: Integer;
begin
{ Get all visible windows for this window process }
Create;
GetWindowThreadProcessID(AWindowHandle, FProcessID);
GetWindows(FApiWindows, FProcessID);
OpenProcessHandle;
for i := 0 to FApiWindows.Count -1 do
if IsWindowVisible(FApiWindows[i].Handle) then
FVisibleWindows.Add(FApiWindows[i].Handle);
end;
{------------------------------------------------------------------------------}
constructor TApiProcess.Create;
begin
FApiWindows := TApiWindowList.Create;
FVisibleWindows := THandleList.Create;
FShowHideWindows := THandleList.Create;
end;
{------------------------------------------------------------------------------}
function TApiProcess.GetApiWindow(Index: Integer): TApiWindow;
begin
Result := FApiWindows[Index];
end;
{------------------------------------------------------------------------------}
function TApiProcess.GetExeName: String;
begin
if FExeName <> '' then
Result := FExeName
else
begin
if WindowCount = 0 then
Result := 'No Process assigned'
else
begin
FExeName := GetWindowExeName(Windows[0].Handle);
Result := FExeName;
end;
end;
end;
{------------------------------------------------------------------------------}
function TApiProcess.GetShowHideWindow(Index: Integer): TApiWindow;
var
vIndex: Integer;
begin
Result := Nil;
vIndex := FApiWindows.IndexOfHandle(FShowHideWindows[Index]);
if vIndex >= 0 then
Result := FApiWindows[vIndex];
end;
{------------------------------------------------------------------------------}
function TApiProcess.GetShowHideWindowCount: Integer;
begin
Result := FShowHideWindows.Count;
end;
{------------------------------------------------------------------------------}
function TApiProcess.GetVisibleWindow(Index: Integer): TApiWindow;
var
vIndex: Integer;
begin
Result := Nil;
vIndex := FApiWindows.IndexOfHandle(FVisibleWindows[Index]);
if vIndex >= 0 then
Result := FApiWindows[vIndex];
end;
{------------------------------------------------------------------------------}
function TApiProcess.GetVisibleWindowCount: Integer;
begin
Result := FVisibleWindows.Count;
end;
{------------------------------------------------------------------------------}
function TApiProcess.GetWindowCount: Integer;
begin
Result := FApiWindows.Count;
end;
{ THandleList }
{==============================================================================}
function THandleList.Add(Item: THandle): Integer;
begin
Result := inherited Add(Pointer(Item));
end;
{------------------------------------------------------------------------------}
function THandleList.Extract(Item: THandle): THandle;
begin
Result := THandle(inherited Extract(Pointer(Item)));
end;
{------------------------------------------------------------------------------}
function THandleList.First: THandle;
begin
Result := THandle(inherited First);
end;
{------------------------------------------------------------------------------}
function THandleList.Get(Index: Integer): THandle;
begin
Result := THandle(inherited Get(Index));
end;
{------------------------------------------------------------------------------}
function THandleList.IndexOf(Item: THandle): Integer;
begin
Result := inherited IndexOf(Pointer(Item));
end;
{------------------------------------------------------------------------------}
procedure THandleList.Insert(Index: Integer; Item: THandle);
begin
inherited Insert(Index, Pointer(Item));
end;
{------------------------------------------------------------------------------}
function THandleList.Last: THandle;
begin
Result := THandle(inherited Last);
end;
{------------------------------------------------------------------------------}
procedure THandleList.Put(Index: Integer; const Value: THandle);
begin
inherited Put(Index, Pointer(Value));
end;
{------------------------------------------------------------------------------}
function THandleList.Remove(Item: THandle): Integer;
begin
Result := inherited Remove(Pointer(Item));
end;
{ TEnumOptions }
{==============================================================================}
constructor TEnumOptions.Create(AApiWindowList: TApiWindowList;
AApiProcessList: TApiProcessList;
AFilterVisibleWindows: Boolean;
AProcessID: Cardinal);
begin
FApiWindowList := AApiWindowList;
FApiProcessList := AApiProcessList;
FFilterVisibleWindows := AFilterVisibleWindows;
FProcessID := AProcessID;
end;
{ TApiProcessList }
{==============================================================================}
function TApiProcessList.Add(aApiProcess: TApiProcess): Integer;
begin
Result := inherited Add(aApiProcess);
end;
{------------------------------------------------------------------------------}
function TApiProcessList.GetItem(Index: Integer): TApiProcess;
begin
Result := TApiProcess(Inherited Items[Index]);
end;
{------------------------------------------------------------------------------}
function TApiProcessList.IndexOfProcessID(aProcessID: Cardinal):
Integer;
{ Returns the index of a ProcessID Item whose ProcessID matches
aProcessID }
var
i: Integer;
begin
i := 0;
Result := -1;
While (i < Count) and (Result = -1) do
begin
if Items[i].ProcessID = aProcessId then
Result := i;
Inc(i);
end;
end;
{------------------------------------------------------------------------------}
function TApiProcessList.ItemByProcessID(aProcessID: Cardinal):
TApiProcess;
{ Returns a TProcessID object whose ProcessID matches aProcessID }
var
vIndex: Integer;
begin
Result := nil;
vIndex := IndexOfProcessID(aProcessID);
if vIndex >= 0 then
Result := Items[vIndex];
end;
{------------------------------------------------------------------------------}
procedure TApiProcess.HideWindows;
var
i: Integer;
begin
if not FHiding then
begin
RefreshWindows;
FHiding := True;
for i := 0 to FShowHideWindows.Count -1 do
ShowWindow(FShowHideWindows[i], SW_HIDE);
if Assigned(FOnShowHide) then
FOnShowHide(Self);
end;
end;
{------------------------------------------------------------------------------}
function TApiProcess.IsAlive: Boolean;
var
vExitCode: Cardinal;
begin
Result := False; //assume failure
if FProcessHandle > 0 then
begin
GetExitCodeProcess(FProcessHandle, vExitCode);
Result := vExitCode = STILL_ACTIVE;
end;
end;
{------------------------------------------------------------------------------}
procedure TApiProcess.MinimizeWindows;
var
i: Integer;
begin
if not FHiding then
begin
RefreshWindows;
FHiding := True;
for i := 0 to FShowHideWindows.Count -1 do
ShowWindow(FShowHideWindows[i], SW_MINIMIZE);
if Assigned(FOnShowHide) then
FOnShowHide(Self);
end;
end;
{------------------------------------------------------------------------------}
procedure TApiProcess.OpenProcessHandle;
begin
FProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION, False,
FProcessID);
end;
{------------------------------------------------------------------------------}
procedure TApiProcess.RefreshWindows;
{ Refreshes all window lists. Note that refreshing the ShowHide window
list
is handled differently than the VisibleWindow list. This is because,
if
a window is hidden, we don't want to remove it from the ShowHide
list. We
do remove dead windows from it, however. }
var
i: Integer;
begin
FApiWindows.Clear;
FVisibleWindows.Clear;
GetWindows(FApiWindows, FProcessID);
{ Refresh Visible Windows }
for i := 0 to FApiWindows.Count -1 do
if FApiWindows[i].IsVisible then
begin
FVisibleWindows.Add(FApiWindows[i].Handle);
if FShowHideWindows.IndexOf(FApiWindows[i].Handle) = -1 then
FShowHideWindows.Add(FApiWindows[i].Handle);
end;
{ Remove ShowHideWindows that are dead }
for i := FShowHideWindows.Count -1 downto 0 do
if not IsWindow(FShowHideWindows[i]) then
FShowHideWindows.Delete(i);
end;
{------------------------------------------------------------------------------}
procedure TApiProcess.ShowWindows;
var
i: Integer;
begin
if FHiding then
begin
RefreshWindows;
for i := 0 to FShowHideWindows.Count -1 do
ShowWindow(FShowHideWindows[i], SW_SHOWNA); //"Show No Activate"
FHiding := False;
if Assigned(FOnShowHide) then
FOnShowHide(Self);
end;
end;
{------------------------------------------------------------------------------}
procedure TApiProcess.Terminate(AWaitTime: Cardinal);
begin
if Assigned(FOnBeforeTerminate) then
FOnBeforeTerminate(Self);
FTermProcThread := TTermProcThread.Create(FProcessID, FApiWindows,
AWaitTime);
if Assigned(FOnAfterTerminate) then
FOnAfterTerminate(Self);
end;
{ TTermProcThread }
{==============================================================================}
constructor TTermProcThread.Create(AProcessID: Cardinal; AWindows:
TApiWindowList;
AWaitTime: Cardinal);
begin
inherited Create(False);
FApiWindows := AWindows;
FProcessID := AProcessID;
FWaitTime := AWaitTime;
end;
{------------------------------------------------------------------------------}
procedure TTermProcThread.Execute;
var
i: Integer;
begin
inherited;
if Not Terminated then
begin
FProcessHandle := OpenProcess(Windows.SYNCHRONIZE, FALSE,
FProcessID);
if FProcessHandle > 0 then
begin
for i := 0 to FApiWindows.Count -1 do
SendMessage(fApiWindows[i].Handle, WM_CLOSE, 0, 0);
WaitForSingleObject(FProcessHandle, FWaitTime);
Terminate;
end;
end;
end;
initialization
REWindowList := TApiWindowList.Create;
finalization
REWindowList.Free;
end.
Roy Coates wrote:
Hi, it's been quite a while since I've used Delphi - and I'm stuck.
I need to build a list of running user apps, specifically the applications title. eg:- "Notepad - myfile.txt"
Can anyone help? Google hasn't !
Many thanks,
Roy.
.
- References:
- Need list of running Apps
- From: Roy Coates
- Need list of running Apps
- Prev by Date: Re: Need list of running Apps
- Next by Date: What does this do: TMyClass(AClass.member).Member?
- Previous by thread: Re: Need list of running Apps
- Next by thread: What does this do: TMyClass(AClass.member).Member?
- Index(es):
Relevant Pages
|