2010-04-05 9 views
1

J'ai ajouté une icône dans le menu contextuel du système (le menu contextuel lorsque l'on clique avec le bouton droit de la souris sur un fichier/foler). Mais l'icône n'est pas transparente (en XP c'est pas remarqué, mais dans vista/win7 c'est clairement visible) il y a un fond blanc sous l'icône. Mais les icônes WinRAR ou TortoiseSVN n'ont pas d'arrière-plan blanc, elles sont transparentes.Menu contextuel du système Icône non transparente comme WinRAR

J'ai essayé le code C++ suivant:

#define BITMAP_MAIN 201 //in resource.h 
BITMAP_MAIN BITMAP "main.bmp" // in .rc file 

// showing icon in menu... 
HBITMAP imgMain = LoadBitmap(aHinstance, MAKEINTRESOURCE(BITMAP_MAIN)); 
SetMenuItemBitmaps (hSubmenu, uMenuIndex, MF_BYPOSITION, imgMain, imgMain); 

[main.bmp est 16X16]

  1. également l'icône (.bmp) n'est pas représenté entièrement dans OS non-anglais.

Y at-il une technique spéciale pour rendre l'icône dans le menu contextuel du système transparente comme WinRAR?

+0

Comme vous pouvez le voir int la fonction SetMenuItemBitmaps ne prend que HBITMAP arguments de type. J'ai essayé de charger le fichier .ico et l'ai converti en HBITMAP, puis j'ai passé l'icône à cette fonction, mais cela n'a pas résolu le problème. En passant, je vais faire attention à accepter les réponses des gens la prochaine fois. Merci de me le faire savoir. – Samir

Répondre

1

Vous avez besoin d'un mécanisme spécial pour charger les icônes dans Vista et plus tard, car elles ne semblent pas traiter (par défaut) les transparences dans les fichiers BMP. Vous devez détecter le système d'exploitation:

// Necessary for getting icons in the proper manner. 
bool isVistaOrMore() { 
    OSVERSIONINFOEX inf; 
    SecureZeroMemory(&inf, sizeof(OSVERSIONINFOEX)); 
    inf.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 
    WORD fullver = GetVersionEx((OSVERSIONINFO *)&inf); 
    return (fullver >= 0x0600); 
} 

Si elle retourne false puis faites ce que vous faites en ce moment, si elle retourne vrai, effectuer analogique quelque chose à ce qui est décrit dans: http://msdn.microsoft.com/en-us/library/bb757020.aspx

1

Je pense TortoiseSVN utilise des menus owner-draw. Ne sait pas à propos de winrar, mais ce code pourrait fonctionner même sur win98 où TransparentBlt a une fuite de mémoire. Bitmap doit avoir une table de couleurs (8 bits).

Utilisez comme celui-ci (cette mise en forme de code peut mutiler texte, afin de vérifier les erreurs!)

//we replace magenta with menu color 
ReplaceDIBColor(m_hMenuBmp, RGB(255,0,255), GetSysColor(COLOR_MENU));

//function inline BOOL ReplaceDIBColor(HBITMAP &hDIB, COLORREF oldColor, COLORREF newColor) { BOOL bRet=FALSE; //get color information DIBSECTION ds; if (!GetObject(hDIB, sizeof(DIBSECTION), &ds)) return FALSE; if (ds.dsBmih.biBitCount>8) return FALSE; //must be 8 bpp max

HDC hDC=CreateCompatibleDC(NULL); if (!hDC) return FALSE; HBITMAP hbmpOld=(HBITMAP)::SelectObject(hDC, hDIB); //allocate color table UINT nColors = ds.dsBmih.biClrUsed ? ds.dsBmih.biClrUsed : 1<<ds.dsBmih.biBitCount; //bpp to UINT RGBQUAD* ptbl=(RGBQUAD*)CoTaskMemAlloc(nColors*sizeof(RGBQUAD)); if (ptbl) { if (GetDIBColorTable(hDC, 0, nColors, ptbl)) { //replace color table entries UINT i; for (i=0; i<nColors ; i++) { if (oldColor==RGB(ptbl[i].rgbRed, ptbl[i].rgbGreen, ptbl[i].rgbBlue)) { ptbl[i].rgbRed=GetRValue(newColor); ptbl[i].rgbGreen=GetGValue(newColor); ptbl[i].rgbBlue=GetBValue(newColor); bRet=TRUE; } } //set new table if (bRet) if (!SetDIBColorTable(hDC, 0, nColors, ptbl)) bRet=FALSE; } //cleanup CoTaskMemFree(ptbl); ptbl=NULL; bRet=TRUE; } else bRet=FALSE; hDIB=(HBITMAP)::SelectObject(hDC, hbmpOld); DeleteDC(hDC); return bRet; }