6 - Dessiner

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Après avoir vu les contextes de périphériques, nous allons aborder les principales fonctions de dessin.

Image non disponible

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.

II. 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ères avec TextOut, mais une seule fois. Ensuite, nous tracerons un rectangle au-dessous de la chaîne de caractères :

 
Sélectionnez
              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.

 
Sélectionnez
              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 se 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 (deux 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éés, 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ées, 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 qu'elle 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étails.

 
Sélectionnez
              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.

III. Les polices de caractères

Nous avons dessiné une chaîne de caractères sur la fenêtre, mais comme vous le savez Windows peut utiliser d'autres polices de caractères installées sur le système telles 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 seront initialisés à zéro à l'aide de la fonction ZeroMemory :

 
Sélectionnez
              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.

IV. Code complet

 
Sélectionnez
#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);
    }
}


À vos PC.

CGi

Sommaire

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2013 CGI. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.