Salut,
Sinon, il y a une solution plus propre avec CreateProcess. Mais elle ne fonctionne que sur certains .exe, ceux qui utilisent CW_DEFAULT dans leur CreateWindow (Par exemple notepad n'est pas dans ce cas là, mais sysedit si).
procedure TForm1.Button1Click(Sender: TObject);
var
startupInfo: TStartupInfo;
processInfo: TProcessInformation;
begin
ZeroMemory(@startupInfo, SizeOf(startupInfo));
with startupInfo do
begin
cb:= SizeOf(startupInfo);
dwFlags:= STARTF_USESHOWWINDOW or STARTF_USEPOSITION or STARTF_USESIZE;
wShowWindow:= SW_SHOW;
dwX:= 10;
dwY:= 10;
dwXSize:= 800;
dwYSize:= 300;
end;
if not CreateProcess(nil, 'sysedit', nil, nil, False, 0, nil, nil, startupInfo, processInfo) then
RaiseLastOSError
else
begin
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
end;
end;
Utiliser SetWindowPos est risqué car il faut récupérer le handle de la fenêtre de l'appli juste lancée. Donc si elle n'est pas complètement lancée, la fenêtre n'existe pas encore... D'où l'utilisation d'un Sleep, mais difficile de fixer sa valeur. Autre problème, plusieurs instance de l'application à lancer peuvent exister -> plusieurs fenêtres correspondantes. On utilise alors GetWindowThreadProcessId et comparer avec le PID renvoyé par CreateProcess.
Voilà une solution de meilleure qualité qu'avec un Sleep en utilisant WaitForSingleObject (On est sur d'attendre suffisamment tout en attendant le minimum de temps). Par contre il y a un risque de partir en boucle infinie. Mais il est réduit car la boucle s'arrête si le processus lancé s'arrête.
type TFindWindowParam = packed record
nPid: Cardinal;
bFound: LongBool;
end;
implementation
function EnumWndAndResize(hWnd: THandle; var lpFindWindowParam: TFindWindowParam): LongBool; stdcall;
var
nPid: Cardinal;
begin
Result:= True;
// Changement de position si le PID correspond
GetWindowThreadProcessId(hWnd, @nPid);
if nPid = lpFindWindowParam.nPid then
begin
SetWindowPos(hWnd, 0, 10, 10, 800, 300, SWP_NOZORDER);
lpFindWindowParam.bFound:= True;
Result:= False; // On arrête l'énumération
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
startupInfo: TStartupInfo;
processInfo: TProcessInformation;
findWindowParam: TFindWindowParam;
begin
ZeroMemory(@startupInfo, SizeOf(startupInfo));
with startupInfo do
begin
cb:= SizeOf(startupInfo);
dwFlags:= STARTF_USESHOWWINDOW;
wShowWindow:= SW_SHOW;
end;
if not CreateProcess(nil, 'notepad', nil, nil, False, 0, nil, nil, startupInfo, processInfo) then
RaiseLastOSError
else
begin
// Initialisation du paramètre passé à la fonction d'énumération des fenêtres
with findWindowParam do
begin
nPid:= processInfo.dwProcessId;
bFound:= False;
end;
// Boucle toute les milliseconde tant que le processus créé existe
while WaitForSingleObject(processInfo.hProcess, 1) = WAIT_TIMEOUT do
begin
// Cherche une fenêtre correspondant
EnumWindows(@EnumWndAndResize, Integer(@findWindowParam));
if findWindowParam.bFound then Break;
end;
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
end;
end;