begin process at 2012 02 05 05:17:28
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

API

 > BOÎTE DE DIALOGUE DE PROGRESSION AVEC ANNULATION

BOÎTE DE DIALOGUE DE PROGRESSION AVEC ANNULATION


 Information sur la source

Note :
9 / 10 - par 2 personnes
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :API Classé sous :Progress, Dialog, Progressbar, Pourcentage, Annulation Niveau :Débutant Date de création :27/08/2008 Vu / téléchargé :5 567 / 254

Auteur : racpp

Ecrire un message privé
Commentaire sur cette source (7)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Ce code source montre comment réaliser une boîte de dialogue contenant une ProgressBar permettant de suivre la progression d'une tâche exécutée par l'application avec la possibilité de l'annuler en cliquant sur un bouton ou en appuyant sur la touche Echap.  Grâce à l'interception du message WM_WINDOWPOSCHANGED, on sait que notre boîte de progression vient d'être affichée juste après sa création. On appelle alors la fonction exécutant la tâche dont on veut voir l'évolution. Elle prend en paramètre le HWND de la ProgressBar et celui du bouton d'annulation. Le premier lui permet de mettre à jour la position de la ProgressBar. Le second sert à retrouver l'état du drapeau d'annulation stocké comme attribut USERDATA du bouton. Il est mis à 1 suite à un clic sur le bouton d'annulation ou après appui sur la touche Echap ou Entrée. Pour ne pas blocker la boîte de dialogue, cette fonction doit appeler, après chaque étape de la tâche exécutée, une autre fonction permettant de traiter les messages qui lui sont destinés et effacer de la pile tous ceux destinés à sa boîte mère. Ainsi, cette dernière ne pourra plus réagir aux actions (clics etc) qui resteraient dans la pile des messages. Notre fonction d'exécution de la tâche vérifiera ensuite l'état du drapeau d'annulation. S'il est à 1, on arrête la tâche et retourne, sinon on continue avec l'étape suivante. Au retour de cette fonction, la boîte se ferme.
La ProgressBar utilisée est personnalisée afin d'afficher le pourcentage dans la barre de progression. Pour cela, le contrôle est sous-classé et sa zone cliente est entièrement dessinée pendant le traitement du message WM_PAINT.
Ce code est réalisé sous Visual C/C++ 2005 en Win32 API. Ce qui le rend utilisable avec les autres compilateurs.
Pour tester l'exécutable, renommez le en ProgressDialig.exe
Vos remarques, questions ou commentaires sont les bienvenus.

