cs_jfrancois
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009
2
14 mai 2008 à 16:11
Bonjour,
Voici un petit programme Win32 en C qui gère une image de fond de 3 façons différentes (dupliquée, étirée ou centrée) et provenant soit des ressources du programmes soit d'un fichier ayant le même nom que l'application mais avec l'extension "bmp" (dans le même répertoire que l'application, ça permet à l'utilisateur de "customiser" le programme !).
La maquette originale de ce programme est en C++. J'espère que je l'ai bien passée en C : Commentaires entre /* */ et variables déclarées en début de blocs !
Fichier source Test.c (par exemple) :
/* ================================== */
/* Fenêtre Windows avec image de fond */
/* ================================== */
#include <windows.h>
#include <commctrl.h>
/* --- Librairie pour "InitCommonControls()" */
#pragma comment(lib,"comctl32.lib")
/* --- Constante nouvelle dans l'API */
/* --- (inexistante quand Microsoft Visual C++ 6.0 est sorti !) */
#if _MSC_VER <= 1200
#define CS_DROPSHADOW 0x00020000
#endif
/* --- Constantes */
#define ID_ZONE_EDIT 1000
#define ID_ZONE_STATIC 1001
#define ID_RADIOBOUTON_DUPLIQUER 1002
#define ID_RADIOBOUTON_ETIRER 1003
#define ID_RADIOBOUTON_CENTRER 1004
#define ID_BOUTON_QUITTER 1005
/* --- Instance de l'application */
static HINSTANCE g_hInstance = NULL;
/* --- Largeur et hauteur de la fenêtre */
static int g_iFenetreLargeur = 400;
static int g_iFenetreHauteur = 300;
/* --- Type de remplissage par défaut de la zone client */
static int g_iTypeRemplissage = ID_RADIOBOUTON_DUPLIQUER;
/* --- Prototypes des fonctions locales */
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int);
LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);
/* =================== */
/* Fonction principale */
/* =================== */
int WINAPI WinMain
(
HINSTANCE hInstance /* E:instance courante */
,HINSTANCE hInstancePrec /* E:instance précédente */
,LPSTR pszLigneCommande /* E:ligne de commande */
,int iModeAffichage /* E:mode d'affichage */
) /* S:code retour */
{
/* --- Variables locales */
HDC hDCScreen;
HWND hWnd;
MSG Msg;
WNDCLASSEX WndClass;
static const char* szNomClasse = "TestClassName";
/* --- Initialiser */
g_hInstance = hInstance;
InitCommonControls();
/* --- Enregistrer la classe de la fenêtre */
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = 0;
WndClass.lpfnWndProc = WinProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = g_hInstance;
WndClass.hIcon = LoadIcon(g_hInstance,"ICON_APP");
WndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = szNomClasse;
WndClass.hIconSm = NULL;
if (! RegisterClassEx(&WndClass)) return 0;
/* --- Largeur et hauteur de l'écran */
hDCScreen = CreateDC("DISPLAY","","",NULL);
int iEcranLargeur = GetDeviceCaps(hDCScreen,HORZRES);
int iEcranHauteur = GetDeviceCaps(hDCScreen,VERTRES);
/* --- Créer la fenêtre (centrée sur l'écran) */
hWnd = CreateWindowEx
(
0
,szNomClasse
,"Exemple"
,WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX
,(iEcranLargeur - g_iFenetreLargeur) / 2 /* x */
,(iEcranHauteur - g_iFenetreHauteur) / 2 /* y */
,g_iFenetreLargeur /* largeur */
,g_iFenetreHauteur /* hauteur */
,(HWND)NULL
,(HMENU)NULL
,g_hInstance
,(LPVOID)NULL
);
if (hWnd == NULL) return 0;
/* --- Montrer la fenêtre */
ShowWindow(hWnd,iModeAffichage);
UpdateWindow(hWnd);
/* --- Traiter les messages de la fenêtre */
while (GetMessage(&Msg,NULL,0,0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
/* ================================== */
/* Traiter les messages de la fenêtre */
/* ================================== */
LRESULT CALLBACK WinProc
(
HWND hWnd /* E:handle de la fenêtre */
,UINT uiMsg /* E:message à traiter */
,WPARAM wParam /* E:paramètre WPARAM */
,LPARAM lParam /* E:paramètre LPARAM */
) /* S:code retour */
{
/* --- Variables locales permanentes */
static HBITMAP hBitmapBg = NULL;
static HDC hBitmapBgDC = NULL;
static HFONT hFontTexte = NULL;
switch (uiMsg)
{
/* ---------------- */
/* Créer la fenêtre */
/* ---------------- */
case WM_CREATE:
{
/* --- Variables locales */
HDC hDC;
HMODULE hModule;
HWND hWndEdit,hWndStatic,hWndDupliquer,hWndEtirer,hWndCentrer,hWndQuitter;
int iBordLargeur,iBordHauteur,iTitreHauteur,iMarge,iBoutonLargeur,iBoutonHauteur,iLargeurDispo;
/* --- Remplacer la petite icône standard dans la barre de titre */
SetClassLong(hWnd,GCL_HICON,(long)LoadIcon(g_hInstance,"ICON_APPLICATION"));
/* --- Ajouter un ombrage à la fenêtre !!! */
SetClassLong(hWnd,GCL_STYLE,GetClassLong(hWnd,GCL_STYLE) | CS_DROPSHADOW);
/* --- Créer le nom du fichier image */
/* --- (nom de l'appli avec extension "bmp" à la place de "exe") */
hModule = GetModuleHandle(NULL);
char szNomFichier[MAX_PATH];
GetModuleFileName(hModule,szNomFichier,MAX_PATH);
szNomFichier[strlen(szNomFichier) - 3] = 0; /* - "exe" */
strcat(szNomFichier,"bmp"); /* + "bmp" */
/* --- Charger le bitmap en mémoire */
hDC = GetDC(hWnd);
hBitmapBgDC = CreateCompatibleDC(hDC);
if (hBitmapBgDC)
{
/* --- Charger le fichier image */
hBitmapBg = (HBITMAP)LoadImage(0,szNomFichier,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
/* --- Si le fichier n'a pas été chargé (inexistant ?) */
/* --- alors charger le bitmap défini dans les ressources */ if (hBitmapBg NULL) hBitmapBg LoadBitmap(g_hInstance,(LPCTSTR)"BITMAP_BACKGROUND");
/* --- Selectionner en mémoire le bitmap (fichier ou ressource) */
if (hBitmapBg) SelectObject(hBitmapBgDC,hBitmapBg);
}
ReleaseDC(hWnd,hDC);
/* --- Fonte de caractères pour les textes */
/* --- (pour remplacer l'inesthétique fonte par défaut) */
hFontTexte = CreateFont
(
-MulDiv(10,GetDeviceCaps(GetDC(hWnd),LOGPIXELSY),72),0,0,0
,FW_NORMAL /* graisse */
,(DWORD)TRUE /* italique */
,(DWORD)FALSE /* souligné */
,(DWORD)FALSE /* barré */
,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS
,PROOF_QUALITY,DEFAULT_PITCH | FF_SWISS
,"Verdana"
);
/* --- Dimensions autour de la zone clients */
/* --- (bordure, barre de titre, marge dans la zone client! */
iBordLargeur = GetSystemMetrics(SM_CXFIXEDFRAME);
iBordHauteur = GetSystemMetrics(SM_CYFIXEDFRAME);
iTitreHauteur = GetSystemMetrics(SM_CYCAPTION);
iMarge = 10;
iLargeurDispo = g_iFenetreLargeur - 2 * (iMarge + iBordLargeur);
/* --- Créer un contrôle EDIT (zone de saisie) */
/* --- sur toute la largeur disponible hors marges */
hWndEdit = CreateWindowEx
(
0
,"EDIT"
,"Contrôle de type EDIT modifiable"
,WS_VISIBLE | WS_CHILD | WS_BORDER
,iMarge,iMarge /* x,y */
,iLargeurDispo,20 /* largeur,hauteur */
,hWnd
,(HMENU)ID_ZONE_EDIT
,g_hInstance
,NULL
);
SendMessage(hWndEdit,WM_SETFONT,(WPARAM)hFontTexte,(LPARAM)TRUE);
/* --- Créer un contrôle STATIC (zone non saisissable) */
/* --- sur toute la largeur disponible hors marges */
hWndStatic = CreateWindowEx
(
0
,"STATIC"
,"Contrôle de type STATIC non modifiable"
,WS_VISIBLE | WS_CHILD | WS_BORDER | ES_CENTER
,iMarge,50 /* x,y */
,iLargeurDispo,20 /* largeur,hauteur */
,hWnd
,(HMENU)ID_ZONE_STATIC
,g_hInstance
,NULL
);
SendMessage(hWndStatic,WM_SETFONT,(WPARAM)hFontTexte,(LPARAM)TRUE);
/* --- Radioboutons de sélection du type de remplissage */
hWndDupliquer = CreateWindowEx
(
0
,"BUTTON"
,"Bitmap dupliqué pour remplir la zone client"
,WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON
,iMarge,90 /* x,y */
,iLargeurDispo,20 /* largeur,hauteur */
,hWnd
,(HMENU)ID_RADIOBOUTON_DUPLIQUER
,g_hInstance
,NULL
);
SendMessage(hWndDupliquer,WM_SETFONT,(WPARAM)hFontTexte,(LPARAM)TRUE);
hWndEtirer = CreateWindowEx
(
0
,"BUTTON"
,"Bitmap étiré pour remplir la zone client"
,WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON
,iMarge,120 /* x,y */
,iLargeurDispo,20 /* largeur,hauteur */
,hWnd
,(HMENU)ID_RADIOBOUTON_ETIRER
,g_hInstance
,NULL
);
SendMessage(hWndEtirer,WM_SETFONT,(WPARAM)hFontTexte,(LPARAM)TRUE);
hWndCentrer = CreateWindowEx
(
0
,"BUTTON"
,"Bitmap unique centré dans la zone client"
,WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON
,iMarge,150 /* x,y */
,iLargeurDispo,20 /* largeur,hauteur */
,hWnd
,(HMENU)ID_RADIOBOUTON_CENTRER
,g_hInstance
,NULL
);
SendMessage(hWndCentrer,WM_SETFONT,(WPARAM)hFontTexte,(LPARAM)TRUE);
/* --- Positionner le radiobouton par défaut */
CheckRadioButton
(
hWnd
,ID_RADIOBOUTON_DUPLIQUER /* ID premier radiobouton */
,ID_RADIOBOUTON_CENTRER /* ID dernier radiobouton */
,g_iTypeRemplissage /* ID radiobouton à positionner */
);
/* --- Bouton pour quitter */
/* --- (cadré en bas à droite) */
iBoutonLargeur = 100;
iBoutonHauteur = 30;
hWndQuitter = CreateWindowEx
(
0
,"BUTTON"
,"Quitter"
,WS_CHILD | WS_VISIBLE
,g_iFenetreLargeur - iBordLargeur - iMarge - iBoutonLargeur /* x */
,g_iFenetreHauteur - iBordHauteur - iMarge - iBoutonHauteur - iTitreHauteur /* y */
,iBoutonLargeur,iBoutonHauteur /* largeur,hauteur */
,hWnd
,(HMENU)ID_BOUTON_QUITTER
,g_hInstance
,NULL
);
SendMessage(hWndQuitter,WM_SETFONT,(WPARAM)hFontTexte,(LPARAM)TRUE);
/* --- Focus dans le control EDIT */
SetFocus(hWndEdit);
}
return 0;
/* ----------------------- */
/* Peindre l'image de fond */
/* ----------------------- */
case WM_PAINT :
{
/* --- Variables locales */
PAINTSTRUCT Paint;
HDC hDC;
RECT Client;
BITMAP Bitmap;
int iRet,iX,iY,iBX,iBY;
/* --- Quitter si le bitmap n'a pas pu être créé */
if (hBitmapBg == NULL) return 0;
/* --- DÉBUT DU REMPLISSAGE */
hDC = BeginPaint(hWnd,&Paint);
if (hDC == NULL) return 0;
/* --- Dimensions de la zone client */
/* --- Client.right = largeur de la zone client */
/* --- Client.bottom = hauteur de la zone client */
GetClientRect(hWnd,&Client);
/* --- Dimensions du bitmap */
iRet = GetObject(hBitmapBg,sizeof(BITMAP),&Bitmap);
if (iRet == 0) return 0;
/* --- Remplir la zone client */
switch(g_iTypeRemplissage)
{
/* --- Dupliquer le bitmap dans la zone client */
case ID_RADIOBOUTON_DUPLIQUER :
{
for (iX=0 ; iX<Client.right ; iX+=Bitmap.bmWidth)
for (iY=0 ; iY<Client.bottom ; iY+=Bitmap.bmHeight)
BitBlt(hDC,iX,iY,Bitmap.bmWidth,Bitmap.bmHeight,hBitmapBgDC,0,0,SRCCOPY);
}
break;
/* --- Etirer le bitmap aux dimensions de la zone client */
case ID_RADIOBOUTON_ETIRER :
StretchBlt(hDC,0,0,Client.right,Client.bottom
,hBitmapBgDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,SRCCOPY);
break;
/* --- Centrer le bitmap dans la zone client */
case ID_RADIOBOUTON_CENTRER :
{ iX (Client.right - Bitmap.bmWidth) / 2; if (iX < 0) iX 0; iY (Client.bottom - Bitmap.bmHeight) / 2; if (iY < 0) iY 0; iBX (Bitmap.bmWidth - Client.right) / 2; if (iBX < 0) iBX 0; iBY (Bitmap.bmHeight - Client.bottom) / 2; if (iBY < 0) iBY 0;
BitBlt(hDC,iX,iY,Client.right,Client.bottom,hBitmapBgDC,iBX,iBY,SRCCOPY);
}
break;
}
/* --- FIN DU REMPLISSAGE */
EndPaint(hWnd,&Paint);
}
return 0;
/* ------------------------------------------ */
/* Changer la couleur dans les contrôles EDIT */
/* ------------------------------------------ */
case WM_CTLCOLOREDIT :
{
/* --- Variable locale */
int iID;
/* --- Identificateur du contrôle statique */
iID = GetDlgCtrlID((HWND)lParam);
if (iID == ID_ZONE_EDIT)
{
/* --- Zone EDIT */
SetBkMode((HDC)wParam,TRANSPARENT);
SetTextColor((HDC)wParam,RGB(0,255,0)); /* vert */
}
}
return (LRESULT)GetStockObject(BLACK_BRUSH); /* fond noir */
/* -------------------------------------------- */
/* Changer la couleur dans les contrôles STATIC */
/* -------------------------------------------- */
case WM_CTLCOLORSTATIC :
{
/* --- Variable locale */
int iID;
/* --- Identificateur du contrôle statique */
iID = GetDlgCtrlID((HWND)lParam);
if (iID == ID_ZONE_STATIC)
{
/* --- Zone STATIC */
SetBkMode((HDC)wParam,TRANSPARENT);
SetTextColor((HDC)wParam,RGB(255,0,0)); /* rouge */
}
else if (iID == ID_RADIOBOUTON_DUPLIQUER)
{
/* --- Radiobouton de duplication */
SetBkMode((HDC)wParam,TRANSPARENT);
SetTextColor((HDC)wParam,RGB(0,0,255)); /* bleu */
}
else if (iID == ID_RADIOBOUTON_ETIRER)
{
/* --- Radiobouton d'étirement */
SetBkMode((HDC)wParam,TRANSPARENT);
SetTextColor((HDC)wParam,RGB(255,255,255)); /* blanc */
}
else if (iID == ID_RADIOBOUTON_CENTRER)
{
/* --- Radiobouton de centrage */
SetBkMode((HDC)wParam,TRANSPARENT);
SetTextColor((HDC)wParam,RGB(255,255,0)); /* jaune */
}
}
return (LRESULT)GetStockObject(NULL_BRUSH); /* fond transparent */
/* -------------------- */
/* Traiter une commande */
/* -------------------- */
case WM_COMMAND:
switch(LOWORD(wParam))
{
/* --- Radiobouton pour le type de remplissage */
case ID_RADIOBOUTON_DUPLIQUER :
case ID_RADIOBOUTON_ETIRER :
case ID_RADIOBOUTON_CENTRER :
g_iTypeRemplissage = LOWORD(wParam);
InvalidateRect(hWnd,NULL,TRUE);
break;
/* --- Quitter */
case ID_BOUTON_QUITTER :
case IDCANCEL :
SendMessage(hWnd,WM_DESTROY,0,0);
break;
}
return 0;
/* --------------------- */
/* Quitter l'application */
/* --------------------- */
case WM_DESTROY:
{
/* --- Détruire les objets */
if (hBitmapBg) DeleteObject((HGDIOBJ)hBitmapBg);
if (hBitmapBgDC) DeleteDC(hBitmapBgDC);
if (hFontTexte) DeleteObject((HGDIOBJ)hFontTexte);
PostQuitMessage(0);
}
return 0;
}
/* ------------------------------- */
/* Retour du traitement par défaut */
/* ------------------------------- */
return DefWindowProc(hWnd,uiMsg,wParam,lParam);
}
Fichier des ressources Test.rc (par exemple) à ajouter au projet :
ICON_APPLICATION ICON DISCARDABLE "Test.ico" // 32x32 pixels
BITMAP_BACKGROUND BITMAP DISCARDABLE "Fond.bmp"
Les bitmaps [en ressource (Fond.bmp) ou en fichier (Test.bmp)] font environ 100 pixels par 100 pixels avec des couleurs intermédiaires (pour voir des textes aussi bien clairs que foncés).
Jean-François