Classe graph: gestion des graphiques dans les applications win32

Soyez le premier à donner votre avis sur cette source.

Vue 9 018 fois - Téléchargée 983 fois

Description

Cette classe permet de gérer très facilement l'ajout de graphique dans vos applications. Elle utilise les API win 32 pure.
L'interface homme machine a été pensée pour être le plus simple intuitif et le plus simple possible.

-Un clic gauche déplacé permet de déplacer la fenêtre de visualisation.
-Un clic droit permet de faire un zoom optimal sur les courbes du graphique.
-un clic droit déplacé permet d'adapter la fenêtre de visualisation au rectangle créer.
-La molette de la souris permet de faire un zoom ou un dé zoom sur les données.
-Un clic gauche sur une courbe permet de la sélectionner. La courbe sélectionnée devient la courbe courante.
-Lorsque l'utilisateur appuie le bouton supprimé lorsqu'une courbe est sélectionnée, cette courbe est supprimée.
-La touche Echap permet de désélectionner la courbe.
-Le mouvement de la souris sur les données permet de placer le curseur sur la courbe courante et de visualiser les coordonnées.
-On peut ajouter un titre et une légende.

Source / Exemple :


//**************************************************************************************
//Vincent Morard
//Graph : Classe pour la gestion des graphiques dans une application Win32 
//23/05/2009
//**************************************************************************************
#include <windows.h>
#include <math.h>
#include "Plot.h"
HINSTANCE hInst;

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static int cx,cy;
	static Plot *P1,*P2,*P3;
	switch (message)
	{
	case WM_CREATE:
		double X[1000],Y[1000],Y2[1000],Y3[1000],Y4[1000],Y5[1000],Y6[1000],Y7[1000];

		Plot::Initialize(hInst);
		P1 = new Plot();
		P2 = new Plot();
		P3 = new Plot();
		
		P1->CreatePlot(0,WS_CHILD|WS_VISIBLE,20,20,100,200,hwnd);
		P2->CreatePlot(0,WS_CHILD|WS_VISIBLE|WS_DLGFRAME,300,20,50,200,hwnd);
		P3->CreatePlot(0,WS_CHILD|WS_VISIBLE,20,20,100,200,hwnd);
		
		//Couleur des graphs
		P1->SetBkColor(RGB(112,156,227));
		P1->SetGraphColor(RGB(204,219,244));

		P2->SetBkColor(RGB(95,195,34));
		P2->SetGraphColor(RGB(219,251,196));

		P3->SetBkColor(RGB(193,56,41));
		P3->SetGraphColor(RGB(251,218,196));

		//Création des courbes
		srand(GetTickCount());
		X[0]=0;Y[0]=0;Y2[0]=0;Y3[0]=0;Y4[0]=0,Y5[0]=0,Y6[0]=0,Y7[0]=0;

		for(int i=1;i<1000;i++){
			X[i]=i;
			Y[i]=Y[i-1]+(rand()%2 == 0 ? -1:1);
			Y2[i]=20*sin((double)i/20);
			Y3[i]=(i/30-2)*10;
			Y4[i]=(sin((double)i/4)*sqrt((double)i));
			Y5[i]=(sin((double)i/4)*sqrt((double)i*3));
			Y6[i]=(sin((double)i/4)*sqrt((double)i*6));
			Y7[i]=(sin((double)i/4)*sqrt((double)i*9));
		}

		//Ajout des courbes dans les graph
		P1->Add(X,Y,100  ,RGB(0,200,200) ,PLOT_TYPE_CROSS_AND_LINE);

		P2->Add(X,Y,1000 ,RGB(200,0,0)   ,PLOT_TYPE_LINE);
		P2->Add(X,Y2,1000,RGB(0,200,0)   ,PLOT_TYPE_CROSS_AND_LINE);
		P2->Add(X,Y3,300 ,RGB(255,128,64),PLOT_TYPE_CROSS);
		
		P3->Add(X,Y4,100 ,RGB(100,0,0)     ,PLOT_TYPE_CROSS);
		P3->Add(X,Y5,100 ,RGB(200,0,0)   ,PLOT_TYPE_CROSS);
		P3->Add(X,Y6,100 ,RGB(255,126,0)   ,PLOT_TYPE_CROSS);
		P3->Add(X,Y7,100 ,RGB(255,189,20)   ,PLOT_TYPE_CROSS);
		

		P1->AddTitle("Y[i-1] + (rand()%2 == 0 ? -1:1)");

		P3->AddTitle("Sinus pondéré avec une racine carré");
		P3->AddLegend();
		P3->AddLegend(0,"Sin{w/4} * sqrt(w)");
		P3->AddLegend(1,"Sin{w/4} * sqrt(w*3)");
		P3->AddLegend(2,"Sin{w/4} * sqrt(w*6)");
		P3->AddLegend(3,"Sin{w/4} * sqrt(w*9)");
		return 0 ;

	case WM_SIZE:
		cx = LOWORD (lParam) ;
		cy = HIWORD (lParam) ;
		MoveWindow(P1->GetHWND(),20,20,cx/2-20,cy/2-20,TRUE);
		MoveWindow(P2->GetHWND(),cx/2+20,20,cx/2-40,cy/2-20,TRUE);
		MoveWindow(P3->GetHWND(),20,cy/2+20,cx-40,cy/2-20,TRUE);
		break;

	case WM_DESTROY:
		PostQuitMessage (0) ;
		return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE ,PSTR szCmdLine, int iCmdShow)
{
	static char szAppName[] = "Graph" ;
	HWND         hwnd ;
	MSG          msg ;
	WNDCLASS     wndclass ;

	hInst = hInstance;

	wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc   = WndProc ;
	wndclass.cbClsExtra    = 0 ;
	wndclass.cbWndExtra    = 0 ;
	wndclass.hInstance     = hInstance ;
	wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName  = NULL ;
	wndclass.lpszClassName = szAppName ;

	if (!RegisterClass (&wndclass)){
		MessageBox (NULL, "This program requires Windows NT!",szAppName, MB_ICONERROR) ;
		return 0 ;
	}

	hwnd = CreateWindow (szAppName, "Graphiques",
		WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
		CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, hInstance, NULL) ;

	ShowWindow (hwnd, iCmdShow) ;
	UpdateWindow (hwnd) ;

	while (GetMessage (&msg, NULL, 0, 0))
	{
		TranslateMessage (&msg) ;
		DispatchMessage (&msg) ;
	}
	return msg.wParam ;
}

