Bonjour à tous,
Je cherche à faire qqchose d'archi classique : ouvrir un fichier et attendre que l'utilisateur ait fini pour revenir dans l'application. J'ai cherché à utiliser les moyens suivants :
ShellExecute: Rien à redire. On lui passe le nom d'un fichier quelque soit son type (Pdf, doc, jpg...), il trouve le programme associé et ouvre le fichier avec. Seul problème: dès que le programme en question est lancé, on poursuit l'exécution du code. Donc ca va pas dans mon cas.
CreateProcess + WaitForSingleObject: la on peut effectivement créer un processus et attendre qu'il soit terminé pour poursuivre. Seul problème: on ne peut lancer que des exécutables, et non pas des fichiers nus (que Windows se chargerait d'ouvrir avec le bon programme).
Voir exemple sur le site (que dis-je, la bible!) de Michel Bardou :
http://www.phidels.com/php/index.php...zip.php3&id=66
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 function LanceAppliAttenteFin(NomFichier:string):boolean; { LanceAppliAttenteFin renvoie true si le lancement s'est bien passé } var StartInfo : TStartupInfo; ProcessInformation : TProcessInformation; begin result:=true; ZeroMemory(@StartInfo, sizeof(StartInfo)); // remplie de 0 StartInfo StartInfo.cb:=sizeof(StartInfo); if CreateProcess(nil,PChar(NomFichier),nil,nil,true,0,nil,nil,StartInfo,ProcessInformation) then WaitForSingleObject(ProcessInformation.hProcess, INFINITE)// attend que l'application désignée par le handle ProcessInformation.hProcess soit terminée else result:=false; end;
ShellExecuteEx: Différence avec ShellExecute: on peut récupérer l'id du process. Du coup, après avoir demandé à Windows d'ouvrir le fichier souhaité, on peut attendre que le process soit terminé. Le parfait mariage entre la 1ere et la 2eme méthode. Mais léger problème: le "scan" d'attente de fin de process prend 100% des ressources du CPU.
Méthode utilisée : http://delphi.about.com/od/windowssh...uteprogram.htm
Cette dernière méthode est assez séduisante, mais alors le fait que le processeur soit pris a 100% pendant la boucle repeat ..until est loin d'être satisfaisant.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 uses ShellApi; ... var SEInfo: TShellExecuteInfo; ExitCode: DWORD; ExecuteFile, ParamString, StartInString: string; begin ExecuteFile:='c:\temp\monfichier.pdf'; FillChar(SEInfo, SizeOf(SEInfo), 0) ; SEInfo.cbSize := SizeOf(TShellExecuteInfo) ; with SEInfo do begin fMask := SEE_MASK_NOCLOSEPROCESS; Wnd := Application.Handle; lpFile := PChar(ExecuteFile) ; { ParamString can contain the application parameters. } // lpParameters := PChar(ParamString) ; { StartInString specifies the name of the working directory. If ommited, the current directory is used. } // lpDirectory := PChar(StartInString) ; nShow := SW_SHOWNORMAL; end; if ShellExecuteEx(@SEInfo) then begin repeat Application.ProcessMessages; GetExitCodeProcess(SEInfo.hProcess, ExitCode) ; until (ExitCode <> STILL_ACTIVE) or Application.Terminated; ShowMessage('Fichier PDF fermé') ; end else ShowMessage('Impossible de visionner le fichier PDF!') ; end;
Est-ce que quelqu'un voit un moyen de rendre cette boucle moins gourmande ? J'avais pensé mettre un sleep(1000) dans la boucle, mais je ne trouve pas ca très élégant ?
Partager