[Delphi] Progress Dialog + Cancel => solutions dispo ...

Progress Dialog + Cancel => solutions dispo ... [Delphi] - Delphi/Pascal - Programmation

Marsh Posté le 22-07-2002 à 10:10:28    

J'voudrais faire l'inévitable fenêtre de progression avec le bouton cancel (pas trouvé en cherchant sur le forum Delphi).
La 1ère solution consiste en un truc du style :
 
  Application.CreateForm(TForm2, Form2);
  with Form2 do
  begin
    Show;
    for i:=1 to 100 do
    begin
      if (Stop) then
      begin
        ShowMessage('Processus interrompu par l''utilisateur';);
        Break;
      end else
      begin
        ProgressBar1.StepIt;
        Sleep(100);
        Application.ProcessMessages;
      end;
    end;
  end;
  Form2.Free;

 
Sachant que la Form2 contient la ProgreesBar et un boutton Cancel qui fait passer Form2.Stop à true.
Ca marche pas trop mal, mais le fait qu'on fasse un Form2.Show et pas un ShowModal implique que l'utilisateur peut faire un peu n'importe quoi.
D'un autre côté, un Form2.ShowModal impliquerait que l'appli principale soit bloquée, or le code du traitement (ici le sleep) s'y trouve. Et il est hors de question de passer le code dans la Form2, because le ProgressDialog sert à de multiples endroits.
 
Donc, j'ai testé avec un Thread comme suit :
 
  Thread := TMyThread.Create;
  for i:=1 to 100 do
  begin
    if (Thread.Stop) then
    begin
      ShowMessage('Processus interrompu par l''utilisateur';);
      Break;
    end else
    begin
      Thread.StepIt;
      Sleep(100);
    end;
  end;
  Thread.Free;

 
Avec le thread suivant :
 
//**********************************************************************************
constructor TMyThread.Create;
begin
  inherited Create(False);
  FreeOnTerminate := false;
  stop := false;
  Form2 := TForm2.Create(nil);
end;
//**********************************************************************************
destructor TMyThread.Destroy;
begin
  Form2.Free;
  inherited;
end;
//**********************************************************************************
procedure TMyThread.Execute;
begin
  inherited;
  Form2.ShowModal;
  stop := Form2.Stop;
end;
//**********************************************************************************
procedure TMyThread.StepIt;
begin
  Synchronize(Form2.ProgressBar1.StepIt);
end;
//**********************************************************************************

 
Seulement ça merde pas mal:
 
1. Ca rame grave (la form2 s'affichage supra lentement et le clic du Cancel prend des plombes avant de réagir).
2. Le Form2.Free plante dans le Destructor.
 
J'imagine que ce prb a été traité depuis belle lurette ?

Reply

Marsh Posté le 22-07-2002 à 10:10:28   

Reply

Marsh Posté le 22-07-2002 à 10:30:09    

Ce que j'avais fait c'est une fenêtre qui désactivait la fenêtre appelante :
procedure Execute(Sender: TForm);
begin
  Sender.Enabled := False;
  try
    Show;
  finally
    Sender.Enabled := True;
  end;
end;
(il me semble, faudrait que je vérifie que ça suffit)
 
Donc l'appelante n'était pas bloquée dans son processus, mais l'utilisateur ne pouvait plus cliquer dedans puisque bloquée.
Pour le système de Cancel tu peux faire ce que tu avais fait dans ton premier exemple j'imagine.
 
Pour que tout ce qui est affichage et réception des commandes de l'utilisateur se fasse bien, il faut souvent faire des Application.ProcessMessages;


Message édité par antp le 22-07-2002 à 10:32:45
Reply

Marsh Posté le 22-07-2002 à 10:48:27    

Ouais, c'est une solution pour la première methode (pas de thread supplémentaire).
Je vais sans doute faire ça, mais j'aurais bien aimé faire la manip avec un thread (pour l'esthétique !).

Reply

Marsh Posté le 22-07-2002 à 11:20:27    

Ton thread il sert à kedal là.... complétement inutile
Si tu veux utiliser un thread il fo que tu mettes ton traitement ds le thread (c-à-d ta boucle !!!) sinon C complétement inutile...
 
 :hello:


Message édité par [SDF]Poire le 22-07-2002 à 11:21:03

---------------
Des bons sites pour Delphi? http://forum.hardware.fr/forum2.php3?post=16838&cat=10 -- informaticien -- http://www.z0rglub.com/phpwebgallery/ -- Delphi :love:
Reply

