Introduction :
Après avoir vu les contextes de périphériques, nous allons aborder les principales
fonctions de dessin.
Comme vu au chapitre 5 nous dessinerons suite à la réception du message WM_PAINT
dans un contexte de périphérique obtenu avec BeginPaint.
Dessin :
Nous allons continuer sur la base de l'exemple du chapitre précédent.
Nous y écrirons tout d'abord la même chaîne de caractère avec TextOut,
mais une seule fois.
Ensuite, nous tracerons un rectangle au dessous de la chaîne de caractères :
Rectangle(hdc, 20, 60, 120, 100);
Cette fonction reçoit comme paramètres le handle de contexte de périphérique et
les coordonnées des points haut gauche et bas droit du rectangle.
Windows pour dessiner ce rectangle utilise un crayon et un pinceau.
Quand vous obtenez un handle de contexte de périphérique, il possède déjà
un crayon et un pinceau. Mais vous pouvez aussi dessiner avec des crayons
et des pinceaux que vous avez créés.
HBRUSH hbRed, hbrOld;
HPEN hp2px, hpOld;
/*... ...*/
hp2px = CreatePen(PS_SOLID, 2, 0x00FF0000);
hpOld = SelectObject(hdc,hp2px);
hbRed = CreateSolidBrush(0x000000FF);
hbrOld = SelectObject(hdc,hbRed);
Rectangle(hdc, 160, 60, 260, 100);
SelectObject(hdc,hbrOld);
DeleteObject(hbRed);
SelectObject(hdc,hpOld);
DeleteObject(hp2px);
La création d'un crayon ce fait avec la fonction CreatePen qui reçoit comme
paramètres une constante indiquant le type de trait (continu dans l'exemple),
ensuite la largeur du trait (2 pixels) et enfin sa couleur (bleu).
Après son appel, elle retourne un handle de crayon.
Le pinceau rouge est créé avec la fonction CreateSolidBrush qui reçoit comme
paramètre une couleur.
Mais pour pouvoir les utiliser avec un contexte de périphérique, il faut les sélectionner.
C'est le rôle de la fonction SelectObject, qui reçoit le handle du
contexte de périphérique sur lequel on veut utiliser l'objet (pinceau, crayon ...)
et le handle de l'objet comme second paramètre.
Le second rectangle est donc dessiné avec un contour tracé avec le crayon bleu
d'une largeur de deux pixels et son intérieur peint avec le pinceau rouge.
Quand vous en avez terminé avec l'utilisation des objets que vous avez créé,
il faut les détruire avec la fonction DeleteObject.
De même avant de libérer le contexte de périphérique il faut toujours sélectionner
ses objets d'origine avec SelectObject.
Le handle de ces objets étant retourné par la fonction SelectObject.
Pour la forme nous dessinerons ensuite un cercle à l'aide le la fonction
Ellipse et d'un pinceau à hachures diagonales croisés, puis un trait bleu
à l'aide des fonctions MoveToEx qui positionne le point de départ
et LineTo qui trace jusqu'au point d'arrivée quelle reçoit comme paramètre
et qui devient le nouveau point de départ.
Nous n'avons vu que quelques fonctions de dessin, veuillez consulter l'aide
API Win32 pour plus de détail.
hbGreen = CreateHatchBrush(HS_DIAGCROSS, 0x0000BB00);
SelectObject(hdc,hbGreen);
DeleteObject(hbRed);
Ellipse(hdc, 300, 20, 400, 120);
MoveToEx(hdc, 20, 140, NULL);
LineTo(hdc, 400, 140);
Je vous invite de même à consulter l'aide Win32 API pour voir toutes les possibilités
que fournissent les crayons et les pinceaux.
Les polices de caractères :
Nous avons dessiné une chaîne de caractère sur la fenêtre, mais comme vous
le savez Windows peut utiliser d'autres polices de caractères installées sur le système
tel les polices "True Type".
Pour les utiliser le principe est semblable aux crayons ou pinceaux.
Il faut créer l'objet police avec CreateFont ou CreateFontIndirect
qui retournent un handle de police. Dans l'exemple nous utiliserons
CreateFontIndirect car elle est plus simple à utiliser.
CreateFontIndirect utilise une structure LOGFONT pour initialiser la police.
Nous remplirons seulement deux de ses champs dans l'exemple pour qu'il reste simple.
Les autres serons initialisé à zéro à l'aide de la fonction ZeroMemory :
HFONT NewFont, OldFont;
LOGFONT lf;
/*... ...*/
ZeroMemory(&lf, sizeof(LOGFONT));
lstrcpy(lf.lfFaceName,"Times New Roman");
lf.lfHeight = 36;
NewFont = CreateFontIndirect(&lf);
OldFont = SelectObject(hdc,NewFont);
SetTextColor(hdc, 0x000000FF);
TextOut(hdc, 10, 180, st, lstrlen(st));
SelectObject(hdc,OldFont);
DeleteObject(NewFont);
Première opération, remplir les champs de la variable lf de type LOGFONT.
Elle possède un champ lfFaceName : tableau de caractères où nous copions le nom de la police
que nous désirons utiliser avec la fonction lstrcpy.
Ce tableau a une taille de 32 caractères (y compris le zéro terminal).
Nous mettons le champ lfHeight correspondant à la hauteur des caractères à 36.
Nous positionnerons le champ lfItalic à true et le champ lfWeight
à FW_BOLD pour écrire la chaîne de caractères en gras italique.
Tout comme pour les crayons ou pinceaux, il faut sélectionner les objets Fonts
pour les utiliser et les détruire après utilisation, sans oublier de sélectionner
la police d'origine avant de libérer le contexte de périphérique.
Pour plus de précisions sur les polices de caractères, veuillez consulter l'aide
API Win32.
Code complet :
#include <windows.h>
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
wc.lpszMenuName = NULL;
wc.lpszClassName = "MaWinClass";
if(!RegisterClass(&wc)) return FALSE;
hwnd = CreateWindow("MaWinClass", "Dessiner", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 460, 300,
NULL, NULL, hinstance, NULL);
if (!hwnd) return FALSE;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
/******************************************************************************/
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT :
{
HBRUSH hbRed, hbGreen, hbrOld;
HPEN hp2px, hpOld;
HFONT NewFont, OldFont;
LOGFONT lf;
char st[] = "Bienvenue sur Developpez.com" ;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc, 10, 20, st, lstrlen(st));
Rectangle(hdc, 20, 60, 120, 100);
hp2px = CreatePen(PS_SOLID, 2, 0x00FF0000);
hpOld = SelectObject(hdc,hp2px);
hbRed = CreateSolidBrush(0x000000FF);
hbrOld = SelectObject(hdc,hbRed);
Rectangle(hdc, 160, 60, 260, 100);
hbGreen = CreateHatchBrush(HS_DIAGCROSS, 0x0000BB00);
SelectObject(hdc,hbGreen);
DeleteObject(hbRed);
Ellipse(hdc, 300, 20, 400, 120);
MoveToEx(hdc, 20, 140, NULL);
LineTo(hdc, 400, 140);
SelectObject(hdc,hbrOld);
DeleteObject(hbGreen);
SelectObject(hdc,hpOld);
DeleteObject(hp2px);
ZeroMemory(&lf, sizeof(LOGFONT));
lstrcpy(lf.lfFaceName,"Times New Roman");
lf.lfHeight = 36;
lf.lfItalic = TRUE;
lf.lfWeight = FW_BOLD;
NewFont = CreateFontIndirect(&lf);
OldFont = SelectObject(hdc,NewFont);
SetTextColor(hdc, 0x000000FF);
TextOut(hdc, 10, 180, st, lstrlen(st));
SelectObject(hdc,OldFont);
DeleteObject(NewFont);
EndPaint(hwnd, &ps);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
A vos PC.
CGi
Avec la contribution de nico-pyright(c) pour la relecture.
|