系统上下文菜单图标不像WinRAR那样透明

时间:2010-04-05 11:19:25

标签: c++ winapi icons contextmenu transparent

我在系统上下文菜单中添加了一个图标(当我们右键单击任何文件/文件夹时弹出的菜单)。但是图标不透明(在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]

  1. 此外,非英语操作系统中的图标(.bmp)未完全显示。
  2. 那么是否有任何特殊技术可以使系统上下文菜单中的图标像WinRAR一样透明?

2 个答案:

答案 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; }