Marsh Posté le 22-07-2002 à 11:37:53    

Poire : je me suis sans doute mal expliqué :  
 
Le but de la manoeuvre est de faire un ShowModal sur la ProgressForm pour empecher l'utilisateur de faire n'importe quoi avec la forme appelante (dans un programme Windows classique, les ProgressDialog sont Modal). La soluce de ANTP de faire un DISABLE sur la form appelante marche, mais je voudrais faire la manip avec un thread (notes que je vais pas m'entêter 10 ans sachant que j'ai un truc qui marche, mais ça me chagrine de rester sur un semi-echec).
Si on utilise pas de thread, l'appli principale se bloque sur le ShowModal, et donc le traitement de la boucle principale est stoppé.
De plus, le code de la boucle ne peut pas être dans la ProgressForm, sinon il faudrait déclarer une ProgressForm par traitement différent (ce dialog s'affiche pour plusieurs actions, comme des ouvertures des fichiers, des ecritures, des tris, etc...).
Donc, dans le cas décrit plus haut, le thread sert à ce que les clics utlisateurs soient possible sur la ProgressForm. En effet, le ShowModal est appelé par le thread, donc c'est lui qui se bloque et pas l'appli principale qui peut alors continuer sa boucle.
Ca marche bien, mais ça rame à mort.

Reply

Marsh Posté le 22-07-2002 à 12:21:54    

C toi qui me comprend pas
Moi G trés bien compris ce que tu veux faire  :D  
mais t'as pas le droit de faire un thread comme ça  :pt1cable:  
t'execute le thread avec ton traitement (ta boucle) ds ton form1 et t'appel ton form2 en showmodal tjs ds ton form1
ton form1 est bloqué (il attend le résultat du form2) mais C pas grave vu que ton traitement est ds ton thread qui lui n'est pas bloqué
Toi comprendre l'idée ?
 :hello:


---------------
Des bons sites pour Delphi? http://forum.hardware.fr/forum2.php3?post=16838&cat=10 -- informaticien -- http://www.z0rglub.com/phpwebgallery/ -- Delphi :love:
Reply

Marsh Posté le 22-07-2002 à 12:54:36    

Moi y'en a comprendre, mais moi y'en a être un peu nul comparé à toi, alors moi faire toi excuses d'être aussi con.
 
Sauf que le traitement à réaliser ne se trouve PAS et ne peut PAS se trouver dans le thread, parceque sinon faudrait que je déclare 50 threads différents, 1 pour chaque type d'action, et ça c'est pas envisageable ... a moins de faire du CallBack.
Sinon j'comprends bien que c'est la solution idéale.
M'enfin bon, on en restera là.
 
PS : Sachant, et tu l'auras bien compris, que je me tappe que le code de la boucle soit exécuté en parallèle (l'utilisateur doit attendre la fin avant de faire autre chose).


Message édité par vilo76 le 22-07-2002 à 13:20:56
Reply

Marsh Posté le 22-07-2002 à 14:20:48    

Bon, disons donc que tu veux pas faire un thread vu que le traitement doit pas se faire en parallèle, et admettons donc que la solution du disable te plaise pas.
 
Il reste la solution du callback.
 
En fait, quand tu fais ton ShowModal, il ne revient pas tant que la fenêtre n'est pas fermée, ok? Mais ton application n'est pas morte, c'est juste que t'attends un joli évènement.
 
Soit, tu peux donc faire le traitement via ton form modal, ok? Mais tu peux pas le faire dans le form progress ca n'a aucun sens, ok? (Ca devient long pour une réponse en 2 lignes  :sarcastic: )
 
with TForm2.Create(nil) do
try
  OnModal := TaFonction;
  ShowModal;
finally
  Free;
end;
 
T'as plus qu'a définir l'event OnModal dans ton form2, ta fonction qui sera apellée et tu l'apelles dans le Show du form2, et voila une solution à 0.02?  :sweat:  


---------------
Informaticien.be - Lancez des défis à vos amis
Reply

Marsh Posté le 22-07-2002 à 15:29:08    

Bien vu Mr.
Ca tourne nickel (en plaçant le callback dans le OnActivate parceque dans le OnShow le callback se termine avant affichage de la Form2).
 
Tks A+.

Reply

Marsh Posté le 22-07-2002 à 15:50:07    

Attention au OnActivate, il survient chaque fois que la fenêtre prend le focus (donc aussi quand on passe d'un soft à l'autre)


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed