Créer un bitmap en appliquant une font, une couleur de fond et une couleur à un texte.

Description

Ce code est un exemple pour transformer un DeviceContext en un fichier BMP.

Il permet aussi de selectionner une font

de choisir le texte (changement dans le code, possibilité d'améliorer)

de choisir la couleur de fond et la couleur du texte

Cet exemple montre comment créer un bitmap pour en faire une sprite.

le fichier finalbmp.bmp se place ou s'execute l'exe

le tout en WIN32 sans MFC

Source / Exemple :


// test.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include <windows.h>
#include <Commdlg.h>
#include <conio.h>
#include <stdlib.h>

// ID(identificateur) du bouton
#define ID_BUTTON_1 100
#define ID_BUTTON_2 101
#define ID_BUTTON_3 102
#define ID_BUTTON_4 103
#define ID_STATIC    104

// Handle de la fenêtre
HWND winhWnd;
HWND cmdhWnd1,cmdhWnd2,cmdhWnd3,cmdhWnd4;
HWND imghWnd;
HINSTANCE hInstance;
HFONT hFont;
COLORREF colorBack,colorFont;
bool bAffiche1 = false;
bool bAffiche2 = false;
bool bAffiche3 = false;
HBITMAP hBmpFinal;
HDC hDCBmp;

// Procédure qui va recevoir les messages
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
HFONT ChoisirPolice();
COLORREF ChoisirColor();
void OnButtonSetFont();
void OnButtonSetBackColor();
void OnButtonSetFontColor();
void OnButtonGenerate();
void AfficherResultat();
void SaveBitmap(HDC hdc,int cxClient,int cyClient, char *pszflname);

// Entré du programme
int APIENTRY WinMain(HINSTANCE FirstInstance, HINSTANCE PrevInstance, LPSTR CmdLine, int CmdShow)
{

MSG msg;
WNDCLASSEX wc;

        hInstance = FirstInstance;
        // Création de la classe
        wc.hInstance = FirstInstance;   // Instance
        wc.lpszClassName = "TheFontBitmap"; // Nom de la classe
        wc.lpfnWndProc = WinProc;   // Adresse de la procédure
        wc.style = CS_DBLCLKS;  // Style
        wc.cbSize = sizeof(WNDCLASSEX); // Taille
        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // Grande icone
        wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);   // Petite icone
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);   // Curseur
        wc.lpszMenuName = NULL; // Menu
        wc.cbClsExtra = 0;  // ...
        wc.cbWndExtra = 0;  // ...
        wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);    // Couleur de fond

        // Enregistre la classe
        if (!RegisterClassEx(&wc))
        {
            // Échec
            MessageBox(NULL, "Erreur lors de l'enregistrement de la classe.", "Erreur", MB_OK);
            return 0;

        }

        // Création de la fenêtre
        winhWnd = CreateWindowEx(0, "TheFontBitmap", "TheFontBitmap", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
            640, 480, HWND_DESKTOP, NULL, FirstInstance, NULL);

        if (winhWnd == NULL)
        {
            // Échec
            MessageBox(NULL, "Erreur lors de la création de la fenêtre.", "Erreur", MB_OK);
            return 0;

        }

        // Création du bouton
        cmdhWnd1 = CreateWindowEx(0, "BUTTON", "", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_NOTIFY|BS_TEXT,
            10, 10, 100, 40, winhWnd, (HMENU)ID_BUTTON_1, FirstInstance, NULL);

        if (cmdhWnd1 == NULL)
        {
            // Échec
            MessageBox(winhWnd, "Erreur lors de la création du Bouton.", "Erreur", MB_OK);
            return 0;

        }

        // Création du bouton
        cmdhWnd2 = CreateWindowEx(0, "BUTTON", "", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_NOTIFY|BS_TEXT,
            10, 60, 100, 40, winhWnd, (HMENU)ID_BUTTON_2, FirstInstance, NULL);

        if (cmdhWnd2 == NULL)
        {
            // Échec
            MessageBox(winhWnd, "Erreur lors de la création du Bouton.", "Erreur", MB_OK);
            return 0;

        }

        // Création du bouton
        cmdhWnd3 = CreateWindowEx(0, "BUTTON", "", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_NOTIFY|BS_TEXT,
            10, 110, 100, 40, winhWnd, (HMENU)ID_BUTTON_3, FirstInstance, NULL);

        if (cmdhWnd3 == NULL)
        {
            // Échec
            MessageBox(winhWnd, "Erreur lors de la création du Bouton.", "Erreur", MB_OK);
            return 0;

        }

        // Création du bouton
        cmdhWnd4 = CreateWindowEx(0, "BUTTON", "", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_NOTIFY|BS_TEXT,
            10, 160, 100, 40, winhWnd, (HMENU)ID_BUTTON_4, FirstInstance, NULL);

        if (cmdhWnd4 == NULL)
        {
            // Échec
            MessageBox(winhWnd, "Erreur lors de la création du Bouton.", "Erreur", MB_OK);
            return 0;

        }

        imghWnd = CreateWindowEx(WS_EX_CLIENTEDGE, "STATIC", NULL, WS_VISIBLE|WS_CHILD|SS_ICON,
            120, 10, 505, 400, winhWnd, (HMENU)ID_STATIC, hInstance, NULL);

        if(imghWnd == NULL)
        {
            // Échec
            MessageBox(winhWnd, "Erreur lors de la création du Static.", "Erreur", MB_OK);
            return 0;
        }

        // Affiche la fenêtre
        ShowWindow(winhWnd, SW_SHOW);
        // Met à jour la fenêtre
        UpdateWindow(winhWnd);

        // Envoie tu texte dans le bouton(Caption)
        SetWindowText(cmdhWnd1, "Set Font");

        // Met à jour le bouton
        UpdateWindow(cmdhWnd1);
        // Donne le focus au bouton
        SetFocus(cmdhWnd1);

         // Envoie tu texte dans le bouton(Caption)
        SetWindowText(cmdhWnd2, "Set BackColor");

        // Met à jour le bouton
        UpdateWindow(cmdhWnd2);
        // Donne le focus au bouton
        SetFocus(cmdhWnd2);

        // Envoie tu texte dans le bouton(Caption)
        SetWindowText(cmdhWnd3, "Set FontColor");

        // Met à jour le bouton
        UpdateWindow(cmdhWnd3);
        // Donne le focus au bouton
        SetFocus(cmdhWnd3);

        // Envoie tu texte dans le bouton(Caption)
        SetWindowText(cmdhWnd4, "Generate");

        

        // Met à jour le bouton
        UpdateWindow(cmdhWnd4);
        // Donne le focus au bouton
        SetFocus(cmdhWnd4);

        

        // Boucle qui permet au programme de rester ouvert :)
        while (GetMessage(&msg, NULL, 0, 0))
        {

            TranslateMessage(&msg);
            DispatchMessage(&msg);

        }

        // Fin du programme
        return msg.wParam;

}

