begin process at 2012 05 28 21:48:16
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Au secours

 > 

Comment sortir d'une boucle avec clic sur un bouton Cancel?


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Comment sortir d'une boucle avec clic sur un bouton Cancel?

dimanche 23 janvier 2005 à 12:12:09 | Comment sortir d'une boucle avec clic sur un bouton Cancel?

rolanddegilead1

Bonjour,
je suis debutant et je m'arrache les cheveux depuis presque une semaine a cause d'un truc tout bete: en gros je cree une fenetre avec 2 boutons, ok et cancel, et le bouton ok lance une fonction boucle que je voudrais pouvoir arreter avec le bouton cancel.
Comme vous allez le voir dans mon code, (j'utilise devc++), j'essaie de lui faire lire les messages de la fenetre principale avec getmessage au milieu de la boucle mais rien a y faire...

Merci par avance de vos lumieres, voici donc le code:
#include <stdlib.h>
#include <time.h>
#include <stdio.h>

//=========================================================================================
//#define UNICODE         //make active when compiling on WinNT/2000 (W-fns)
#define WIN32_LEAN_AND_MEAN //optional: no MFC
#include <windows.h>        //include all the basics
#if defined __MINGW_H
#define _WIN32_IE 0x0400
#endif
//DevC++(MinGW) must link with -lcomctl32. bcc5.5,msvc (must link with comctl32.lib)
#include <commctrl.h>
//=========================================================================================
//LCC-WIN32 Specific: LR_SHARED (used by LoadImage API function) is currently not defined
//in WIN.H. If you have a later version of this lcc-win32 header that defines LR_SHARED
//then you may safely discard the following conditional definition.
#if !defined LR_SHARED
#define LR_SHARED 0x00008000   //required only for lcc-win32 (Aug 2002)
#endif
//=========================================================================================

 

 


//declare the Window procedure where all messages will be handled
LRESULT CALLBACK WndProc(HWND hwnd,UINT Message,WPARAM wParam,LPARAM lParam);

//declaration de la boucle
BOOL clickatemps(int n,WPARAM wParam,LPARAM lParam);


//declare some global variables
HINSTANCE g_hInst;          //application instance

int n;

HDC hdc;/* A device context used for drawing */
PAINTSTRUCT ps;/* Also used during window drawing */
RECT rc;/* A rectangle used during drawing */
TEXTMETRIC tm;
static HWND hwndButton = 0;
static HWND hwndButtonCl = 0;
static int cx, cy;/* Height and width of our button. */
static HWND hCntrl;    //handle of static control(s)


int flagbcl = 0, flagbreak = 0;
MSG     Msg;      //a simple structure for storing message information
   
//=========================================================================================
//start the application; all win32 applications require a WinMain function
//that the windows operating system looks for as an entry point to that application
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
HWND    hwnd;     //the wnd handle
//MSG     Msg;      //a simple structure for storing message information
HICON   hIcon;    //window icon
HCURSOR hCursor;  //window cursor
//declare and initialise wnd registration information variables
TCHAR chClassName[]=TEXT("SIMPLEWND");
WNDCLASSEX wcx;    //this structure is used for storing information about the wnd 'class'
g_hInst=hInstance; //store the application instance
//use 'LoadImage' to load wnd class icon and cursor as it supercedes the obsolete functions
//'LoadIcon' and 'LoadCursor', although these functions will still work. Because the icon and
//cursor are loaded from system resources ie they are shared, it is not necessary to free the
//image resources with either 'DestroyIcon' or 'DestroyCursor'.
hIcon=(HICON)LoadImage(0,IDI_APPLICATION,IMAGE_ICON,0,0,LR_SHARED);
hCursor=(HCURSOR)LoadImage(0,IDC_ARROW,IMAGE_CURSOR,0,0,LR_SHARED);
wcx.cbSize           = sizeof(WNDCLASSEX);              //byte size of WNDCLASSEX struct
wcx.style            = CS_HREDRAW|CS_VREDRAW;           //ensure wnd is always redrawn
wcx.lpfnWndProc      = (WNDPROC)WndProc;                //pointer to the Window Procedure
wcx.cbClsExtra       = 0;                               //Extra bytes for 'class' wnds
wcx.cbWndExtra       = 0;                               //Extra bytes for this wnd
wcx.hInstance        = hInstance;                       //Application instance
wcx.hIcon            = hIcon;                           //Application icon
wcx.hCursor          = hCursor;                         //Cursor for wnd
wcx.hbrBackground    = (HBRUSH)(COLOR_BTNFACE+1);       //Background wnd colour
wcx.lpszMenuName     = NULL;                            //Name of wnd menu
wcx.lpszClassName    = chClassName;                     //Name of this wnd 'class'
wcx.hIconSm          = NULL;                            //Icon in top-left corner of wnd
//Register the wnd class with the Windows system
if (!RegisterClassEx(&wcx))
    {
    //Registration has failed so inform the user
    MessageBox( NULL,
                TEXT("Failed to register wnd class"),
                TEXT("ERROR"),
                MB_OK|MB_ICONERROR);
    return FALSE;
    }
//create wnd of the 'class' just registered
hwnd=CreateWindowEx(0,                                  //more or 'extended' styles
                    chClassName,                        //the 'class' of window to create
                    TEXT("demo simple d'arret d1 boucle"),//the window title
                    WS_CAPTION|WS_SYSMENU,
//                    WS_OVERLAPPEDWINDOW,                //window style: how it looks
                    GetSystemMetrics(SM_CXSCREEN)/4,    //window position: left
                    GetSystemMetrics(SM_CYSCREEN)/4,    //window position: top
                    500, //window width
                    250, //window height
                    NULL,                               //parent window handle
                    NULL,                               //handle to this windows's menu
                    hInstance,                          //application instance
                    NULL);                              //user defined information
if (!hwnd)
    {
    //wnd creation has failed so inform the user 
    MessageBox( NULL,
                TEXT("Failed to create wnd"),
                TEXT("ERROR"),
                MB_OK|MB_ICONERROR);
    return FALSE;
    }
//Display the wnd
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
//start message loop
while (GetMessage(&Msg,NULL,0,0)>0)
    {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
    }

return Msg.wParam;
}

 

