MinGW et TransparentBlt()

Résolu
Signaler
Messages postés
94
Date d'inscription
lundi 13 janvier 2003
Statut
Membre
Dernière intervention
22 janvier 2009
-
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
-
Hello tout le monde !!

Voilà, je suis plutôt un développeur Delphi, mais vu que je reprends une formation cette année, je me replonge dans le C/C++. Et on en profite pour apprendre à utiliser Eclipse !!

Donc, mon environnement de dev est le suivant :
- Windows XP ou Windows 2000
- Plateforme Eclipse
- Compilateur MinGW

Et maintenant, mon problème :
Je cherche à mapper un ancien projet fait sous Borland C++ 5.0 vers MinGW... J'ai déjà réussi à créer le bon makefile, changer deux ou trois petites choses, et au final, la plupart du code marche bien... Il ne me reste qu'un seul problème :
Sous MinGW, la fonction TransparentBlt() ne fonctionne pas. En fait, dans <wingdi.h>, elle n'est déclarée que si la variable WINVER >= 0x0500, ce qui n'est apparemment pas le cas sous Windows XP... Alors que je lis partout que cette fonction n'est pas compatible avec Win 95/98/NT4 uniquement !

Quelqu'un aurait une idée pour régler ça ? Ou au pire, recréer une fonction correspondant en se basant sur BitBlt avec un masque XOR...

Keep Cool & Be Wild
Divad

3 réponses

Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Fait simplement
#define WINVER 0x0500 avant d'inclure <windows.h> et cela rendra disponible la fonction.
=> ton code sera alors valide pour W2K et XP.

Ce define permet de limiter des fonctionnalités à la compilation. A l'exécution, tu peut toujours faire un GetVersionEx pour signaler la version min qu'il faut

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/using_the_windows_headers.asp
Messages postés
94
Date d'inscription
lundi 13 janvier 2003
Statut
Membre
Dernière intervention
22 janvier 2009
2
Merci bcp pour cette réponse... La technique fonctionne bien !

Malgré tout, je me suis plutôt tourné vers la redéfinition de la fonction : je préfère ne pas trop modifier les variables globales gérées par le compilo !!

Pour régler mon problème, j'ai trouvé une fonction nommé TransparentBltU( ), qui fonctionne avec les mêmes arguments, et qui est également compatible Win 95/98/NT4 !

Pour info, voici la fonction :




bool TransparentBltU(HDC dcDest, int nXOriginDest, int nYOriginDest,



int nWidthDest, int nHeightDest, HDC dcSrc, int nXOriginSrc, int nYOriginSrc,



int nWidthSrc, int nHeightSrc, UINT crTransparent )



//------------------------------------------------------------------



// TransparentBltU permet d'afficher un bitmap en rendant une de



// ses couleurs transparente.



//------------------------------------------------------------------



// Paramètres :



// - HDC dcDest handle du DC de destination



// - int nXOriginDest gauche du cadre de destination



// - int nYOriginDest haut du cadre de destination



// - int nWidthDest largeur du cadre de destination



// - int nHeightDest hauteur du cadre de destination



// - HDC dcSrc handle du DC source



// - int nXOriginSrc gauche du cadre source



// - int nYOriginSrc haut du cadre source



// - int nWidthSrc largeur du cadre source



// - int nHeightSrc hauteur du cadre source



// - UINT crTransparent couleur à rendre transparente



//------------------------------------------------------------------



