IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Arrêt forcé dans une boucle [FAQ]


Sujet :

C++Builder

  1. #1
    Membre averti
    Inscrit en
    Juin 2005
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 45
    Par défaut Arrêt forcé dans une boucle
    Salut,

    dans mon programme, j'ai un algorithme qui fait 100 000 iterations.

    mais voila, 100 000 iterations, c assez long, et je voudrais que l'utilisateur puisse a tout moment stopper l'algorithme (en appuyant sur une touche par exemple), mais je n'arrive pas du tout!

    Pouvez vous m'aider?

    merci

    jul

  2. #2
    Membre éclairé Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    934
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 934
    Par défaut
    Ce que tu peux faire, c'est utiliser un booléen comme condition de boucle

    tant que ton booléen est faux (ou vrai comme tu veux), tu boucle, sinon tu sors.

    Ensuite il faut définir tes conditions de sortie

    - La première est quand tu as atteint ton nombre d'itération si tu le connais à l'avance.

    - La deuxième est quand la touche de ton choix est frappé.

    lorsque ces conditions survienne, tu change l'état de ton booléen est ansi ton programme sortira.


    Exemple :

    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
     
       bool Sortie = false;   // booléen pour la boucle à déclarer dans la form
     
       // A l'endroit ou tu effectue tes itérations
     
       int i = 0;                  // Indice de boucle
     
       // j'utilise un do while car tu rentres au moin une fois dans ta boucle
       do
       {
                   // Ton code ici
     
                   // Si tu n'as pas atteint ton nombre d'itération
                   if(i < 100000)
                   {
                       // Tu incrémente ton indice de boucle
                       i++;
                   }
                   // Sinon tu as atteint ton nombre d'itération
                   else
                   {
                       // On sort de la boucle
                       Sortie = true;
                   }
       }
       while(!Sortie);
    Ensuite dans l'évènement OnKeyDown ou OnKeyPress, tu effectue ceci, on va supposer pour l'exemple que la touche à presser est ECHAP

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void __fastcall TForm1::OnKeyPress(TObject *Sender, char &Key)
    {
            // Si la touche pressé est ESC
            if(key == VK_ESCAPE)
            {
                    // Alors tu mets ton bolléen de sortie à vrai
                    Sortie = true;
            }
    }

  3. #3
    Membre averti
    Inscrit en
    Juin 2005
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 45
    Par défaut
    merci pour ta reponse, g essayer, il manque encore un ptit truc.

    mon algo est une boucle "for"

    quand je clic sur le Button1 par exemple, je lance mon algo :

    voici ce que g fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    for(i=0;i<100000;i++){
     
    //mon algorithme
     
     
    //et la je voudrais faire : (mais jarrive pas)
    //si la touche ESC est presser i=100000
     
    }
    tu sais comment faire comme sa?

    le probleme avec ta solution, c que tu lui demande jamais d'aller voir si ESC est presser?

    g peut etre pas activer une option!

  4. #4
    Membre éclairé Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    934
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 934
    Par défaut
    Il faut que sur ta form, tu déclare l'évènement OnKeyPress et que dans la méthode associé à l'évènement, tu mette le code de la méthode OnKeyPress de tout a l'heure. Excuse moi j'ai oublié de te préciser qu'il fallait créer l'évènement.

    Pour ta boucle for, tu ne l'utilise plus dans ma solution, tu utilise la strucure do while que je t'ai indiqué. l'incrémentation du i se fait également.

  5. #5
    Membre Expert
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Par défaut
    Avez-vous essayé votre proposition? Pour ma part, j'ai essayé et ça ne marche pas.

    Ce genre de problème est assez difficile car, d'une part, en POO, on ne sort pas si facilement d'un événement et d'autre part, il est difficile pendant un événement de capturer le calvier.

    À bientôt
    Gilles

  6. #6
    Membre averti
    Inscrit en
    Juin 2005
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 45
    Par défaut
    excuse moi mais g encore un pb

    quand je fait juste:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    void __fastcall TForm1::OnKeyPress(TObject *Sender, char &Key) 
    { 
     
            // Si la touche pressé est ESC 
            if(key == VK_ESCAPE) 
            { 
                    Edit1->Text  = "ok";
            } 
    }
    sa ne fait rien du tout, meme quand je lance pas mon algo

  7. #7
    Membre éclairé Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    934
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 934
    Par défaut
    Tu peux essayer d'intercepter l'évènement OnKeyDown à la place de l'évènement OnKeyPress mais je ne sais pas si cela va changer grand chose.

    Gilles, l'énoncé n'a pas changé il demande toujours coment interrompre une boucle

    Citation Envoyé par cquadjul
    //et la je voudrais faire : (mais jarrive pas)
    //si la touche ESC est presser i=100000
    il ne demande pas de réinitialiser l'indice de bouche quand la touche ESC est pressé mais de le forcé a atteindre la bouche supérieur du for, donc de l'arrêter.

  8. #8
    Membre Expert
    Avatar de bakaneko
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 268
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 268
    Par défaut
    Je ne sais pas si ça va solutionner votre problème.
    Vous avez pensé à mettre la propriété KeyPreview de la forme à true pour être sûr que quelque soit l'élément qui est le focus, la fiche reçoive l'évènement clavier...

  9. #9
    Membre Expert
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Par défaut
    Effectivement, quand vous disiez i=100000 en cas d'appui sur une touche, je croyais par erreur qu'il fallait refaire toute la boucle, en fait elle se termine comme vous le demandiez. (reflexe assembleur où l'on procède par décrémentation et non incrémentation).

    Il est très difficile d'intercepter les événements du clavier pendant un événement, à moins de passer par des hooks et je vous souhaite bien du courage.

    J'utilise pour ma part, pour éviter ces usines à gaz, la position de la souris (GetCurPos), qui elle est interrogeable à tout moment, si sa position est modifiée de plus d'un certain nombre de pixels, ça s'arrête.

    C'est quand même un monde qu'on puisse pas savoir à n'importe quel moment, notamment pendant un événement qui exécute une boucle, si une touche a été appuyée par une simple instruction.

    À bientôt
    Gilles

  10. #10
    Membre averti
    Inscrit en
    Juin 2005
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 45
    Par défaut
    oui, je vais passez par la souris, car jarrive vraiement pas autrement
    merci a tous pour votre aide

    bonne soiree

    jul

  11. #11
    Membre Expert
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Par défaut
    Citation Envoyé par bakaneko
    mettre la propriété KeyPreview de la forme à true
    Oui, mais cela ne change rien, on ne peut capter cet événement durant une boucle très longue. Ça marche si par exemple il ne passe rien et que vous appuyiez sur une touche, là, oui, on passera par l'événement de la forme mais si un événement de bouton par exemple comme ici contient une très longue boucle, la boucle est prioritaire et l'événement clavier n'est pas capté, tout le problème est là pour pouvoir interrompre une boucle via la clavier.

    À bientôt
    Gilles

  12. #12
    Membre Expert
    Avatar de bakaneko
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 268
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 268
    Par défaut
    Citation Envoyé par Gilles Louïse
    Citation Envoyé par bakaneko
    mettre la propriété KeyPreview de la forme à true
    Oui, mais cela ne change rien, on ne peut capter cet événement durant une boucle très longue. Ça marche si par exemple il ne passe rien et que vous appuyiez sur une touche, là, oui, on passera par l'événement de la forme mais si un événement de bouton par exemple comme ici contient une très longue boucle, la boucle est prioritaire et l'événement clavier n'est pas capté, tout le problème est là pour pouvoir interrompre une boucle via la clavier.

    À bientôt
    Gilles
    Je ne savais pas comment l'évènement réagissé pendant une boucle longue.
    Merci pout l'information.

  13. #13
    Membre éclairé Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    934
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 934
    Par défaut
    Essaye, en mettant un Application->ProcessMessages(); juste avant le do et un juste avant le while.

    Moi dans une de mes applications, je devais interrompre la lecture d'une vidéo. J'ai donc fait un while sur un booléen et intercepter un évènement clavier et cela fonctionne correctement avec les ProcessMessages.

  14. #14
    Membre averti
    Inscrit en
    Juin 2005
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 45
    Par défaut
    Alors là, tu es vraiment trop fort.
    C'est excellent ton truc.

    Merci beaucoup, on peut tout intercepter !!!

    MERCI ET VIVE LES Application->ProcessMessages();

    ++

    JUL

  15. #15
    Membre Expert
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Par défaut
    Très joli en effet, ça marche très bien, un test aura ainsi fatalement lieu après chaque itération.

    La question a souvent été posée mais seuls des hooks ont été proposés, ce qui me paraissait très lourd comme solution.

    J'espère qu'on mettra votre solution dans la FAQ, ce serait très bien.

    Merci à vous et à bientôt
    Gilles

  16. #16
    Membre éprouvé

    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 163
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 163
    Par défaut
    +1 pour le Application->ProcessMessages.
    Cette fonction est souvent à utiliser dans le cas de longues boucles, par exemple si on a une barre de progression cela permet de rafraîchir l'affichage.
    Ici le problème c'est que ton programme est dans la boucle et ne traite rien d'autre (pas même les messages windows) pendant ce traitement.

    Autre avantage de Application->ProcessMessages : cela évite que Windows croit que ton application est bloquée (le petit (Ne répond pas) à côté du nom de ton application dans le gestionnaire de tâches)...

    Bref que du bon et à utiliser donc !

  17. #17
    Membre éclairé Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    934
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 934
    Par défaut
    De rien, contant que cela est pu t'aider cquadjul

    Dans mon exemple de départ, je les avait oublié, désolé.

    Gilles, si ca peu aidé de le mettre dans la faq, cela ne me pose aucun problème.

  18. #18
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Il ne serait pas intéressant de traiter l'algo dans un thread ?
    Ca n'enlève bien sur pas l'intérêt du ProcessMessages
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  19. #19
    Membre éclairé Avatar de kurul1
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    934
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 934
    Par défaut
    Ca semble possible mais
    d'une part tu va avoir ta boucle et de l'autre ton timer. il n'y aura pas de synchronisation entre les 2. Alors que si tu effectue le teste à chaque itération de ta boucle, sa semble plus judicieux.

    Mais rien ne t'empêce d'essayer.

  20. #20
    Membre Expert
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Par défaut
    Citation Envoyé par kurul1
    Gilles, si ca peut aider de le mettre dans la faq, cela ne me pose aucun problème.
    Merci à vous.

    Étant donné que la question a souvent été posée, je crois qu'un petit paragraphe s'impose sur ce sujet.

    Pour ma part, je connaissais l'instruction Application->ProcessMessages() mais je ne l'utilisais qu'isolément dans mon code. Ici, la nouveauté, et c'est pourquoi je n'y avais pas pensé, c'est que cette instruction s'insère dans une boucle. On écrit cette instruction juste avant le test de fin de boucle (quel que soit le type de boucle, do, while ou for), ce qui permet de libérer les interruptions clavier. Il se peut qu'il y ait aussi à coupler cette instruction avec la propriété KeyPreview de Form1 de manière à faire ce traitement spécifique ici car parfois on ne sait pas très bien quel composant a le focus et plusieurs sont susceptibles de l'avoir. En mettant KeyPrevieiw de Form1 à true, on oblige l'interruption à passer par les événements clavier de Form1.

    À bientôt
    Gilles

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [langage] incrementation de variable dans une boucle
    Par mimilou dans le forum Langage
    Réponses: 15
    Dernier message: 16/04/2004, 13h23
  2. Problème avec TNMSMTP dans une boucle.
    Par Orgied dans le forum Web & réseau
    Réponses: 3
    Dernier message: 07/04/2004, 10h19
  3. swf dans une boucle asp
    Par Chucky69 dans le forum Flash
    Réponses: 11
    Dernier message: 10/02/2004, 17h07
  4. [Vb.net] Indexé un objet crée dans une boucle
    Par picpic dans le forum Windows Forms
    Réponses: 10
    Dernier message: 17/12/2003, 14h37
  5. Pause dans une boucle
    Par HT dans le forum Langage
    Réponses: 4
    Dernier message: 03/06/2003, 08h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo