Terminating applications
Close
current Delphi application:
- there are several options for closing a Delphi application:
- NB. "abort" does not terminate an application, it creates a
silent exception which gets handled by the exception handler
- call form.close method of the main form:
- but this then checks the OnClose routine to see if it can close
and if errors arise then close fails
- call application.terminate:
- doesn't work for console applications (use Halt instead)
- this will process the finalization section but not try..finally
- call halt:
- this is the more generic way to terminate an application
- this will process the finalization section but not try..finally
- create own app killer routine that should definitely destroy
the application:
- eg. procedure KillProcessNow; //in fmxutils.pas
- var memmgr : TMemoryManager;
- begin
- try
- exitproc := nil; ExceptProc := nil; ErrorProc := nil;
SetRaiseList(nil); LibModuleList := nil; ModuleUnloadList := Nil;
- // ask windows nicely to kill us. (well, as nice as we get here)
- TerminateProcess(GetCurrentProcess, 0);
- // what - still here? Surely not, Let's pop the stack
- while true do
- finally
- // we don't believe you could ever get here. but if we do,
- // well, we'll just make sure that nothing will ever work again anyway.
- memmgr.GetMem := nil; memmgr.FreeMem := nil; memmgr.ReallocMem := nil;
SetMemoryManager(memmgr); end;
- end;
Run
an application, wait for it to finish, then destroy it:
- see example in FMXUtils.pas for function WinExecAndWait which will
allow you to run an application such as a DOS application running in a
console window, wait for it to complete, then terminate it and then continue
with your program.
- NB. for this to work on a DOS console, you should execute a shortcut to the app.
and set the shortcut's property to "Close on Exit"
Kill All Applications:
- this uses the TerminateApp command (in WinAPI ToolHelp)
to kill the app but may not free all its resources.
- uses: ToolHelp;
- procedure KillAll;
- var pTask : PTaskEntry; Task : Bool; ThisTask:
THANDLE;
- begin
- GetMem (pTask, SizeOf (TTaskEntry));
- pTask^.dwSize := SizeOf (TTaskEntry);
- Task := TaskFirst (pTask);
- while Task do
- begin
- if pTask^.hInst = hInstance then
- else TerminateApp (pTask^.hTask,
NO_UAE_BOX);
- Task := TaskNext (pTask);
- end;
- TerminateApp (ThisTask, NO_UAE_BOX);
- end;
My method to close a particular named
application:
- uses: ShellAPI;
- procedure TFrmHASFix.CloseAnApplication(Title,AltTitle
:String);
- var
- SwitchWnd, Wnd : hWnd;
- Style : LongInt;
- Buff, ProgTitle, AlternativeTitle : Array[0..6]
of Char; {limit size to first 6 characters}
- begin
- StrPLCopy(ProgTitle,Title,6); {convert string
title to null-term. char ProgTitle}
- StrPLCopy(AlternativeTitle,AltTitle,6); {convert
string title to null-term. char ProgTitle}
- {Wnd := EnumWindow(Handle,)}{is this a better
tool????}
- Wnd := GetWindow(Handle, gw_HWndLast);
- GetWindowText(Wnd,buff,sizeof(buff)); {initialise
buff}
- While ((Wnd <> 0) and not((Buff =
ProgTitle) or (Buff = AlternativeTitle))) do
- {get list of all open windows except this
programs window handle}
- begin
- if (Wnd <> Handle) and
isWindowVisible(Wnd) and (GetWindow(Wnd,
gw_Owner) = 0) and
(GetWindowText(Wnd,buff, sizeof(buff))
<> 0) then
- GetWindowText(Wnd,buff,sizeof(buff));
- if ((buff = ProgTitle) or (Buff =
AlternativeTitle)) then
- begin
- postMessage(Wnd, $10, 0,
0);{gives window close command
but closure is under application
control}
- {ToolHelp.TerminateApp(Wnd,NO_UAE_BOX);
}{forcibly closes app but may not
free all resources}
- {DestroyWindow(Wnd);}{close
application - is there a better
way???}
- showMessage('One instance
closed');
- end;
- Wnd := GetWindow(Wnd, gw_hWndPrev);
- end;
- end;
Close an external application using
WM_CLOSE:
- NB. this will not force closure if target application prompts user such as
"Save changes?"
- hnd : FindWindow(nil, PChar('EQuery Sender'));
- if hnd = 0 then exit; //sender application was not running
- if not postmessage(hnd, WM_CLOSE, 0, 0) then
- Application.messageBox('Warning! Sender application did not close.',
'Sender did not close', idok);