Source

  • #include <windows.h>
  • #include <commctrl.h>
  • WNDPROC OldProgressBarProc;
  • // Structure de récupération des données d'une ProgressBar:
  • typedef struct
  • {
  • HWND hwnd;
  • DWORD dwStyle;
  • INT iMin;
  • INT iMax;
  • INT iPos;
  • INT iStep;
  • HFONT hfont;
  • COLORREF bkcolor;
  • COLORREF barcolor;
  • } PRODATA;
  • // Cette fonction vide la pile des messages de la fenêtre parente de notre boîte de dialogue
  • // afin de l'empêcher de réagir aux actions survenues pendant la progression.
  • // Elle permet aussi d'intercepter le clic sur le bouton "Annuler" et l'utilisation de la touche Echap et Entrée.
  • void TraiterMessages(HWND hwnd)
  • {
  • MSG msg;
  • // Enlever tous les messages destinés aux fenêtres de l'application:
  • while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  • {
  • // Utiliser la fonction IsDialogMessage() pour permmetre à notre boîte de réagir aux actions clavier:
  • if(!IsDialogMessage(hwnd, &msg))
  • {
  • TranslateMessage(&msg);
  • DispatchMessage(&msg);
  • }
  • }
  • }
  • // Fonction exécutant une boucle de simulation d'une tâche en progression:
  • int ProgressFunction(HWND hdlg, HWND progress, HWND cancel)
  • {
  • // Mettre l'attribut USERDATA du bouton "Annuler" à 0:
  • SetWindowLong(cancel,GWL_USERDATA,0);
  • int i;
  • // Lancer la boucle pour simuler une progression:
  • for(i=0;i<3000000;i++)
  • {
  • // Mettre à jour la position de la ProgressBar:
  • SendMessage(progress,PBM_SETPOS,i/30000,0);
  • // Autoriser le traitement des messages de notre boîte de progression:
  • TraiterMessages(hdlg);
  • // Sortir de la boucle si l'attibut USERDATA du bouton Annuler est à 1 suite à un clic ou un appui sur Echap ou Entrée:
  • if (GetWindowLong(cancel,GWL_USERDATA))break;
  • }
  • // Retourner la dernière valeur de i:
  • return i;
  • }
  • // Fonction de conversion de la position de la ProgressBar en chaîne contenant un pourcentage:
  • int utoa(UINT nombre, char* buf, char car)
  • {
  • // retour immédiat si buf est null:
  • if(!buf) return 0;
  • char tampon[12];
  • char* ptampon = tampon;
  • char* pbuf=buf;
  • UINT i;
  • // Boucle de conversion en caractères:
  • do
  • {
  • i=nombre%10;
  • nombre=nombre/10;
  • *ptampon=i+'0';
  • ptampon++;
  • }while(nombre);
  • // Boucle de transfert des caractères, à l'envers, vers le buffer destination:
  • while (ptampon > tampon)
  • {
  • ptampon--;
  • *pbuf=*ptampon;
  • pbuf++;
  • }
  • // Ajouter le symbole donné en 3è paramètre de la fonction (ici %):
  • *pbuf = car;
  • // Mettre le 0 final de la chaîne:
  • pbuf++;
  • *pbuf = 0;
  • // Retourner la longueur de la chaîne:
  • return pbuf-buf;
  • }
  • // Procédure de sous-classement de notre ProgressBar:
  • LRESULT CALLBACK ProgressBarProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  • {
  • if (message == WM_PAINT)
  • {
  • PAINTSTRUCT ps;
  • RECT clientrect, leftrect, rightrect, textrect;
  • char buffer[12];
  • // Obtenir le HDC de la ProgressBar:
  • HDC hdc = BeginPaint(hwnd, &ps) ;
  • // Récupérer les données de la ProgressBar:
  • PRODATA* pdata=(PRODATA*)GetWindowLong(hwnd,0);
  • // Obtenir le rectangle de la zone cliente de la ProgressBar:
  • GetClientRect(hwnd, &clientrect);
  • // Obtenir la position courante de la barre:
  • UINT position = pdata->iPos;
  • // Calculer et définir les rectangles gauche et droit correspondant respectivement à la partie pleine et vide de la ProgressBar:
  • leftrect=rightrect=clientrect;
  • leftrect.right =MulDiv(clientrect.right,position,100);
  • rightrect.left =leftrect.right;
  • // Former le texte à partir de la position courante et obtenir sa longueur:
  • int len=utoa(position,buffer,'%');
  • // Sélectionner la police de la barre:
  • HFONT oldfont=(HFONT)SelectObject(hdc,pdata->hfont);
  • // Calculer les dimensions du texte:
  • SetRect(&textrect,0,0,0,0);
  • DrawText(hdc,buffer,-1,&textrect,DT_CALCRECT);
  • // Calculer la position horizontale et verticale du texte:
  • int xpos=(clientrect.right/2)-(textrect.right/2);
  • int ypos=(clientrect.bottom/2)-(textrect.bottom/2);
  • // Récupérer la couleur de la barre:
  • COLORREF couleurbarre = pdata->barcolor;
  • // Récupérer la couleur du fond de la ProgressBar:
  • COLORREF couleurfond = pdata->bkcolor;
  • // Mettre les couleurs par défaut si elles ne sont pas définies:
  • if(couleurbarre==CLR_DEFAULT )couleurbarre=GetSysColor(COLOR_HIGHLIGHT);
  • if(couleurfond==CLR_DEFAULT )couleurfond=GetSysColor(COLOR_3DFACE);
  • // Définir la couleur de la partie pleine de la barre:
  • SetBkColor(hdc,couleurbarre);
  • // Définir la couleur du texte de la partie pleine de la barre
  • SetTextColor(hdc,couleurfond);
  • // Remplir la partie pleine et afficher texte:
  • ExtTextOut(hdc,xpos,ypos,ETO_OPAQUE | ETO_CLIPPED,&leftrect,buffer,len,0);
  • // Définir la couleur de la partie vide de la barre:
  • SetBkColor(hdc,couleurfond);
  • // Définir la couleur du texte de la partie vide de la barre
  • SetTextColor(hdc,couleurbarre);
  • // Remplir la partie vide et afficher texte:
  • ExtTextOut(hdc,xpos,ypos,ETO_OPAQUE | ETO_CLIPPED,&rightrect,buffer,len,0);
  • // Remettre la police originale:
  • SelectObject(hdc,oldfont);
  • // Libérer le HDC de la ProgressBar:
  • EndPaint (hwnd, &ps) ;
  • return 0;
  • }
  • // Appeler la procédure originale de la ProgressBar:
  • return CallWindowProc((WNDPROC)OldProgressBarProc, hwnd, message, wParam, lParam);
  • }
  • // Procédure de la boite de dialogue de progression:
  • BOOL CALLBACK ProgressDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  • {
  • static HWND hGroupbox, hAnnuler, hProgress;
  • static HFONT police;
  • static HBRUSH couleurfond;
  • switch(message)
  • {
  • case WM_INITDIALOG:
  • // Centrer la boite par rapport à la boite mère: :
  • RECT rect,rect2;
  • POINT pt;
  • GetClientRect(GetParent(hwnd),&rect);
  • GetWindowRect(hwnd,&rect2);
  • pt.x=(rect.right/2)-((rect2.right-rect2.left)/2);
  • pt.y=(rect.bottom/2)-((rect2.bottom-rect2.top)/2);
  • ClientToScreen(GetParent(hwnd),&pt);
  • SetWindowPos(hwnd,0,pt.x,pt.y,0,0,SWP_NOZORDER | SWP_NOSIZE);
  • // Créer le HBRUSH de la couleur du fond:
  • couleurfond=CreateSolidBrush(RGB(255,190,120));
  • // Créer un GroupBox et le bouton "Annuler":
  • hGroupbox=CreateWindowEx(0,"button"," Progression ",WS_CHILD | WS_VISIBLE | BS_GROUPBOX | BS_CENTER ,10,4,340,94,hwnd,0,0,0);
  • hAnnuler=CreateWindowEx(0,"button","Annuler",WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,140,66,80,24,hwnd,(HMENU)IDCANCEL,0,0);
  • // Créer et sous-classer notre ProgressBar:
  • hProgress=CreateWindowEx(0,PROGRESS_CLASS,"",WS_VISIBLE | WS_CHILD | PBS_SMOOTH ,20,30,320,28,hwnd,0,0,0);
  • OldProgressBarProc=(WNDPROC)SetWindowLong(hProgress,GWL_WNDPROC,(LONG)ProgressBarProc);
  • // Définir les couleurs de la ProgressBar:
  • SendMessage(hProgress,PBM_SETBARCOLOR,0,(LPARAM)RGB(180,80,0));
  • SendMessage(hProgress,PBM_SETBKCOLOR,0,(LPARAM)RGB(255,230,200));
  • // Créer et appliquer une police à notre ProgressBar:
  • police=CreateFont(24,0,0,0,0,0,0,0,0,0,0,0,0,"Arial");
  • SendMessage(hProgress,WM_SETFONT,(WPARAM)police,0);
  • // Mettre le focus sur le bouton "Annuler":
  • SetFocus(hAnnuler);
  • // Simuler appui sur ALT Gauche pour interaction avec le clavier au lancement.
  • keybd_event(VK_MENU,0,0,0);
  • keybd_event(VK_MENU,0,KEYEVENTF_KEYUP,0);
  • return 0;
  • case WM_CTLCOLORSTATIC:
  • // Assurer la transparence de notre GroupBox:
  • LOGBRUSH lb;
  • GetObject(couleurfond,sizeof(LOGBRUSH),&lb);
  • SetBkColor((HDC)wParam,lb.lbColor);
  • return (BOOL) couleurfond;
  • case WM_CTLCOLORDLG:
  • // Appliquer notre couleur de fond à la boîte de dialogue:
  • return (BOOL) couleurfond;
  • case WM_WINDOWPOSCHANGED:
  • WINDOWPOS* wp;
  • wp=(WINDOWPOS*)lParam;
  • // S'assurer que notre boîte de progression vient d'être affichée:
  • if(wp->flags & SWP_SHOWWINDOW)
  • {
  • // Appeler la fonction exécutant la tâche dont on veut voir la progression:
  • int nbr=ProgressFunction(hwnd,hProgress,hAnnuler);
  • // Détruire les objets GDI:
  • DeleteObject(couleurfond);
  • DeleteObject(police);
  • // Fermer la boîte de progression:
  • EndDialog(hwnd,nbr);
  • }
  • break;
  • case WM_COMMAND:
  • // Mettre l'attribut USERDATA du bouton "Annuler" à 1 s'il est cliqué ou si la touche Echap ou Entrée a été appuyée:
  • if(LOWORD(wParam)==IDCANCEL)SetWindowLong(hAnnuler,GWL_USERDATA,1);
  • break;
  • case WM_CLOSE:
  • // Empêcher notre boîte de se fermer suite à un ALT-F4 en retournant 1 au lieu de 0:
  • return 1;
  • default:
  • break;
  • }
  • return 0;
  • }
  • // Procédure de la boîte principale:
  • BOOL CALLBACK MainDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  • {
  • static HWND hIntro, hQuitter, hLancer;
  • switch(message)
  • {
  • case WM_INITDIALOG:
  • // Définir le titre de la boîte:
  • SetWindowText(hwnd,"Progress Dialog");
  • // Créer le Static et les Boutons:
  • hIntro=CreateWindowEx(0,"static","Cliquez sur le bouton \"Lancer\" pour démarrer la boîte de progression.", WS_CHILD | WS_VISIBLE | SS_CENTER,50,80,412,50,hwnd,0,0,0);
  • hLancer=CreateWindowEx(0,"button","Lancer", WS_CHILD | WS_VISIBLE,312,200,80,24,hwnd,0,0,0);
  • hQuitter=CreateWindowEx(0,"button","Quitter", WS_CHILD | WS_VISIBLE,120,200,80,24,hwnd,0,0,0);
  • return 0;
  • case WM_CTLCOLORSTATIC:
  • // Assurer la transparence des Statics:
  • SetBkMode((HDC)wParam,TRANSPARENT);
  • return (BOOL) GetStockObject(NULL_BRUSH);
  • case WM_ERASEBKGND:
  • // Remplir le fond de la boîte en vert:
  • RECT rc;
  • GetClientRect(hwnd,&rc);
  • SetBkColor((HDC)wParam,RGB(160,230,160));
  • ExtTextOut((HDC)wParam,0,0,ETO_OPAQUE,&rc,0,0,0);
  • return 1;
  • case WM_COMMAND:
  • if( (HWND)lParam == hLancer )
  • {
  • // Allouer de la mémoire pour notre dialog template:
  • LPDLGTEMPLATE lpdt = ( LPDLGTEMPLATE) GlobalAlloc(GPTR, 512);
  • // Définir les styles de la boite de dialogue fille:
  • lpdt->style = WS_POPUP | WS_DLGFRAME ;
  • lpdt->dwExtendedStyle=0;
  • // Obtenir les unités d'affichage des boites de dialogues:
  • LONG baseunits=GetDialogBaseUnits();
  • // Définir les dimensions de la boite fille:
  • lpdt->cx = MulDiv(360, 4,LOWORD(baseunits));
  • lpdt->cy = MulDiv(110, 8, HIWORD(baseunits));;
  • // Lancer la boite de dialogue fille (de progression):
  • DialogBoxIndirectParam(GetModuleHandle(0),lpdt,hwnd,(DLGPROC)ProgressDlgProc,(LPARAM)0);
  • // Libérer la mémoire allouée:
  • GlobalFree((HGLOBAL)lpdt);
  • return 0;
  • }
  • if((HWND)lParam==hQuitter)
  • {
  • // Envoyer le message de fermeture de notre boîte de dialogue:
  • SendMessage(hwnd,WM_CLOSE,0,0);
  • }
  • return 0;
  • case WM_CLOSE:
  • // Fermer la boîte de dialogue:
  • EndDialog(hwnd,0);
  • return 0;
  • default:
  • break;
  • }
  • return 0;
  • }
  • // Fonction d'entrée du programme:
  • int APIENTRY WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmd, int show)
  • {
  • // Charger La DLL pour les Common Controls:
  • HINSTANCE hCmLib= LoadLibrary("comctl32.dll");
  • //Allouer de la mémoire pour notre dialog template:
  • LPDLGTEMPLATE lpdt = ( LPDLGTEMPLATE) GlobalAlloc(GPTR, 512);
  • // Définir les styles de la boite de dialogue:
  • lpdt->style = DS_CENTER | WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX |WS_CAPTION ;
  • lpdt->dwExtendedStyle=0;
  • // Obtenir les unités d'affichage des boites de dialogues:
  • LONG baseunits=GetDialogBaseUnits();
  • // Définir les dimensions de la boite:
  • lpdt->cx = MulDiv(512, 4,LOWORD(baseunits));
  • lpdt->cy = MulDiv(240, 8, HIWORD(baseunits));;
  • //Lancer la boite de dialogue
  • DialogBoxIndirectParam(GetModuleHandle(0),lpdt,0,(DLGPROC)MainDlgProc,(LPARAM)0);
  • //Libération de la mémoire allouée:
  • GlobalFree((HGLOBAL)lpdt);
  • // Libérer "comctl32.dll";
  • FreeLibrary(hCmLib);
  • return 0;
  • }
