Transparence sur fenetre - demande de correction de mon programme

elflink Messages postés 34 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 10 novembre 2009 - 20 oct. 2004 à 03:04
ero_senin Messages postés 39 Date d'inscription mercredi 1 décembre 2004 Statut Membre Dernière intervention 17 janvier 2005 - 10 déc. 2004 à 08:11
bonjour à tous et à toutes,

voila j'ai créé un petit logiciel qui permet d'appliquer un effet de transparence sur une fenetre via une couleur de transparence.
Néanmoins ça ne fonctionne pas et ayant tout essayé je poste mon code source ici avec espoir...

Premiere fonction qui va permettre de transformer la fenetre en HBITMAP >>

HBITMAP HwndToBmpFile(HWND hwnd)
{
HDC memdc, hdc;
HANDLE hfl;
DWORD dwBytes, dwNumColors;
void *pBits;
HBITMAP hbmp;
BITMAPFILEHEADER fileheader;
RGBQUAD colors[256];
BITMAPINFO bmpinfo;
HGDIOBJ hret;
RECT rct;
hdc = GetWindowDC(hwnd);
if(!hdc) return 0;
GetWindowRect(hwnd, &rct);
rct.bottom -= rct.top;
rct.right -= rct.left;
rct.top = GetDeviceCaps(hdc, BITSPIXEL); if(rct.top <8) dwNumColors 256;
else dwNumColors = 0;
if(!(memdc = CreateCompatibleDC(hdc))) goto relHwndDc;
bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.bmiHeader.biWidth = rct.right;
bmpinfo.bmiHeader.biHeight = rct.bottom;
bmpinfo.bmiHeader.biPlanes = 1;
bmpinfo.bmiHeader.biBitCount = (WORD) rct.top;
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, rct.right, rct.bottom, hdc, 0, 0, SRCCOPY)) goto errato;
if(dwNumColors) dwNumColors = GetDIBColorTable(memdc, 0, dwNumColors, colors);
fileheader.bfType = 0x4D42;
rct.left = dwNumColors * sizeof(RGBQUAD);
fileheader.bfSize = ((rct.right * rct.bottom * rct.top) >> 3) + rct.left + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); fileheader.bfReserved1 fileheader.bfReserved2 0;
fileheader.bfOffBits = rct.left + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpinfo.bmiHeader.biClrImportant = 0;
bmpinfo.bmiHeader.biClrUsed = dwNumColors;
hfl = CreateFile(TEXT("c:\\monfichier.bmp"),GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
if(hfl == INVALID_HANDLE_VALUE) { goto errato;}
WriteFile(hfl, &fileheader, sizeof(BITMAPFILEHEADER), &dwBytes, 0);
WriteFile(hfl, &bmpinfo.bmiHeader, sizeof(BITMAPINFOHEADER), &dwBytes, 0);
if(!dwNumColors) WriteFile(hfl, colors, rct.left, &dwBytes, 0);
WriteFile(hfl, pBits, (rct.right * rct.bottom * rct.top) >> 3, &dwBytes, 0);
CloseHandle(hfl);
DeleteDC(memdc);
errato:
DeleteDC(memdc);
relHwndDc:
ReleaseDC(hwnd, hdc);

return hbmp;
}

Seconde fonction qui va creer grâce aux regions un effet de transparence >>
HRGN BmpToRgn (HBITMAP hBmp, COLORREF cTransparentColor)
{
#define ALLOC_UNIT 100
HRGN hRgn = NULL;
if (!hBmp) return 0; // si bitmap invalide retourne
BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm); // met les infos d'en tete du bitmap dans bm
UINT siz=bm.bmWidth*bm.bmHeight*4; // enregistre la taille des donnes de l'image
char *lpBmpBits=(char*)LocalAlloc(LMEM_FIXED,siz); // fait de la place pour les bits du bitmap
GetBitmapBits(hBmp,siz,lpBmpBits); // obtient les bits de l'image dans l'espace qu'on a reservé
bm.bmBits=lpBmpBits; // complete la strucutre bm avec les bits
while (bm.bmWidthBytes % 4) bm.bmWidthBytes++; // bmWidthBytes doit être divisible par 4

DWORD maxRects = ALLOC_UNIT;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES; pData->rdh.nCount pData->rdh.nRgnSize 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);

BYTE *p32 = (BYTE *)bm.bmBits;
for (int y = 0; y < bm.bmHeight; y++) // parcourt toutes les lignes de l'image, de haut en bas
{
for (int x = 0; x < bm.bmWidth; x++) // parcourt tous les pixels de la ligne, de gauche à droite
{
// Recherche une suite continue de pixels non transparents
int x0 = x;
long *p = (long *)(p32 + 4*x);
while (x < bm.bmWidth)
{
if ((unsigned)*p==cTransparentColor)
break; // ce pixel est transparent
p++;
x++;
}
if (x > x0)
{
// ajoute les pixels (de (x0, y) à (x, y+1)) à la region en tant que rectangle
if (pData->rdh.nCount >= maxRects)
{
GlobalUnlock(hData);
maxRects += ALLOC_UNIT;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) +
(sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pr = (RECT *)&pData->Buffer;
SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y+1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y+1;
pData->rdh.nCount++;

// Il parait que sous Windows 98, ExtCreateRegion() ne marche pas s'il y a trop de rectangles
// Pas de panique: on construit la region en deux fois
if (pData->rdh.nCount == 2000)
{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
// On passe à la ligne suivante
p32 += bm.bmWidthBytes;
}
// On cree la region
// (et, s'il y avait plus de 2000 rectangles, on la combine avec celle créee precedemment)
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else hRgn = h;
LocalFree((HLOCAL)lpBmpBits);
return hRgn;
}

La façon dont j'associe ces 2 fonctions >>
HRGN Rgn = BmpToRgn(HwndToBmpFile(fenetre), RGB(49,239,25));
SetWindowRgn(ghFGirl, Rgn, 1);
DeleteObject(Rgn);

merci bcp
@+

3 réponses

cs_thierry la fronde Messages postés 351 Date d'inscription mercredi 21 juillet 2004 Statut Membre Dernière intervention 12 août 2009
20 oct. 2004 à 15:33
J'ai utilisé un code qui ferme une application en rendant transparente la fenêtre (ou le dialog). Peut-être trouveras-tu ce qui te manque , suivre le lien (note : la transparence ne fonctionne pas sous W98):
http://www.codeguru.com/Cpp/W-D/dislog/animation/article.php/c5063/

A+
0
elflink Messages postés 34 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 10 novembre 2009
20 oct. 2004 à 19:36
Je tiens à te remercier d'avoir répondu à ma question, toutefois, si j'utilise un système de région c'est parce que je veux rendre opérationnel le programme sur tous les différents windows.

@+
0
ero_senin Messages postés 39 Date d'inscription mercredi 1 décembre 2004 Statut Membre Dernière intervention 17 janvier 2005
10 déc. 2004 à 08:11
salut tt le monde c pour savoir si elfink ta résolu ton pbl car ça m"interesse pas mal vu que je dois rendre transparent ma fenetre et laissé apparant quelque simbole uniquement.... donc si tu peux m'aider.... merci

:-p
0
Rejoignez-nous