C'est dans la procédure de fenêtre que nous allons ajouter le code nécessaire à nos dessins. Le message "WM_PAINT" est envoyé chaque fois que la fenêtre doit être redessinée. Nous ajoutons donc ce message, ce qui nous donne le code :
LRESULT CALLBACK WindowProcedure (HWND hwnd,
UINT message, WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
// C'est ici que nous allons dessiner
break;
case WM_DESTROY:
PostQuitMessage
(0);
// Déclenche la fermeture de la fenêtre
break;
default:
return DefWindowProc
(hwnd,
message, wParam,
lParam)
;
}
return
0;
}
Pour dessiner, il nous faut commencer par créer ce qu'on appelle un "handle de contexte de périphérique", et déclarer une structure pour le dessin. La dernière ligne permet de lier notre "handle de périphérique" à la fenêtre actuelle.
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hwnd,
&ps);
Une fois notre dessin réalisé, il ne faut pas oublier de fermer avec le code :
EndPaint(hwnd, &ps);
C'est maintenant que nous allons voir comment nous dessinons dans une fenêtre.
Windows utilise ce que nous appelons des crayons pour le dessin. Ces crayons peuvent être paramétrés en couleur, en épaisseur, etc.
Premièrement nous créons deux "handle de crayon". Le premier servira à conserver le crayon actuellement utilisé par
Windows. Ceci afin de pouvoir lui rendre à la fin de notre travail.
Le deuxième "handle" permettra de manipuler le crayon que nous allons définir pour notre dessin.
Nous déclarons ensuite une variable qui contiendra la couleur que nous allons utiliser, et qui sera de type RGB.
Le crayon se voit ensuite attribué un type de trait, une épaisseur en pixels, et enfin la couleur choisie. Le code est le suivant :
HPEN hOldPen;
// "handle" sur le crayon actuel
HPEN hRedPen;
// "handle" sur notre nouveau crayon
COLORREF qRedColor;
// Variable pour enregistrer notre couleur
qRedColor =
RGB (255,
0,
0);
// La couleur sera rouge
// Transmission des paramètres à notre crayon
hRedPen =
CreatePen(PS_SOLID,
3, qRedColor);
Arrêtons nous un instant sur cette nouvelle fonction : "CreatePen()". Elle comporte 3 paramètres :
Le premier paramètre est le type de trait. Voici quelques exemples :
PS_SOLID | PS_DASH | PS_DOT | PS_DASHDOT | PS_DASHDOTDOT |
![]() |
![]() |
![]() |
![]() |
![]() |
Le paramètre suivant est l'épaisseur du trait en pixel.
Le dernier paramètre permet d'affecter une couleur de type RGB au crayon.
Un dernier effort avant de dessiner, il faut préciser au programme que nous allons utiliser notre nouveau crayon. C'est la ligne suivante qui permet de permuter l'ancien et le nouveau :
// permutation des crayons
hOldPen =
(HPEN)
SelectObject (hDC,
hRedPen );
Il sera nécessaire après notre dessin de récupérer l'ancien crayon, et de détruire celui que nous avons utilisé afin de libérer la mémoire. Ce qui se fait avec le code suivant :
// Réattribution de l'ancien crayon
SelectObject (hDC,
hOldPen );
// Suppression du crayon utilisé pour dessiner
DeleteObject (hRedPen );
Nous voici maintenant prêt à dessiner. Nous commençons par poser le crayon ce qui se fait avec :
// Le crayon est placé à la position (x, y), ici x = 100, et y = 50
MoveToEx (hDC,
100,
50,
NULL );
Le tracé à partir de la position précédente se fait ensuite avec l'instruction :
// Tracé d'une ligne jusqu'à la position (x, y), ici x = 400, et y = 30
LineTo (hDC,
400,
30);
Si tout c'est bien passé, vous devriez voir ceci (un magnifique trait rouge) :
Pour ceux qui éprouveraient encore quelques difficultés voici le code complet concernant la procédure de fenêtre :
LRESULT CALLBACK WindowProcedure (HWND hwnd,
UINT message, WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
// C'est ici que nous allons dessiner
HDC hDC;
// Déclaration du "handle" du contexte de périphérique
PAINTSTRUCT ps;
// Le pointeur sur la structure de dessin
hDC = BeginPaint(hwnd,
&ps);
// le "handle" devient opérationnel
HPEN hOldPen;
// "handle" sur le crayon actuel
HPEN hRedPen;
// "handle" sur notre nouveau crayon
COLORREF qRedColor;
// Variable pour enregistrer notre couleur
qRedColor =
RGB (255,
0,
0);
// La couleur sera rouge
// Transmission des paramètres à notre crayon
hRedPen =
CreatePen(PS_SOLID,
3, qRedColor);
// permutation des crayons
hOldPen =
(HPEN)
SelectObject (hDC,
hRedPen );
// Le crayon est placé à la position (x, y), ici x = 100, et y = 50
MoveToEx (hDC,
100,
50,
NULL );
// Tracé d'une ligne jusqu'à la position (x, y), ici x = 400, et y = 30
LineTo (hDC,
400,
30);
// Réattribution de l'ancien crayon
SelectObject (hDC,
hOldPen );
// Suppression du crayon utilisé pour dessiner
DeleteObject (hRedPen );
EndPaint(hwnd,
&ps);
break;
case WM_DESTROY:
PostQuitMessage
(0);
// Déclenche la fermeture de la fenêtre
break;
default:
return DefWindowProc
(hwnd,
message, wParam,
lParam)
;
}
return
0;
}
Vous savez maintenant tracer une ligne, lui donner une couleur et une épaisseur. Et si on voulait tracer un cercle ?
Voyons maintenant quelques instructions supplémentaires.
Nous venons de voir comment tracer une ligne :
// Le crayon est placé à la position (x, y), ici x = 100, et y = 50
MoveToEx (hDC,
100,
50,
NULL );
// Tracé d'une ligne jusqu'à la position (x, y), ici x = 400, et y = 30
LineTo (hDC,
400,
30);
Nous allons maintenant apprendre à tracer une ellipse :
// Tracé d'une Ellipse
Arc (hDC,
50,
30,
300,
100,
0,
0,
0,
0);
Ce qui nous donnerait :
Un peu d'explication :
50 et 30 désignent respectivement les coordonnées x et y du coin supérieur gauche du rectangle contenant l'ellipse.
300 et 100 désignentt respectivement les coordonnées x et y du coin inférieur droit du rectangle contenant l'ellipse.
Si nous désirons ne tracer qu'une portion de cette arc, alors les paramètres suivants permettent de définir le point
de début de l'arc, et le point de fin. Il n'est pas nécessaire de placer ces points sur le tracé de l'ellipse.
Exemple :
// Tracé d'un contour du visage (cercle)
Arc (hDC,
20,
20,
200,
200,
0,
0,
0,
0);
// Oeil gauche (ellipses)
Arc (hDC,
50,
50,
100,
120,
0,
0,
0,
0);
Arc (hDC,
50,
65,
80,
105,
0,
0,
0,
0);
// Oeil droit (ellipses)
Arc (hDC,
120,
50,
170,
120,
0,
0,
0,
0);
Arc (hDC,
120,
65,
150,
105,
0,
0,
0,
0);
// Sourire (arcs d'ellipses)
Arc (hDC,
50,
80,
170,
160,
50,
130,
170,
130);
Arc (hDC,
50,
60,
170,
180,
50,
130,
170,
130);
et voici le résultat :
Une petite pause maintenant en attendant le chapître suivant.