{



// On vérifie que les cadres source et destination sont valides



if (nWidthDest < 1) return false;



if (nWidthSrc < 1) return false;



if (nHeightDest < 1) return false;



if (nHeightSrc < 1) return false;



// On crée un contexte temporaire



HDC dc = CreateCompatibleDC(NULL);



HBITMAP bitmap = CreateBitmap(nWidthSrc, nHeightSrc, 1,



GetDeviceCaps(dc, BITSPIXEL), NULL);







// Si ça n'a pas marché, on quitte !



if (bitmap == NULL) return false;



HBITMAP oldBitmap = (HBITMAP)SelectObject(dc, bitmap);



if (!BitBlt(dc, 0, 0, nWidthSrc, nHeightSrc, dcSrc, nXOriginSrc,



nYOriginSrc, SRCCOPY)) return false;



HDC maskDC = CreateCompatibleDC(NULL);



HBITMAP maskBitmap = CreateBitmap(nWidthSrc, nHeightSrc, 1, 1, NULL);



if (maskBitmap == NULL) return false;



HBITMAP oldMask = (HBITMAP)SelectObject(maskDC, maskBitmap);



SetBkColor(maskDC, RGB(0,0,0));



SetTextColor(maskDC, RGB(255,255,255));



if (!BitBlt(maskDC, 0,0,nWidthSrc,nHeightSrc,NULL, 0,0,BLACKNESS))



return false;



SetBkColor(dc, crTransparent);



BitBlt(maskDC, 0,0,nWidthSrc,nHeightSrc,dc,0,0,SRCINVERT);



SetBkColor(dc, RGB(0,0,0));



SetTextColor(dc, RGB(255,255,255));



BitBlt(dc, 0,0,nWidthSrc,nHeightSrc,maskDC,0,0,SRCAND);



HDC newMaskDC = CreateCompatibleDC(NULL);



HBITMAP newMask;



newMask = CreateBitmap(nWidthDest, nHeightDest, 1,



GetDeviceCaps(newMaskDC, BITSPIXEL), NULL);



if (newMask == NULL) {



SelectObject(dc, oldBitmap);



DeleteDC(dc);



SelectObject(maskDC, oldMask);



DeleteDC(maskDC);



DeleteDC(newMaskDC);



return false;



}



SetStretchBltMode(newMaskDC, COLORONCOLOR);



HBITMAP oldNewMask = (HBITMAP) SelectObject(newMaskDC, newMask);



StretchBlt(newMaskDC, 0, 0, nWidthDest, nHeightDest,



maskDC, 0, 0, nWidthSrc, nHeightSrc, SRCCOPY);



SelectObject(maskDC, oldMask);



DeleteDC(maskDC);



HDC newImageDC = CreateCompatibleDC(NULL);



HBITMAP newImage = CreateBitmap(nWidthDest, nHeightDest,



1, GetDeviceCaps(newMaskDC, BITSPIXEL), NULL);



if (newImage == NULL) {



SelectObject(dc, oldBitmap);



DeleteDC(dc);



DeleteDC(newMaskDC);



return false;



}



HBITMAP oldNewImage = (HBITMAP)SelectObject(newImageDC, newImage);



StretchBlt(newImageDC, 0, 0, nWidthDest, nHeightDest,



dc, 0, 0, nWidthSrc, nHeightSrc, SRCCOPY);



SelectObject(dc, oldBitmap);



DeleteDC(dc);



BitBlt( dcDest, nXOriginDest, nYOriginDest, nWidthDest,



nHeightDest, newMaskDC, 0, 0, SRCAND);



BitBlt( dcDest, nXOriginDest, nYOriginDest, nWidthDest,



nHeightDest, newImageDC, 0, 0, SRCPAINT);



newImage = (HBITMAP)SelectObject(newImageDC, oldNewImage);



DeleteObject(newImage) ;



DeleteDC(newImageDC);



newMask = (HBITMAP)SelectObject(newMaskDC, oldNewMask);



DeleteObject(newMask) ;



DeleteDC(newMaskDC);



DeleteDC(dc) ;



DeleteObject(bitmap) ;



return true;



}


Keep Cool & Be Wild
Divad
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Il n'y a aucun risque à définir des variables de version avant d'inclure des headers. Cela permet d'activer ou désactiver des fonctionnalités. Après tout dépend de la cible min de ton prog. Tu peux également faire un test de la version de Windows pour savoir quelle fonction appeler (celle de l'API, sans doute optimisée ou la version compatible que tu as donné pour les systèmes dépourvus de la fonction de l'API).