Me permito decir que la API FindWindow tiene las desventaja de tener que conocer el nombre de la clase de ventana o el Caption (este último puede ser cambiante). Lo ideal es poder conocer el Handle de la ventana de un proceso desde su pid.
En ese sentido propongo complicar el código:
Código Delphi
[-]
function GetWindowFromPId(PId: DWORD): THandle;
type
TWinParam = record
Handle: THandle;
PId: DWORD;
end;
PWinParam = ^TWinParam;
var
WinParam: TWinParam;
function EnumWindowsProc(Handle: Thandle; lParam: LPARAM): BOOL; stdcall;
var
PId: DWORD;
begin
Result:= true;
PId:= 0;
GetWindowThreadProcessId(Handle, PId);
if PWinParam(lParam).PId = PId then
begin
PWinParam(lParam).Handle:= Handle;
Result:= false;
end;
end;
begin
WinParam.Handle:= 0;
WinParam.PId:= PId;
EnumWindows(@EnumWindowsProc, LPARAM(@WinParam));
repeat
Result:= WinParam.Handle;
WinParam.Handle:= Windows.GetParent(Result);
until WinParam.Handle = 0;
end;
function ExecuteAsChild(CommandLine: String; Handle: THandle): THandle;
var
SI: TStartupInfo;
PI: TProcessInformation;
CR: TRect;
begin
ZeroMemory(@SI, sizeof(TStartupInfo));
SI.cb:= sizeof(SI);
Result:= 0;
if CreateProcess(nil, PCHAR(CommandLine), nil, nil, false, 0, nil, nil, SI, PI) then
begin
WaitForInputIdle(PI.hProcess, 10000);
Result:= GetWindowFromPId(PI.dwProcessId);
Windows.SetParent(Result, Handle);
GetClientRect(Handle, CR);
SetWindowPos(Result, 0, 0, 0, CR.Right-CR.Left, CR.Bottom-CR.Top, SWP_SHOWWINDOW);
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
end;
end;
Si quisiéramos usar la versión propuesta por
duilioisola con ShellExecuteEx en lugar de con CreateProcess, también podemos:
Código Delphi
[-]
type
function GetProcessId(hProcess: THANDLE): DWORD; stdcall; external Kernel32;
function ExecuteAsChild2(ExeFile: String; Handle: THandle): THandle;
var
RI: TShellExecuteInfo;
CR: TRect;
begin
FillChar(RI, SizeOf(RI), #0);
RI.cbSize := SizeOf(RI);
RI.fMask := SEE_MASK_NOCLOSEPROCESS;
RI.lpVerb := 'Open';
RI.lpFile := PChar(ExeFile);
RI.lpParameters := PChar('');
RI.lpDirectory := PChar('');
Result:= 0;
if ShellExecuteEx(@RI) then
begin
WaitForInputIdle(Ri.hProcess, 5000);
Result:= GetWindowFromPId(GetProcessId(Ri.hProcess));
Windows.SetParent(Result, Handle );
Windows.GetClientRect(Handle, CR);
SetWindowPos(Result, 0, 0, 0, CR.Right-CR.Left, CR.Bottom-CR.Top, SWP_SHOWWINDOW);
CloseHandle(RI.hProcess);
end;
end;
Saludos.