Comment sortir d'une boucle avec clic sur un bouton Cancel?
rolanddegilead1
Messages postés1Date d'inscriptionvendredi 7 janvier 2005StatutMembreDernière intervention23 janvier 2005
-
23 janv. 2005 à 12:12
cs_LordBob
Messages postés2865Date d'inscriptionsamedi 2 novembre 2002StatutMembreDernière intervention11 mai 2009
-
23 janv. 2005 à 14:48
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
#include
#include
//=========================================================================================
//#define UNICODE //make active when compiling on WinNT/2000 (W-fns)
#define WIN32_LEAN_AND_MEAN //optional: no MFC
#include //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
//=========================================================================================
//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);
}
//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
}
}
//=========================================================================================
A voir également:
Comment sortir d'une boucle avec clic sur un bouton Cancel?
simtiers
Messages postés207Date d'inscriptionjeudi 3 avril 2003StatutMembreDernière intervention 2 novembre 2006 23 janv. 2005 à 13:24
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.
cs_LordBob
Messages postés2865Date d'inscriptionsamedi 2 novembre 2002StatutMembreDernière intervention11 mai 20099 23 janv. 2005 à 14:48
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..."