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.
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.