Je développe actuellement un projet sous Dev C++ en utilisant une API Windows.
Je voudrais savoir comment insérer une image en arrière plan sur fenetre principale de mon programme (en arrière plan d'un texte par exemple).
J'ai trouvé des aides sur internet pour insérer une BMP mais il me semble (ou alors je n'ai pas bien vu ou compris...) que l'image se met par dessus le texte...On ne peut donc plus rien lire... Et ce n'est ce que je veux...
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
/* --- Largeur et hauteur de l'écran */
hDCScreen = CreateDC("DISPLAY","","",NULL);
int iEcranLargeur = GetDeviceCaps(hDCScreen,HORZRES);
int iEcranHauteur = GetDeviceCaps(hDCScreen,VERTRES);
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);
/* --- 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 */
);
/* --- 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);
/* -------------------- */
/* 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 :
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).
Il n'y a pas de duplication, le message WM_CREATE n'est généré qu'une seule fois. Ajouter une trace du message Windows juste avant le switch(message) dans la procédure de traitement des messages et vous le constaterez sans problème. Voici ce que celà donne pour une exécution complète de ce petit programme :
Merci pour ton aide Jean-François je vais suivre tes directives.... Et voir si ça marche parce que je suis pas sorti, ça a l'air difficile toutes les modifs qu'il faut apporter au winmain() !!!