I am using the following code to open another application from within my app.
type TShellState = class
SEInfo: TShellExecuteInfo;
AppName: String;
Constructor Create(pSEInfo: TShellExecuteInfo; pAppName: String);
end;
Var
ShellStates: TObjectStack<TShellState>;
Constructor TShellstate.Create(pSEInfo: TShellExecuteInfo; pAppName: string);
begin
inherited Create;
SEInfo := pSEInfo;
AppName := pAppName;
end;
//In Form Create
ShellStates := TObjectStack<TShellState>.create;
ShellStates.OwnsObjects := true;
function DoExecute(Const ExecuteFile: string;
Const ParamString: string;
Modal: Boolean;
UseLocalDir: Boolean = false;
NoCloseProc: Boolean = true): Boolean;
Var SEInfo: TShellExecuteInfo;
ExitCode: DWORD;
begin
FillChar(SEInfo, SizeOf(SEInfo), 0) ;
SEInfo.cbSize := SizeOf(TShellExecuteInfo) ;
with SEInfo do begin
fMask := SEE_MASK_DEFAULT;
Wnd := Application.Handle;
lpFile := PChar(ExecuteFile) ;
lpParameters := PChar(ParamString) ;
if UseLocalDir then
lpDirectory := PChar(ExtractFilePath(ExecuteFile));
nShow := SW_SHOWNORMAL;
end;
Result := ShellExecuteEx(@SEInfo);
if result then begin
if Modal then begin
if SEInfo.hProcess <> 0 then begin
WaitForSingleObject(SEInfo.hProcess, INFINITE);
CloseHandle(SEInfo.hProcess);
end;
Result := true;
end
else if NoCloseProc then
ShellStates.Push(TShellState.Create(SEInfo, ExecuteFile));
end;
end;
If NoCloseProc is true I place the SEInfo record into stack.
When I come to close the main program, I was expecting to be able to use fields in the SEInfo to identify the window to receive the WM_CLOSE message. e.g.
while ShellStates.Count > 0 do begin
ShellState := ShellStates.Peek;
SendMessage(ShellState.SEInfo.Wnd, WM_CLOSE,0,0);
ShellStates.Pop;
end
But both hProcess and Wnd are 0 so it looks like I will have to locate the window using the file name. Is there a more straightforward way? I tried using the FindWindow API call with the SEInfo.lpFile but that returns 0.