我在系统上下文菜单中添加了一个图标(当我们右键单击任何文件/文件夹时弹出的菜单)。但是图标不透明(在xp中它没有注意到,但在vista / win7中它清晰可见)图标下方有一个白色背景。但WinRAR或TortoiseSVN图标没有任何白色背景,它们是透明的。
我尝试了以下C ++代码:
#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是16X16]
那么是否有任何特殊技术可以使系统上下文菜单中的图标像WinRAR一样透明?
答案 0 :(得分:1)
您需要一种特殊的机制来在Vista及更高版本中加载图标,因为它们似乎不会处理(默认情况下)BMP文件中的透明度。您需要检测操作系统:
// 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);
}
如果它返回false然后执行你现在正在做的事情,如果它返回true,执行类似于下面描述的内容: http://msdn.microsoft.com/en-us/library/bb757020.aspx
答案 1 :(得分:1)
我认为TortoiseSVN使用所有者绘制菜单。 不知道winrar,但是这个代码甚至可能在win98上工作,其中TransparentBlt有内存泄漏。 位图必须有颜色表(8位)。
像这样使用(此代码格式化可能会破坏文本,因此请检查错误!)
//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; }