#include <windows.h>
#include <commctrl.h>

WNDPROC OldProgressBarProc;

// Structure de récupération des données d'une ProgressBar:
typedef struct 
{
    HWND hwnd;
    DWORD dwStyle;
    INT iMin;
	INT iMax;
    INT iPos;
    INT iStep;
    HFONT hfont;
    COLORREF bkcolor;
    COLORREF barcolor;
} PRODATA;


// Cette fonction vide la pile des messages de la fenêtre parente de notre boîte de dialogue
// afin de l'empêcher de réagir aux actions survenues pendant la progression.
// Elle permet aussi d'intercepter le clic sur le bouton "Annuler" et l'utilisation de la touche Echap et Entrée.
void TraiterMessages(HWND hwnd)
{
	MSG msg;
	// Enlever tous les messages destinés aux fenêtres de l'application:
	while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
	{
		// Utiliser la fonction IsDialogMessage() pour permmetre à notre boîte de réagir aux actions clavier:
		if(!IsDialogMessage(hwnd, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
}

// Fonction exécutant une boucle de simulation d'une tâche en progression:
int ProgressFunction(HWND hdlg, HWND progress, HWND cancel)
{
	// Mettre l'attribut USERDATA du bouton "Annuler" à 0:
	SetWindowLong(cancel,GWL_USERDATA,0);
	int i;
	// Lancer la boucle pour simuler une progression:
	for(i=0;i<3000000;i++) 
	{ 
		// Mettre à jour la position de la ProgressBar:
		SendMessage(progress,PBM_SETPOS,i/30000,0);
		// Autoriser le traitement des messages de notre boîte de progression:
		TraiterMessages(hdlg);
		// Sortir de la boucle si l'attibut USERDATA du bouton Annuler est à 1 suite à un clic ou un appui sur Echap ou Entrée:
		if (GetWindowLong(cancel,GWL_USERDATA))break;
	}
	// Retourner la dernière valeur de i:
	return i;
}

// Fonction de conversion de la position de la ProgressBar en chaîne contenant un pourcentage:
int utoa(UINT nombre, char* buf, char car)
{
	// retour immédiat si buf est null:
	if(!buf) return 0;
	char tampon[12];
	char* ptampon = tampon;
	char* pbuf=buf;
	UINT i;
	// Boucle de conversion en caractères:
	do
	{
		i=nombre%10;
		nombre=nombre/10;
		*ptampon=i+'0';
		ptampon++;
	}while(nombre);
	// Boucle de transfert des caractères, à l'envers, vers le buffer destination:
	while (ptampon > tampon)
	{
		ptampon--;
		*pbuf=*ptampon;
		pbuf++;
	}
	// Ajouter le symbole donné en 3è paramètre de la fonction (ici %):
	*pbuf = car;
	// Mettre le 0 final de la chaîne:
	pbuf++;
	*pbuf = 0;
	// Retourner la longueur de la chaîne:
	return pbuf-buf;
}

// Procédure de sous-classement de notre ProgressBar:
LRESULT CALLBACK ProgressBarProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message == WM_PAINT)
	{
		PAINTSTRUCT ps;
		RECT clientrect, leftrect, rightrect, textrect;
		char buffer[12];
		// Obtenir le HDC de la ProgressBar:
		HDC hdc = BeginPaint(hwnd, &ps) ;
		// Récupérer les données de la ProgressBar:
		PRODATA* pdata=(PRODATA*)GetWindowLong(hwnd,0);
		// Obtenir le rectangle de la zone cliente de la ProgressBar:
		GetClientRect(hwnd, &clientrect);
		// Obtenir la position courante de la barre:
		UINT position = pdata->iPos;
		// Calculer et définir les rectangles gauche et droit correspondant respectivement à la partie pleine et vide de la ProgressBar:
		leftrect=rightrect=clientrect;
		leftrect.right =MulDiv(clientrect.right,position,100);
		rightrect.left =leftrect.right;
		// Former le texte à partir de la position courante et obtenir sa longueur:
		int len=utoa(position,buffer,'%');
		// Sélectionner la police de la barre:
		HFONT oldfont=(HFONT)SelectObject(hdc,pdata->hfont);
		// Calculer les dimensions du texte:
		SetRect(&textrect,0,0,0,0);
		DrawText(hdc,buffer,-1,&textrect,DT_CALCRECT);
		// Calculer la position horizontale et verticale du texte:
		int xpos=(clientrect.right/2)-(textrect.right/2);
		int ypos=(clientrect.bottom/2)-(textrect.bottom/2);

		// Récupérer la couleur de la barre:
		COLORREF couleurbarre = pdata->barcolor;
		// Récupérer la couleur du fond de la ProgressBar:
		COLORREF couleurfond = pdata->bkcolor;
		// Mettre les couleurs par défaut si elles ne sont pas définies:
		if(couleurbarre==CLR_DEFAULT )couleurbarre=GetSysColor(COLOR_HIGHLIGHT);
		if(couleurfond==CLR_DEFAULT )couleurfond=GetSysColor(COLOR_3DFACE);

		// Définir la couleur de la partie pleine de la barre:
		SetBkColor(hdc,couleurbarre);
		// Définir la couleur du texte de la partie pleine de la barre
		SetTextColor(hdc,couleurfond);
		// Remplir la partie pleine et afficher texte:
		ExtTextOut(hdc,xpos,ypos,ETO_OPAQUE | ETO_CLIPPED,&leftrect,buffer,len,0);

		// Définir la couleur de la partie vide de la barre:
		SetBkColor(hdc,couleurfond);
		// Définir la couleur du texte de la partie vide de la barre
		SetTextColor(hdc,couleurbarre);
		// Remplir la partie vide et afficher texte:
		ExtTextOut(hdc,xpos,ypos,ETO_OPAQUE | ETO_CLIPPED,&rightrect,buffer,len,0);

		// Remettre la police originale:
		SelectObject(hdc,oldfont);
		// Libérer le HDC de la ProgressBar:
		EndPaint (hwnd, &ps) ;
		return 0;
	}
	// Appeler la procédure originale de la ProgressBar:
	return CallWindowProc((WNDPROC)OldProgressBarProc, hwnd, message, wParam, lParam);
}

// Procédure de la boite de dialogue de progression:
BOOL CALLBACK ProgressDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HWND hGroupbox, hAnnuler, hProgress;
	static HFONT police;
	static HBRUSH couleurfond;
	switch(message)
	{
	case WM_INITDIALOG:
		// Centrer la boite par rapport à la boite mère: :
		RECT rect,rect2;
		POINT pt;
		GetClientRect(GetParent(hwnd),&rect);
		GetWindowRect(hwnd,&rect2);
		pt.x=(rect.right/2)-((rect2.right-rect2.left)/2);
		pt.y=(rect.bottom/2)-((rect2.bottom-rect2.top)/2);
		ClientToScreen(GetParent(hwnd),&pt);
		SetWindowPos(hwnd,0,pt.x,pt.y,0,0,SWP_NOZORDER | SWP_NOSIZE);
		// Créer le HBRUSH de la couleur du fond:
		couleurfond=CreateSolidBrush(RGB(255,190,120));
		// Créer un GroupBox et le bouton "Annuler":
		hGroupbox=CreateWindowEx(0,"button"," Progression ",WS_CHILD | WS_VISIBLE | BS_GROUPBOX | BS_CENTER ,10,4,340,94,hwnd,0,0,0);
		hAnnuler=CreateWindowEx(0,"button","Annuler",WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,140,66,80,24,hwnd,(HMENU)IDCANCEL,0,0);
		// Créer et sous-classer notre ProgressBar:
		hProgress=CreateWindowEx(0,PROGRESS_CLASS,"",WS_VISIBLE | WS_CHILD  | PBS_SMOOTH ,20,30,320,28,hwnd,0,0,0);
		OldProgressBarProc=(WNDPROC)SetWindowLong(hProgress,GWL_WNDPROC,(LONG)ProgressBarProc);
		// Définir les couleurs de la ProgressBar:
		SendMessage(hProgress,PBM_SETBARCOLOR,0,(LPARAM)RGB(180,80,0));
		SendMessage(hProgress,PBM_SETBKCOLOR,0,(LPARAM)RGB(255,230,200));
		// Créer et appliquer une police à notre ProgressBar:
		police=CreateFont(24,0,0,0,0,0,0,0,0,0,0,0,0,"Arial");
		SendMessage(hProgress,WM_SETFONT,(WPARAM)police,0);
		// Mettre le focus sur le bouton "Annuler":
		SetFocus(hAnnuler);
		// Simuler appui sur ALT Gauche  pour interaction avec le clavier au lancement. 
		keybd_event(VK_MENU,0,0,0);
		keybd_event(VK_MENU,0,KEYEVENTF_KEYUP,0);
		return 0;

	case WM_CTLCOLORSTATIC:
		// Assurer la transparence de notre GroupBox:
		LOGBRUSH lb;
		GetObject(couleurfond,sizeof(LOGBRUSH),&lb);
		SetBkColor((HDC)wParam,lb.lbColor);
		return (BOOL) couleurfond;

	case WM_CTLCOLORDLG:
		// Appliquer notre couleur de fond à la boîte de dialogue:
		return (BOOL) couleurfond;

	case WM_WINDOWPOSCHANGED:
		WINDOWPOS* wp;
		wp=(WINDOWPOS*)lParam;
		// S'assurer que notre boîte de progression vient d'être affichée:
		if(wp->flags & SWP_SHOWWINDOW)
		{
			// Appeler la fonction exécutant la tâche dont on veut voir la progression:
			int nbr=ProgressFunction(hwnd,hProgress,hAnnuler);
			// Détruire les objets GDI:
			DeleteObject(couleurfond);
			DeleteObject(police);
			// Fermer la boîte de progression:
			EndDialog(hwnd,nbr);
		}
		break;

	case WM_COMMAND:
		// Mettre l'attribut USERDATA du bouton "Annuler" à 1 s'il est cliqué ou si la touche Echap ou Entrée a été appuyée:
		if(LOWORD(wParam)==IDCANCEL)SetWindowLong(hAnnuler,GWL_USERDATA,1);
		break;

	case WM_CLOSE:
		// Empêcher notre boîte de se fermer suite à un ALT-F4 en retournant 1 au lieu de 0:
		return 1;

	default:
		break;
	}
	return 0;
}