BOOL clickatemps(int n,WPARAM wParam,LPARAM lParam,HWND hwnd)
{
        BOOL fdone;
        //MSG Msg;
        
        fdone = FALSE;
        n = 0;
                  while(n < 30)
                         {
                        
                         Sleep(1000);
                         n++;
                        
                         //sprintf(string,"%g",inter);
                         //SendMessage(hCntrl, WM_SETTEXT, (WPARAM) 0, (LPARAM) &string);
                         //GetMessage( &Msg, NULL, 0, 0 );
                         PeekMessage(&Msg, hwnd,  0, 0, PM_REMOVE);
                         if (LOWORD(wParam) == 2 && HIWORD(wParam) == BN_CLICKED && (HWND) lParam == hwndButtonCl)
                            {
                                       //DestroyWindow (hwnd);
                                       //break;
                                         fdone = FALSE;
                                         return fdone;
                            }
                        
                         }
  fdone = TRUE;
  return fdone;  
}

 

 

//=========================================================================================
LRESULT CALLBACK WndProc(HWND hwnd,UINT Message,WPARAM wParam,LPARAM lParam)
{
 BOOL fDone;
 MSG Msg;
switch (Message)
    {
    case WM_CREATE:
        {

 
        //first load in the common controls dll, specifying the date and time picker control wnd class
        INITCOMMONCONTROLSEX iccx;
        iccx.dwSize=sizeof(INITCOMMONCONTROLSEX);
        iccx.dwICC=ICC_DATE_CLASSES ;
        InitCommonControlsEx(&iccx);
       

              /* First we use the system fixed font size to choose
         * a nice button size. */
        hdc = GetDC (hwnd);
        SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
        GetTextMetrics (hdc, &tm);
        cx = 100;
//        cx = tm.tmAveCharWidth * 30;
        cy = (tm.tmHeight + tm.tmExternalLeading) * 2;
        ReleaseDC (hwnd, hdc);
       
        /* Now create the button OK */
        hwndButton = CreateWindow (
                "button",/* Builtin button class */
                 "OK",
                 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                 140, 140, cx, cy,
                 hwnd,/* Parent is this window. */
                 (HMENU) 1,/* Control ID: 1 */
                 ((LPCREATESTRUCT) lParam)->hInstance,
                 NULL
                 );                                    
        /* Now create the button CANCEL*/
        hwndButtonCl = CreateWindow (
                "button",/* Builtin button class */
                 "Cancel",
                 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                 260, 140, cx, cy,
                 hwnd,/* Parent is this window. */
                 (HMENU) 2,/* Control ID: 2 */
                 ((LPCREATESTRUCT) lParam)->hInstance,
                 NULL
                 );
       
        return 0;
        break;
        }

 

 

       case WM_DESTROY:
        {
        PostQuitMessage(0);    //signal end of application
        return 0;
        }


/* The window needs to be painted (redrawn). */
       case WM_PAINT: 
       {
        hdc = BeginPaint (hwnd, &ps);
        GetClientRect (hwnd, &rc);
        SetBkMode(hdc,TRANSPARENT);

         rc.left = 0;
         rc.top = 70;
         rc.right = 500;
         rc.bottom = 130;
         DrawText (hdc, "quand on clique sur OK \n une boucle compteur se lance\n et on doit pouvoir l'interrompre avec le bouton Cancel", -1, &rc, DT_CENTER | DT_VCENTER);

         EndPaint (hwnd, &ps);
        return 0;
        }


        case WM_COMMAND:
        {
        /* Check the control ID, notification code and
         * control handle to see if this is a button click
          * message from our child button. */

          if (LOWORD(wParam) == 1 && HIWORD(wParam) == BN_CLICKED && (HWND) lParam == hwndButton)
             {
                  if (flagbcl == 0)
                  {

                   
                    flagbcl = 1; // on previent qu' on rentre dans la boucle


                    fDone = FALSE;
                   
                    while (!fDone)
                    {
                          fDone = clickatemps(flagbcl,wParam,lParam,hwnd);
                   
                              while (PeekMessage(&Msg, hwnd,  0, 0, PM_REMOVE));         
                              {
                                    switch(Msg.message)
                                    {
                                          case WM_LBUTTONDOWN:
                                          case WM_RBUTTONDOWN:    
                                          case WM_KEYDOWN:
                                          DestroyWindow (hwnd);
                                    }
                              }
                    }               
 
                    //Our button was clicked. Close the window.
                    DestroyWindow (hwnd);

                  }
                 
                  }                       
                  return 0;
                  break;
                  }
                 
                 

    default:
        return DefWindowProc(hwnd,Message,wParam,lParam);  //let system deal with msg
    }
}
//=========================================================================================

 

