{***********************************************************************}
{									}
{ __WinExPgm  Execute a process within a window 			}
{									}
{ procedure __WinExPgm(ProgName : _Path;				}
{			CmdLine : string;				}
{		    X1,Y1,X2,Y2 : byte; 				}
{	      ForeAttr,BackAttr : byte; 				}
{		  var ErrorCode : word);				}
{									}
{	      ProgName	The program to execute.  The format for 	}
{			ProgName may optionally contain a full path	}
{			specifier and extension, but need not contain	}
{			either. If DOS is specified, a secondary copy	}
{			copy of COMMAND is loaded, and CmdLine is	}
{			passed as the program to execute.		}
{	      CmdLine	The command line to pass to the program.	}
{	      X1,Y1,X2,Y2						}
{			The coordinates of the window in which the	}
{			child process is to execute.  (X1,Y1) is the	}
{			upper left corner (column and row), and (X2,Y2) }
{			is the lower right corner.  Unpredicatable	}
{			results can occur if the values do not define	}
{			a physical window.				}
{	      ForeAttr	The foreground and background attributes of	}
{	      BackAttr	of the window in which the child executes.	}
{	      ErrorCode The returned error status code: 		}
{			0 - File successfully loaded and executed.	}
{			2 - File not found. This error is also returned }
{			    if ProgName is the null string (length 0).	}
{			3 - Path not found.  If a path is specified and }
{			    one of the entries is not present, this	}
{			    code is returned.				}
{			5 - Access denied.  A file not suitable for	}
{			    execution was specified.			}
{			8 - Insufficient memory to load the program.	}
{		       98 - COMSPEC= could not be found in the environ- }
{			    ment.					}
{		       99 - The window coordinates specified do not	}
{			    represent a physical window.		}
{			If DOS version 3.0 or later is used, a call to	}
{			__RetErUtl can be made to return more detail	}
{			on errors 2 through 8.				}
{									}
{ Description This procedure invokes ProgName as a child process,	}
{	      passing to the program CmdLine as the command line	}
{	      parameter.  The procedure __SpawnPgm is used to load	}
{	      the child, so directories are searched as done at the	}
{	      DOS prompt (see __SpawnPgm). If DOS is specified as the	}
{	      path, a secondary copy of COMMAND is loaded using 	}
{	      __DOSExPgm.						}
{									}
{	      When the child process gains control, all I/O to the	}
{	      standard devices (standard input and output) is forced	}
{	      in the specified window.	Programs that do not use DOS	}
{	      services for I/O may not execute properly.  Note that	}
{	      Turbo Pascal programs that use the CRT unit, normally	}
{	      write to the display adapter directly, and even if the	}
{	      variable DirectVideo is set to FALSE, call BIOS services	}
{	      directly.  For Turbo Pascal programs that need CRT	}
{	      services to position the cursor, clear the screen, etc.,	}
{	      Input and Output should be reopened as the standard DOS	}
{	      devices.							}
{									}
{	      When the child executes, it may change the cursor 	}
{	      position and screen image.  It is the responsibility of	}
{	      the calling program to restore the screen if that is	}
{	      desired.							}
{									}
{ Version     4.00 (C)Copyright Blaise Computing Inc.  1987		}
{_______________________________________________________________________}

procedure __WinExPgm(ProgName : _Path;
		      CmdLine : string;
		  X1,Y1,X2,Y2 : byte;
	    ForeAttr,BackAttr : byte;
		var ErrorCode : word);

  var
    Cur10Vector : pointer;
    TempPath	: _Path;
    I,J 	: integer;

  begin {__WinExPgm}

    { Check that the coordinates specified are reasonable.		}

    if ((X1 > X2) or (Y1 > Y2) or (X1 < 1) or (Y1 < 1)) then
       begin
	 ErrorCode := 99;
	 Exit
       end;

    { Now set the global variables used by the BIOS Video service	}
    { routine.								}

    Lo(WinUpper_) := X1 - 1;
    Hi(WinUpper_) := Y1 - 1;
    Lo(WinLower_) := X2 - 1;
    Hi(WinLower_) := Y2 - 1;
    VideoAttr_	  := (BackAttr shl 4) or ForeAttr;
    GetIntVec($10,Prev10Vector_);
    SetIntVec($10,@__Int10Pgm);

    { To test if ProgName is DOS, remove all leading and trailing	}
    { blanks and tabs, and if the resulting length is 3, check if it is }
    { the string DOS (case is not considered).				}

    J := Length(ProgName);
    I := 1;
    while ((I <= J) and ((ProgName[I] = #32) or (ProgName[I] = #9))) do
      Inc(I);
    while ((J >= I) and ((ProgName[J] = #32) or (ProgName[J] = #9))) do
      Dec(J);
    TempPath := Copy(ProgName,I,J - I + 1);

    if (Length(TempPath) = 3) then
       for I := 1 to 3 do
	 TempPath[I] := Upcase(TempPath[I]);

    if (TempPath = 'DOS') then
       __DOSExPgm(CmdLine,ErrorCode)
    else
       __SpawnPgm(ProgName,CmdLine,ErrorCode);

    { Finally, reestablish the original interrupt $10 vector.		}

    SetIntVec($10,Prev10Vector_)

  end;	{__WinExPgm}
