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

发布于 2024-08-27 21:14:32 字数 569 浏览 5 评论 0原文

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

  1. 此外,图标(.bmp)在非英语操作系统中未完全显示。

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

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_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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心的憧憬 2024-09-03 21:14:32

您需要一种特殊的机制来在 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

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

夜空下最亮的亮点 2024-09-03 21:14:32

我认为 TortoiseSVN 使用所有者绘制菜单。
不了解 winrar,但此代码甚至可以在透明Blt 存在内存泄漏的 win98 上运行。
位图必须有颜色表(8 位)。

像这样使用(此代码格式可能会破坏文本,因此请检查错误!)

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

//功能 内联 BOOL ReplaceDIBColor(HBITMAP &hDIB, COLORREF oldColor, COLORREF newColor) { BOOL bRet=FALSE; //获取颜色信息 解剖 ds; if (!GetObject(hDIB, sizeof(DIBSECTION), &ds)) 返回 FALSE; if (ds.dsBmih.biBitCount>8) 返回 FALSE; // 最大必须为 8 bpp

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

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; }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文