0/5 (4 avis)
Vue 9 652 fois - Téléchargée 1 023 fois
//************************************************************************************** //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 ; }
26 juin 2009 à 14:37
26 juin 2009 à 14:21
3 juin 2009 à 09:07
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+
31 mai 2009 à 15:55
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.