// Réception des messages
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    
        switch (msg)
        {

            // Fermeture du programme
            case WM_DESTROY:

                    // Ferme le programme
                    PostQuitMessage(0);
                    break;

            // Fermeture de la fenêtre via le menu système ou la croix(X) noir
            case WM_CLOSE:

                    // Détruit la fenêtre
                    DestroyWindow(hwnd);
                    break;

            // Réception des commandes
            case WM_COMMAND:

                    // Vérifie que c'est bien le bouton Vérifie si on à cliquer sur le bouton
					if (wParam == MAKELONG(ID_BUTTON_1, BN_CLICKED))
                    //if ((LOWORD(wParam) == ID_BUTTON_1) && (HIWORD(wParam) == BN_CLICKED))
                    {
                        OnButtonSetFont();
                    }

                    if (wParam == MAKELONG(ID_BUTTON_2, BN_CLICKED))
					//if ((LOWORD(wParam) == ID_BUTTON_2) && (HIWORD(wParam) == BN_CLICKED))
                    {
                        OnButtonSetBackColor();
                    }
					if (wParam == MAKELONG(ID_BUTTON_3, BN_CLICKED))
                    //if ((LOWORD(wParam) == ID_BUTTON_3) && (HIWORD(wParam) == BN_CLICKED))
                    {
                        OnButtonSetFontColor();
                    }

					if (wParam == MAKELONG(ID_BUTTON_4, BN_CLICKED))
                    //if ((LOWORD(wParam) == ID_BUTTON_4) && (HIWORD(wParam) == BN_CLICKED))
                    {
                        OnButtonGenerate();
                    }
                    break;

            

            default:
                    return DefWindowProc(hwnd, msg, wParam, lParam);
                    break;

        }

        return 0;

}

HFONT ChoisirPolice()
{
    CHOOSEFONT cf;      // Structure common dialog
    LOGFONT lf;          // Paramètre LOGFONT 
    //HWND hwnd;                // HANDLE de la fenêtre
    //HFONT hfont;              // Police qui va être crée

    // Initialisation de la Structure CHOOSEFONT
    cf.lStructSize = sizeof (CHOOSEFONT);
    cf.hwndOwner = winhWnd;
    cf.lpLogFont = &lf;
    cf.Flags = CF_SCREENFONTS | CF_EFFECTS;

    if (ChooseFont(&cf)==TRUE)  
        return CreateFontIndirect(cf.lpLogFont);
    else 
        return 0;

    
} 

