2

我在系统上下文菜单中添加了一个图标(当我们右键单击任何文件/文件夹时弹出的菜单)。但是图标不是透明的(在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)在非英语操作系统中也没有完全显示。

那么有没有什么特殊的技术可以让系统上下文菜单中的图标像WinRAR一样透明呢?

4

2 回答 2

1

I think TortoiseSVN uses owner-draw menus. Don't know about winrar, but this code might work even on win98 where TransparentBlt has memory leak. Bitmap must have color table (8-bit).

Use like this (this code formatting can mangle text, so check for errors!)

//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; }
于 2011-03-31T22:37:57.943 回答
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

于 2011-02-18T12:57:04.127 回答