Системное контекстное меню Значок не прозрачный, как WinRAR - PullRequest
1 голос
/ 05 апреля 2010

Я добавил значок в системное контекстное меню (всплывающее меню, когда мы щелкаем правой кнопкой мыши по любому файлу / файлеру). Но значок не прозрачный (в 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?

Ответы [ 2 ]

1 голос
/ 01 апреля 2011

Я думаю, что TortoiseSVN использует меню для рисования владельцем. Не знаю про winrar, но этот код может работать даже на win98, где у TransparentBlt утечка памяти. Растровое изображение должно иметь таблицу цветов (8 бит).

Используйте вот так (это форматирование кода может искажать текст, поэтому проверьте на ошибки!)

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

<p>//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</p>

<code>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;  }
</code>
1 голос
/ 18 февраля 2011

Вам необходим специальный механизм для загрузки значков в 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

...