COLORREF ChoisirColor()
{
    CHOOSECOLOR cc;     // Structure common dialog
    COLORREF color;
    //HWND hwnd;                // HANDLE de la fenêtre
    //HFONT hfont;              // Police qui va être crée

    // Initialisation de la Structure CHOOSEFONT
    cc.lStructSize      = sizeof(cc);
    cc.hwndOwner        = winhWnd;
    //cc.hInstance      = hInstance;
    cc.Flags            = CC_ANYCOLOR;

    cc.rgbResult        = RGB(0,0,0);
    cc.lpCustColors  = &color;

    if (ChooseColor(&cc)==TRUE) 
        return cc.rgbResult;
    else 
        return -1;

    
} 

void OnButtonSetFont()
{
    //SendMessage(cmdhWnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0));

    hFont = ChoisirPolice();
    if(hFont == 0)
    {
        bAffiche1 = false;
        return;
    }
    //choisi la police et l'applique
    SendMessage(cmdhWnd1, WM_SETFONT,(WPARAM)hFont, TRUE);

    // Affiche la fenêtre
    ShowWindow(winhWnd, SW_SHOW);
    // Met à jour la fenêtre
    UpdateWindow(winhWnd);

    // Envoie tu texte dans le bouton(Caption)
    SetWindowText(cmdhWnd1, "Set Font");

    // Met à jour le bouton
    UpdateWindow(cmdhWnd1);
    // Donne le focus au bouton
    SetFocus(cmdhWnd1);

    bAffiche1 = true;
    AfficherResultat();
}

void OnButtonSetBackColor()
{
    SetWindowText(cmdhWnd2, "");
    colorBack = ChoisirColor();
    if(colorBack == -1)
    {
        bAffiche2 = false;
        return;
    }
    char *text="Set BackColor";
    HDC hDC;
    RECT rcClient;
    GetClientRect(cmdhWnd2,&rcClient);
    hDC=GetDC(cmdhWnd2);
    SetTextColor(hDC,0x00000000);
    SetBkColor(hDC,colorBack);
    //SetBkMode(hDC,TRANSPARENT);
    SetTextAlign(hDC,TA_CENTER|TA_TOP|VTA_CENTER);
    TextOut(hDC,(int)((float)rcClient.right/2),11,text,strlen(text));
    ReleaseDC(cmdhWnd2,hDC);
    bAffiche2 = true;
    AfficherResultat();
}

void OnButtonSetFontColor()
{
    
    SetWindowText(cmdhWnd3, "");
    colorFont = ChoisirColor();
    if(colorFont == -1)
    {
        bAffiche3 = false;
        return;
    }
    char *text="Set FontColor";
    HDC hDC;
    RECT rcClient;
    GetClientRect(cmdhWnd3,&rcClient);
    hDC=GetDC(cmdhWnd3);
    SetTextColor(hDC,colorFont);
    SetTextAlign(hDC,TA_CENTER|TA_TOP|VTA_CENTER);
    TextOut(hDC,(int)((float)rcClient.right/2),11,text,strlen(text));
    ReleaseDC(cmdhWnd3,hDC);

    bAffiche3 = true;
    AfficherResultat();
    
}

void OnButtonGenerate()
{
    
    RECT rcClient;

    char *text="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char *text2="abcdefghijklmnopqrstuvwxyz";
    char *text3="0123456789";

    GetClientRect(imghWnd,&rcClient);
    int cxClient = rcClient.right-rcClient.left;
    int cyClient = rcClient.bottom-rcClient.top;

    hDCBmp = GetDC(imghWnd);
    
    SelectObject(hDCBmp,(HGDIOBJ)hFont);

    HBRUSH hWhiteBrush = CreateSolidBrush(colorBack);
    FillRect(hDCBmp, &rcClient, hWhiteBrush);
    DeleteObject(hWhiteBrush);

    SetTextColor(hDCBmp,colorFont);
    SetBkColor(hDCBmp,colorBack);
    SetTextAlign(hDCBmp,TA_CENTER);

    int size;

    size = ((int)strlen(text)-1);
    for(int i=0;i<=size;i++)
    {
        TextOut(hDCBmp,(13*(i+1)),10,text,1);
        
        text++;
    }
    text = text - size+1;

    size = ((int)strlen(text2)-1);
    for(i=0;i<=size;i++)
    {
        TextOut(hDCBmp,(13*(i+1)),50,text2,1);
        text2++;
    }
    text2 = text2 - size+1;

    size = ((int)strlen(text3)-1);
    for(i=0;i<=size;i++)
    {
        TextOut(hDCBmp,(13*(i+1)),100,text3,1);
        text3++;
    }
    text3 = text3 - size+1;

    hBmpFinal = CreateCompatibleBitmap(hDCBmp, cxClient, cyClient);

    SaveBitmap(hDCBmp,cxClient,cyClient,"finalbmp.bmp");

    SendMessage(imghWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmpFinal);

    ReleaseDC(imghWnd,hDCBmp);
    
}

