none
arrêter boucle while(1) via un bouton en c++ RRS feed

  • Question

  • bonjour,

    j´utilise c++express 2010. Avec un button1, je démarre une boucle while(1). Comment sortir de la boucle avec un button2? Est-ce que quelqu´un a un exemple de programmation?

    merci

     

    mercredi 18 mai 2011 13:45

Réponses

  • J'ai oublié de vous dire qu'il faut ajouter quelques librairies pour compiler:

    #include <windows.h>
    #include <winbase.h>
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <process.h>
    #include <time.h>
    #include <io.h>
    #include <fcntl.h>
    #include <sys\types.h>
    #include <sys\stat.h>
    #include <time.h>
    #include <SYS\TIMEB.H>

    #include <winioctl.h>
    #include <Mmsystem.h> 


    Delphine GARRO
    • Marqué comme réponse charly_67160 vendredi 20 mai 2011 17:05
    jeudi 19 mai 2011 08:23

Toutes les réponses

  • Tant que vous êtes à l'intérieur de votre fonction bouton, l'utilisateur ne pourra pas appuyer sur un autre bouton car ce dernier garde le focus...

     

    Procédure à suivre:

    Lorsque vous appuyer sur le premier bouton, vous lancer un thread qui va éxécuter ce while(1) et vérifier l'état d'une variable qui va permettre d'interrompre la boucle infinie. Lorsque vous appuyer sur le second bouton, vous changer l'état de cette variable pour sortir de cette boucle infinie.

     

    Pour la création des threads, lire l'article :

    http://social.msdn.microsoft.com/Forums/fr-FR/visualcplusfr/thread/f71c3811-b8b3-4071-8965-c7312ac6214b

     

    EXEMPLE:

     

    bool ATTENTE_Active;

    bool ThreadP201_Actif=false

    HANDLE P201;

    DWORD ID_P201, SansArgument;

     

    void FonctionBOUTON_1( void ) // La fonction appelée lors de l'appuie de votre bouton 1

    {

    ATTENTE_Active=true;

    P201= CreateThread( NULL, 0, SpATTENTE,&SansArgument,0 ,&ID_P201);

    }

    void FonctionBOUTON_2( void ) // La fonction appelée lors de l'appuie de votre bouton 2

    {

    ATTENTE_Active=false;

    }

     

    // ===========================================

    DWORD WINAPI SpATTENTE( LPVOID Param )

    {

     ThreadP201_Actif=true; //Variable générale qui indique que votre thread est actif et chargé en mémoire

     

     while( ATTENTE_Active)

     {

     // *******************************************************

     //Insérer votre fonction 

    Sleep(100); // par exemple.... Attente de 100ms

     

     // *******************************************************

    }

    // Fin du thread :

    ThreadP201_Actif=false;

     

    ExitThread( 0 );

    return 0;

     

    }


    Delphine GARRO
    mercredi 18 mai 2011 16:15
  • Bonjour Delphine,

    Merci d´avoir répondu. Je ne m´y connais pas du tout en c++ mais c´est le seul language commun de deux composants possible dans une application Siemens. L´erreur suivante est affichée: 

    error C3867: "thread::Form1::SpATTENTE": Dem Funktionsaufruf fehlt die Argumentliste. Verwenden Sie "&thread::Form1::SpATTENTE", um einen Zeiger auf den Member zu erstellen.

    et pointe sur la ligne:

    P201= CreateThread( NULL, 0, SpATTENTE, &SansArgument,0 ,&ID_P201);

    

    jeudi 19 mai 2011 06:56
  • J'ai oublié de vous dire qu'il faut ajouter quelques librairies pour compiler:

    #include <windows.h>
    #include <winbase.h>
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <process.h>
    #include <time.h>
    #include <io.h>
    #include <fcntl.h>
    #include <sys\types.h>
    #include <sys\stat.h>
    #include <time.h>
    #include <SYS\TIMEB.H>

    #include <winioctl.h>
    #include <Mmsystem.h> 


    Delphine GARRO
    • Marqué comme réponse charly_67160 vendredi 20 mai 2011 17:05
    jeudi 19 mai 2011 08:23
  • Du multi-therading juste pour ça ?

    C'est un peu overkill.

    Primo, ne jamais faire de boucle active, donc jamais de while(1).

    Sur les systèmes évènementiels type Windows, tous programme graphique doit avoir une pompe à message :

     

    MSG msg;
    while(GetMessage(&msg, hwnd, 0, 0))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    
     
    
      // do stuff
    
    }
    
    
    
     
    

    Sans attente active et avec une pompe à message l'interface réagit à chaque évènement.

    Il reste donc le "pourquoi" faire une attente active.


    Paul Bacelar, Ex - MVP VC++
    jeudi 19 mai 2011 08:59
    Modérateur
  • Bonjour,

    votre solution m´intéresse aussi mais étant donné que je suis nul en c++, il faut être un peu plus précis. J´ai un Forms sur lequel se trouve un bouton start et bouton stop et j´ai un petit programme scan() dans lequel se trouve la boucle while. Je ne peux pas utiliser le mode console

    charly

    jeudi 19 mai 2011 14:10
  • Le C++ n'est qu'un langage, et dans ce langage "Forms" n'existe pas.

    Si votre code compile c'est que du code (le votre ou celui d'une librairie que vous utilisez) défini cette classe.

    Donc le problème n'est pas C++ mais lié au Framework (ensemble de librairie conçu pour travailler de concert) que vous utilisez.

    Si vous avez réussi à afficher une fenêtre avec des boutons sans implémenter une pompe à message, c'est que vous utilisez un Framework graphique comme les MFC, WTL ou les Winform etc.

    Chacun de ces Framework travail de manière différentes mais généralement contiennent tous les outils pour faire des tâches aussi simple que de réagir à des clicks sur un bouton.

    Mais une attente active rend toujours vain les efforts faits par ces librairies pour simplifier les cas d'usages simples.

    Donc quel Framework graphique utilisez-vous ?

    Il faudra transformer votre boucle active en un code évènementiel, qui réagit à des évènements plutôt que les attendre. Sinon c'est le multi-threading avec tous les problèmes de partage et de transfert de données entre thread et d'impossibilité d'accès multi-threadé sur les contrôles Windows.


    Paul Bacelar, Ex - MVP VC++
    jeudi 19 mai 2011 14:51
    Modérateur
  • Bonjour,

    Je suis automaticien, je ne suis pas spécialiste du c+++,je dois résoudre ce point précis, j´utilise c++ espress 2010/Windows forms application

    public

     

    : System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)

    {

    pos = 0;

     

     

    while

    (??????????????)

     

    {

    rc = ad_poll_scan_state (adh, &state);

     

     

    if

    (!(state.flags & AD_SF_SCANNING))

     

     

    break

    ;

    rc = ad_get_sample_layout (adh, 0, &layout);

     

     

     

    if

    (pos < layout.start)

    pos = layout.start;

     

     

     

    for

    ( ; pos < (layout.start+layout.prehist_samples+layout.posthist_samples); pos++)

    {

    fprintf (fp,

     

    "%s %d", pos < (layout.start+layout.prehist_samples) ? "": "", (unsigned

    ) pos);

     

     

    for

    (j = 0; j < CHAC; j++)

    {

    nval = 1;

    ad_get_samples_f (adh, j, AD_STORE_DISCRETE, pos, &nval, &val);

    fprintf (fp,

     

    " %8.3f", val);

    // // impression fichier: imprime valeurs canal 1 & 2

     

    }

     

     

    //printf ("\n"); // affichage sur console

    fprintf(fp,

     

    " \n"

    );

     

     

     

     

     

    }

     

     

    }

    private

     

    : System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)

    {

     

    // par action sur ce bouton, sortir de la boucle while

    }

    vendredi 20 mai 2011 09:51
  • Windows Forms = WinForms

    C'est pas du C++ mais du C++/CLI. C'est comme si vous confondiez C et C++.

    Votre code est truffé de d'archaïsmes C. C'est déjà pas très beau en C++ mais en C++/CLI c'est encore pire.

    Si vous voulez être cohérent, soit vous utilisez un framework graphique C comme un projet Win32, soit vous mettez à niveau votre code pour utiliser les classes de stream de .NET (C++/CLI) et non des fprintf d'y a 40 ans.

    Cette mise en cohérence n'est pas obligatoire, mais pour la fiabilité et la maintenabilité de votre code, cela serait bien mieux. Le compilateur pourra aussi vous envoyer balader si vous continuez avec ces archaïsmes.

    Vérifiez que la bibliothèque que vous utilisez (LIBAD4 selon Google ;-) ) ne dispose pas d'une API orientée événements/callback.

    Si elle existe, cela sera nettement plus simple à utiliser.


    Paul Bacelar, Ex - MVP VC++
    vendredi 20 mai 2011 12:35
    Modérateur