Conclusion :


L'exe est à renommer de Graph.ex en Graph.exe

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
1054
Date d'inscription
samedi 2 octobre 2004
Statut
Membre
Dernière intervention
9 juillet 2013
6
Merci Shorzy!
Messages postés
94
Date d'inscription
jeudi 23 novembre 2000
Statut
Membre
Dernière intervention
1 juin 2013

EXCELENT TRAVAIL !!!!!!!!!!
Messages postés
1054
Date d'inscription
samedi 2 octobre 2004
Statut
Membre
Dernière intervention
9 juillet 2013
6
Salut
Merci de ton message. Oui effectivement je vois de ce que tu parles pour le trait verticale. Je corrigerai cela à l'occasion.

Pour le double buffering, je procède comme tu l'as évoqué. Je le crée une unique fois dans le WM_CREATE. C'est effectivement bien plus rapide que de le créer à chaque WM_PAINT. Cependant, la contre partie est de créer un double buffer qui est de taille fixe. Aussi pour certaine configuration d'écran (forte résolution), il est possible que le double buffer ne soit pas assez grand.
Je pense qu'une solution serait de récréer le double buffer de la taille de la fenêtre dans le WM_SIZE mais après quelques tests où je redimensionne beaucoup la fenêtre , il s'avère que la création du buffer échoue... Je ne sais pas encore à quoi cela est du.

A+
Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
1
Salut,
Bon boulot d'après moi, le résultat est pas mal. Au niveau du rendu, j'aurais cependant une remarque à te faire. Quand on déplace le graphe du bas vers la droite, l'axe des ordonnées reste visible même sur la légende (on voit le trait vertical sur le texte). Ce petit défaut vient de l'ordre de l'utilisation des pinceaux, sans doute.
Niveau code, j'ai regardé en speed, c'est bien codé d'après ce que j'ai vu. J'ai juste une question quant au double buffering, tu créés le DC tampon uniquement dans le WM_CREATE, et tu ne fais que dessiner dessus et recopier sur le DC de la fenêtre avec BitBlt() dans le WM_PAINT, c'est bien ça ?
(je te demande ça, car moi je recréé le DC tampon à chaque WM_PAINT, ce qui est évidemment beaucoup plus lent en temps d'exécution).

Bonne continuation

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.