From: ccdps@levels.unisa.edu.au
Newsgroups: comp.os.ms-windows.programmer.misc
Subject: Detecting termination of an Exec'ed program
Date: 2 Nov 92 08:13:29 +1030
Organization: University of South Australia

Program TestExitTask;

{
   This short TPW 1.5 program installs a callback that does a MessageBeep every
   time a task exits. What I want it to do, however, is beep only when
   a particular task exits, which is trickier. When this program works, it
   will provide a framework for utilities that launch an application and
   then wait for it to finish. My immediate need is for our LAN; we need to
   be able to unlink a network drive when the program is finished, thus taking
   one network copy out of use. (ie, a kind of batch file for Windows.)

   The global variable that holds the taskid I am looking for is always
   0, and so is the dwData that is passed to the callback. I don't know
   why this is. I am using the far memory model.

   Any ideas? This is a Frequently Unanswered Question which goes past
   regularly, and this is the second posting I have made (just in case...
   sorry if I got you twice!)

   Many, many thanks,

   --
   Dan Shearer                        email: Dan.Shearer@UniSA.edu.au
   Information Technology Branch      Phone: +61 8 302 3479
   University of South Australia      Fax  : +61 8 302 3385

[ BTW LAN Manager 2.1 Programmers Toolkit available from comlab.gatech.edu ]

}

{$F+}  {Far model - Needed for global hTaskTest to be available to callback.}


uses
   {TPW Units}
   WObjects, strings, WinProcs, WinTypes, Win31, ToolHelp;

type
  PTaskTestApp = ^TTaskTestApp;
  TTaskTestApp = object(TApplication)
    procedure InitMainWindow; virtual;
  end;

var
  hTestTask : THandle;

{This is the callback installed by a NotifyRegister}
function CheckTask(wId:Word; dwData:longint) : Bool;

begin
  if wID = NFY_EXITTASK then begin
    if THandle(dwData)=hTestTask then begin
      MessageBeep(MB_ICONEXCLAMATION);
    end;
    CheckTask := TRUE;
    end;
  end else begin
    CheckTask := FALSE;
  end;
end; {CheckTask}

{Spawns NOTEPAD}
function Execute : boolean;
var
  PText,PCaption,PAppPath : PChar;
  AppInstance : THandle;
  lpTask : PTaskEntry;
  Result : Integer;
  AppPath : String;
  ExecuteVal : boolean;

begin
  GetMem(PAppPath,64);
  AppPath := 'NOTEPAD.EXE';
  StrPCopy(PAppPath,AppPath);
  ExecuteVal := TRUE;
  AppInstance := THandle(WinExec(PAppPath,SW_SHOWNORMAL));
  if AppInstance < HINSTANCE_ERROR then begin
    GetMem(PText,40);
    GetMem(PCaption,40);
    PText := 'Error loading program';
    PCaption := 'TaskTest Error';
    MessageBox(0,PText,PCaption,1);
    ExecuteVal := FALSE;
  end; {if WinExec unsuccessful}
  hTestTask := AppInstance;
  Execute := ExecuteVal;
end; {Execute}


procedure TTaskTestApp.InitMainWindow;
var
  CheckTaskProc: TFarProc;
  NotifyProc: TNotifyCallback;

begin
  MainWindow := New(PWindow, Init(nil, 'Exit Task Tester'));
  CheckTaskProc := MakeProcInstance(@CheckTask,HInstance); {HInstance means this app}
  NotifyProc := TNotifyCallBack(CheckTaskProc);
  NotifyRegister(THandle(0),NotifyProc,NF_NORMAL);
  if not Execute then begin
  end;
end; {TTestTaskApp.InitMainWindow}



var
  MyApp : TTaskTestApp;

begin
  MyApp.Init('TaskTest');
  MyApp.Run;
  MyApp.Done;
end.
#! rnews 915