// Procédure de la boîte principale:
BOOL CALLBACK MainDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HWND hIntro, hQuitter, hLancer;

	switch(message)
	{
	case WM_INITDIALOG:
		// Définir le titre de la boîte:
		SetWindowText(hwnd,"Progress Dialog");
		// Créer le Static et les Boutons:
		hIntro=CreateWindowEx(0,"static","Cliquez sur le bouton \"Lancer\" pour démarrer la boîte de progression.", WS_CHILD | WS_VISIBLE | SS_CENTER,50,80,412,50,hwnd,0,0,0);
		hLancer=CreateWindowEx(0,"button","Lancer", WS_CHILD | WS_VISIBLE,312,200,80,24,hwnd,0,0,0);
		hQuitter=CreateWindowEx(0,"button","Quitter", WS_CHILD | WS_VISIBLE,120,200,80,24,hwnd,0,0,0);
		return 0;

	case WM_CTLCOLORSTATIC:
		// Assurer la transparence des Statics:
		SetBkMode((HDC)wParam,TRANSPARENT);
		return (BOOL) GetStockObject(NULL_BRUSH);

	case WM_ERASEBKGND:
		// Remplir le fond de la boîte en vert:
		RECT rc;
		GetClientRect(hwnd,&rc);
		SetBkColor((HDC)wParam,RGB(160,230,160));
		ExtTextOut((HDC)wParam,0,0,ETO_OPAQUE,&rc,0,0,0);
		return 1;


	case WM_COMMAND:
		if( (HWND)lParam == hLancer ) 
	    {
			// Allouer de la mémoire pour notre dialog template:
			LPDLGTEMPLATE lpdt = ( LPDLGTEMPLATE) GlobalAlloc(GPTR, 512); 
			// Définir les styles de la boite de dialogue fille:
			lpdt->style =  WS_POPUP  | WS_DLGFRAME ;
			lpdt->dwExtendedStyle=0;
			// Obtenir les unités d'affichage des boites de dialogues:
			LONG baseunits=GetDialogBaseUnits();
			// Définir les dimensions de la boite fille:
			lpdt->cx = MulDiv(360, 4,LOWORD(baseunits)); 
			lpdt->cy = MulDiv(110, 8, HIWORD(baseunits));;         
			// Lancer la boite de dialogue fille (de progression):
			DialogBoxIndirectParam(GetModuleHandle(0),lpdt,hwnd,(DLGPROC)ProgressDlgProc,(LPARAM)0);
			// Libérer la mémoire allouée:
			GlobalFree((HGLOBAL)lpdt);
		   return 0;
	    }
		if((HWND)lParam==hQuitter)
		{
			// Envoyer le message de fermeture de notre boîte de dialogue:
			SendMessage(hwnd,WM_CLOSE,0,0);
		}
		return 0;

	case WM_CLOSE:
		// Fermer la boîte de dialogue:
		EndDialog(hwnd,0);
		return 0;

	default:
		break;
	}
	return 0;
}