void AfficherResultat()
{
    if((bAffiche1==true) && (bAffiche2==true) && (bAffiche3==true))
    {
        //choisi la police et l'applique
        //SendMessage(cmdhWnd4,WM_ENABLE,TRUE,NULL);
    }
    else
    {
        //SendMessage(cmdhWnd4,WM_ENABLE,FALSE,NULL);
    }
    return;
}

void SaveBitmap(HDC hdc,int cxClient,int cyClient, char *pszflname)
{
    HDC memdc;
    HANDLE hfl;
    DWORD dwBytes, dwWidth, dwHeight, dwNumColors, dwBPP, ColorSize;
    void *pBits;
    HBITMAP hbmp;
    BITMAPFILEHEADER fileheader;
    BITMAPINFOHEADER infoheader;
    RGBQUAD colors[256];
    BITMAPINFO bmpinfo;
    HGDIOBJ hret;
    dwWidth = cxClient;
    dwHeight = cyClient;
    dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
    if(dwBPP <= 8) dwNumColors = 256;
    else dwNumColors = 0;
    if(!(memdc = CreateCompatibleDC(hdc))) return;
    bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpinfo.bmiHeader.biWidth = dwWidth;
    bmpinfo.bmiHeader.biHeight = dwHeight;
    bmpinfo.bmiHeader.biPlanes = 1;
    bmpinfo.bmiHeader.biBitCount = (WORD) dwBPP;
    bmpinfo.bmiHeader.biCompression = BI_RGB;
    bmpinfo.bmiHeader.biSizeImage = 0;
    bmpinfo.bmiHeader.biXPelsPerMeter = 0;
    bmpinfo.bmiHeader.biYPelsPerMeter = 0;
    bmpinfo.bmiHeader.biClrUsed = dwNumColors;
    bmpinfo.bmiHeader.biClrImportant = dwNumColors;
    hbmp = CreateDIBSection(hdc, &bmpinfo, DIB_PAL_COLORS, &pBits, NULL, 0);
    if(!hbmp) goto errato;
    hret = SelectObject(memdc, hbmp);
    if(!hret || (hret == HGDI_ERROR)) goto errato;
    if(!BitBlt(memdc, 0, 0, dwWidth, dwHeight, hdc, 0, 0, SRCCOPY)) goto errato;
    if(dwNumColors) dwNumColors = GetDIBColorTable(memdc, 0, dwNumColors, colors);
    fileheader.bfType = 0x4D42;
    ColorSize = dwNumColors * sizeof(RGBQUAD);
    fileheader.bfSize = ((dwWidth*dwHeight*dwBPP) >> 3)+ColorSize+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
    fileheader.bfReserved1 = fileheader.bfReserved2 = 0;
    fileheader.bfOffBits = ColorSize+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
    infoheader.biSize = sizeof(BITMAPINFOHEADER);
    infoheader.biWidth = dwWidth;
    infoheader.biHeight = dwHeight;
    infoheader.biPlanes = 1;
    infoheader.biBitCount = (WORD) dwBPP;
    infoheader.biCompression = BI_RGB;
    infoheader.biSizeImage = infoheader.biClrImportant = 0;
    infoheader.biXPelsPerMeter = infoheader.biYPelsPerMeter = 0;
    infoheader.biClrUsed = dwNumColors;
    hfl = CreateFile(pszflname,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
    if(hfl == INVALID_HANDLE_VALUE) {DeleteObject(hbmp); goto errato;}
    WriteFile(hfl, &fileheader, sizeof(BITMAPFILEHEADER), &dwBytes, 0);
    WriteFile(hfl, &infoheader, sizeof(BITMAPINFOHEADER), &dwBytes, 0);
    if(!dwNumColors) WriteFile(hfl, colors, ColorSize, &dwBytes, 0);
    ColorSize = (dwWidth*dwHeight*dwBPP) >> 3;
    WriteFile(hfl, pBits, ColorSize, &dwBytes, 0);
    CloseHandle(hfl);
    DeleteObject(hbmp);
    DeleteDC(memdc);
    return ;
errato:
    DeleteDC(memdc); return ;
}

Conclusion :


Je tiens à remercier particulièrement BruNews pour sa fonction permettant d'enregister le hDC dans un fichier bitmap.

Codes Sources

A voir également

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.