Transparence sur fenetre - demande de correction de mon programme

Signaler
Messages postés
34
Date d'inscription
mardi 30 décembre 2003
Statut
Membre
Dernière intervention
10 novembre 2009
-
Messages postés
39
Date d'inscription
mercredi 1 décembre 2004
Statut
Membre
Dernière intervention
17 janvier 2005
-
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

Messages postés
351
Date d'inscription
mercredi 21 juillet 2004
Statut
Membre
Dernière intervention
12 août 2009

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+
Messages postés
34
Date d'inscription
mardi 30 décembre 2003
Statut
Membre
Dernière intervention
10 novembre 2009

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.

@+
Messages postés
39
Date d'inscription
mercredi 1 décembre 2004
Statut
Membre
Dernière intervention
17 janvier 2005

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