// Fonction d'entrée du programme:
int APIENTRY WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmd, int show)
{
	// Charger La DLL pour les Common Controls:
	HINSTANCE hCmLib= LoadLibrary("comctl32.dll");
	//Allouer de la mémoire pour notre dialog template:
	LPDLGTEMPLATE lpdt = ( LPDLGTEMPLATE) GlobalAlloc(GPTR, 512); 
	// Définir les styles de la boite de dialogue:
	lpdt->style = DS_CENTER | WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX |WS_CAPTION ; 
	lpdt->dwExtendedStyle=0;
	// Obtenir les unités d'affichage des boites de dialogues:
	LONG baseunits=GetDialogBaseUnits();
	// Définir les dimensions de la boite:
	lpdt->cx = MulDiv(512, 4,LOWORD(baseunits)); 
	lpdt->cy = MulDiv(240, 8, HIWORD(baseunits));;         
	//Lancer la boite de dialogue
	DialogBoxIndirectParam(GetModuleHandle(0),lpdt,0,(DLGPROC)MainDlgProc,(LPARAM)0);
	//Libération de la mémoire allouée:
	GlobalFree((HGLOBAL)lpdt);
	// Libérer "comctl32.dll";
	FreeLibrary(hCmLib);
	return 0;
}


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture SOUS-CLASSEMENT DE FENÊTRE D'UN AUTRE PROCESS PAR INJECTION ...
Source avec Zip Source avec une capture FENÊTRE FLOTTANTE SANS FOCUS (WIN32 API)
Source avec Zip Source avec une capture SERVICE WINDOWS DANS UNE DLL LANCÉ PAR SVCHOST.EXE
Source avec Zip Source avec une capture IMPRESSION EN WIN32 API AVEC OPTIONS
Source avec Zip Source avec une capture INFOTIP SHELL EXTENSION (BULLE DE L'EXPLORATEUR WINDOWS) (WI...

 Sources de la même categorie

Source avec Zip WIN32 TLS LENT par dguilmain
Source avec Zip VIDER ELEMENTS DE CORBEILLE WINDOWS7 (WIN64) par BruNews
Source avec Zip Source avec une capture FIND TEXT (WIN64) par BruNews
Source avec Zip DELETE DIRECTORY (WIN64) par BruNews
Source avec Zip ENUM DIRECTORY (WIN64) par BruNews

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture GALAWA, ÉDITEUR DE SCRIPTS MIRC (+ CRÉATEUR DE PICWINS ET DI... par uaip
Source avec Zip Source avec une capture CALCULER SES MOYENNES par uaip
Source avec Zip Source avec une capture [WIN32][C][DEV-C++] SNIFF EN RAW SOCKET, AVEC ANNALYSE DES ... par omnia
Source avec Zip Source avec une capture PIECHART SUR DIALOG SANS RESSOURCE par yann_lo_san
Source avec Zip CLASSE PROGRESS BAR par yserver

Commentaires et avis

Commentaire de soso62fr le 05/11/2008 01:49:23

J'arrive pas a la compiler sous CODE::BLOCK...

Commentaire de racpp le 05/11/2008 19:27:42 administrateur CS

Quelles sont les erreurs affichées?

Commentaire de soso62fr le 07/11/2008 02:56:34

||=== testeCode, Debug ===|
obj\Debug\main.o||In function `_Z15ProgressBarProcP6HWND__jjl':|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|108|undefined reference to `_SelectObject@8'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|123|undefined reference to `_SetBkColor@8'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|125|undefined reference to `_SetTextColor@8'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|127|undefined reference to `_ExtTextOutA@32'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|129|undefined reference to `_SetBkColor@8'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|131|undefined reference to `_SetTextColor@8'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|133|undefined reference to `_ExtTextOutA@32'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|135|undefined reference to `_SelectObject@8'|
obj\Debug\main.o||In function `_Z15ProgressDlgProcP6HWND__jjl':|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|162|undefined reference to `_CreateSolidBrush@4'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|173|undefined reference to `_CreateFontA@56'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|184|undefined reference to `_GetObjectA@12'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|185|undefined reference to `_SetBkColor@8'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|199|undefined reference to `_DeleteObject@4'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|200|undefined reference to `_DeleteObject@4'|
obj\Debug\main.o||In function `_Z11MainDlgProcP6HWND__jjl':|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|233|undefined reference to `_SetBkMode@8'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|234|undefined reference to `_GetStockObject@4'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|239|undefined reference to `_SetBkColor@8'|
C:\Documents and Settings\Administrateur\Mes documents\testeCode\main.cpp|240|undefined reference to `_ExtTextOutA@32'|
||=== Build finished: 18 errors, 0 warnings ===|

Commentaire de racpp le 07/11/2008 20:32:37 administrateur CS

Ce sont des erreurs de l'éditeur de liens car il ne trouve pas les fonctions de la GDI. Pour résoudre le problème il suffit de lier ton projet avec libgdi32.a et ça devrait marcher. Aller au menu "Project" et choisir "Build Options...". Dans la boite qui apparait cliquer sur l'onglet "Linker settings" puis sur "Add" et choisir le fichier "libgdi32.a" qui se trouve dans "C:\Program Files\CodeBlocks\MinGW\lib"

Commentaire de soso62fr le 08/11/2008 05:23:24

Merci ! Il me fallais juste le nom du fichier a lier (libgdi32.a) pour le reste je sais faire ;) ! Desolé de t'avoir deranger mais je pouvais pas savoir qui fallais lier ce fichier car je connais pas ces fonctions.

Ciao :) !

Commentaire de soso62fr le 08/11/2008 05:23:46 9/10

9/10 :)

Commentaire de SimTran le 16/08/2011 12:53:30 9/10

Même des années après, c'est encore utile. Merci.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Progress bar, dialog refuse de s'afficher [ par babylone2019 ] Bonjour, Je debute avec visual C++ 6.J'ai creer une ressource de type dialog qui ce compose de quelque label et d'une progress bar.J'inclus la librair Hook clavier pendant progressbar [ par goutbouyo ] Salut,Je voudrais mettre un hook général sur le clavier pendant une progress bar.J'ai essayé en mettant un WinExec sur un programme trouvé sur ce site Pb avec VC [ par kokoariko ] Lus',1/Sous Visual C++, j'ai créé différents contrôles (CListBox, CProgressBar, CStatic ...) sur une fenêtre Dialog, grace à MFC ClassWizard.Tout se p ProgressBar dans Status Bar [ par thierry la fronde ] Salut,J'ai vu il y a quelque temps un source pour mettre une barre de progression dans la barre d'état. Quelqu'un saurait-il ? Comment reactiver une fentre Dialog [ par enrageur ] Je programme sous visual C++ 6. je concois un petit logiciel avec des fenetres windows (fenetre Dialog par default). Voila mon probleme, j'ouvre une f REsiZE Dialog [ par furiouspk ] Bonjour!!!Je Cherche Le Moyen De LimiTer Le ResiZe D'une Dialog !!Si Vous Avez Une Tite Idée La Dessus??Merci Za Vous................................. Child Dialog dans une app en MDI [ par LudovicJ ] Bonjour à tous,Je suis en train de faire une app MDI qui contient plusieurs boites de dialogue.J'arrives à insérer mes boites de dialogue sans pb. Seu directdraw et dialog box [ par mannix ] Salut à tous, je débute en c++ et j'ai un peu de mal à comprendre tous les mecanismes qui permettent de manipuler facilement le fenetres. Je voudrais InvalidateRect a fermeture d'une fenetre fille [ par AlexMAN ] Bonsoir, Voila, j'ai une ptite kestion qui me turlupine. J'ai une dialog a partir de laquelle je gere l'affichage d'autres dialogs, mais a la fermetur [MFC] Dialog non modal [ par Helau ] Bonjour,Mon application utilise des boites de dialogues non modales, car je suis obligée de faire un create et un show window, par forcément en même t


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
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 : 2,106 sec (3)

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