开发者

System context menu Icon not transparent like WinRAR

开发者 https://www.devze.com 2022-12-25 11:55 出处:网络
I added a icon at the system context menu(the popped up menu when we right mouse click on any file/foler). But the icon is not transparent(in xp its not notice able, but in vista/win7 it is clearly vi

I added a icon at the system context menu(the popped up menu when we right mouse click on any file/foler). But the icon is not transparent(in xp its not notice able, but in vista/win7 it is clearly visible) there is a white background beneath the icon. But WinRAR or TortoiseSVN icons don't have any white background, they are transparent.

I tried the following C++ code:

#define BITMAP_MAIN 201 //in resource.h
BITMAP_M开发者_如何学CAIN 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 is 16X16]

  1. Also the icon(.bmp) is not shown fully in non-english OS.

So is there be any special technique to make the icon in the system context menu transparent like WinRAR?


You need a special mechanism for loading icons in Vista and later, since they don't seem to process (by default) transparencies in BMP files. You need to detect the operating system:

// 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);
}

If it returns false then do what you're doing right now, if it returns true, perform something analog to what's described in: http://msdn.microsoft.com/en-us/library/bb757020.aspx


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; }
0

精彩评论

暂无评论...
验证码 换一张
取 消