dimanche 23 janvier 2005 à 13:24:50 | Re : Comment sortir d'une boucle avec clic sur un bouton Cancel?

simtiers

Oula, avec toutes ces boucles, ton programme risque de ramer sévère

Pour pouvoir recevoir un message alors qu'une boucle est en cours, il faut utiliser les threads, c'est le plus simple. D'autre part, je ne vois pas où tu as mis ton compteur.

Il faut que tu crées une fonction de la forme DWORD WINAPI MonCompteur( void* parametres ), c'est le prototype des fonctions à lancer par un thread.
Ensuite, crées ta boucle de compteur dans cette fonction avec :
while( !BoutonCancelClique ) { ... }
[...]
return 0; => on retourne un DWORD quelconque

Tu dois donc définir la variable bool  BoutonCancelClique  en variable globale.

Dans la WndProc, dans le WM_COMMAND, si tu reçois le message comme quoi le bouton Cancel a été cliqué, alors tu met la variaible BoutonCancelClique à true, ce qui aura pour effet d'arrêter ta boucle dans le thread, qui se terminera alors tout seul (comme un grand )

Pour épurer ton programme :
* supprime la boucle que tu as mis dans le WM_COMMAND, elle ne sert à rien d'autre qu'à bloquer le programme.
* Supprime ta fonction clickatemps, on va dire que tu la remplace par MonCompteur.

Voilà, ça doit être tout.

dimanche 23 janvier 2005 à 14:48:47 | Re : Comment sortir d'une boucle avec clic sur un bouton Cancel?

LordBob

Membre Club
j'ai pas regarder ton code, mais si tu veux sortie d'une boucle avec un bouton, l'idée qui me vient, ca serait de lancer un thread (voir source sur le site), qui executera ta/tes boucles et ensutie quand tu cliques sur le bouton, bah tu arretes de thread
Bob...

"La chance accorde ses faveur aux esprits avertis..."


Cette discussion est classée dans : hwnd, window, msg, wparam, lparam


Répondre à ce message

Sujets en rapport avec ce message

transcodage arabe anglais [ par elmarokinho ] bonjour, je suis en DUT 2e année ... je dois réaliser un projet pr la mi-mars  ;:realisation d'un logiciel de transcodage anglais/arabe ...<br Je trouve pas le bon code [ par vah bi ] Bonjour à tous , voilà je débute en c et comme editeur j'ai le visual c++.Je  fais actuellement une application avec l'api de visual c++  mais en lang Comment faire pour re_afficher un dialogue apres "RedrawWindow" API sous DEV cpp [ par LouisJean ] louisjean dev cpp Bonjours a tous!Comment faire pour remontrer le dialogue "Mon_DIALOG" en API wind32 sous DEV Problème sous-classement [ par Albanderuaz ] Bonjour !J'ai un petit problème avec ce code qui est censé, grâce à un sous-classement, modifier le texte de tous les boutons grâce à un hook global. Créer sa classe OpenGL [problème pointeur de fonction membre] [ par Mickatronic ] Bonjour, je réalise un projet tutauré en C++, dans ce projet je dois créer une classe qui va me permettre de généré la fenêtre OpenGl. Comme je savais souci bouton C++ [ par Tom56340 ] bonjours voila j'ai un couci l'or de mon compile run j'ai mi un bouton donnée un non ect.. donner une valuer a ID_BOUTON "1"; mais cela ne marche c++ API Windows : sous classement de fenetre dans une classe [ par _Jonathan ] Bonjour, je cherche à créer un controle de type Edit en utilisant une classe. Le probleme, c'est que je souhaite redéfinir la procedure callback du co Sous classement foireux [ par HeavenForsaker ] Mon sous classement n'a pas l'air de fonctionner correctement, je voudrais receptionner le message WM_MOVING lors du déplacement de ma fenêtre. Voila Win32 problème. [ par TeniX ] Salut, Voila j'ai crée de maniere simple une source qui exprime mon problème , je trouve pas la source du problème , enfaite quand les fenêtres sont l


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,764 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales