Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
765 connectés 

  FORUM HardWare.fr
  Programmation
  Delphi/Pascal

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

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

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

n°179759
vilo76
Posté le 22-07-2002 à 10:10:28  profilanswer
 

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 ?

mood
Publicité
Posté le 22-07-2002 à 10:10:28  profilanswer
 

n°179767
antp
Super Administrateur
Champion des excuses bidons
Posté le 22-07-2002 à 10:30:09  profilanswer
 

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
n°179778
vilo76
Posté le 22-07-2002 à 10:48:27  profilanswer
 

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 !).

n°179806
[SDF]Poire
Vive Grumly
Posté le 22-07-2002 à 11:20:27  profilanswer
 

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:
n°179831
vilo76
Posté le 22-07-2002 à 11:37:53  profilanswer
 

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.

n°179875
[SDF]Poire
Vive Grumly
Posté le 22-07-2002 à 12:21:54  profilanswer
 

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:
n°179895
vilo76
Posté le 22-07-2002 à 12:54:36  profilanswer
 

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
n°179942
zion
Plop
Posté le 22-07-2002 à 14:20:48  profilanswer
 

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
n°180003
vilo76
Posté le 22-07-2002 à 15:29:08  profilanswer
 

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+.

n°180038
antp
Super Administrateur
Champion des excuses bidons
Posté le 22-07-2002 à 15:50:07  profilanswer
 

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

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Delphi/Pascal

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

 

Sujets relatifs
comment envoyer un mail ds une appli delphi[delphi] probleme avec &
[Delphi] Hmm, impossible de faire un always on top !![Delphi]¨DBgrid affichage de champs ?
[Delphi]"Demarree en"??[Delphi] pourquoi les TPanel n'ont pas de Tcanvas ??
[Delphi] Active X (media player), qui marche paaaas..... help SVPest ce que je pêut vendre mon logiciel fait sous delphi 6 ?
[DELPHI / ALGO] Antialiasing [Done mais besoin d'avis][Delphi] TShellTreeView, comment forcer un répertoire ? (résolu)
Plus de sujets relatifs à : [Delphi] Progress Dialog + Cancel => solutions dispo ...


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR