Changeset 2254 for trunk/eraser


Ignore:
Timestamp:
10/24/2010 8:01:49 AM (4 years ago)
Author:
lowjoel
Message:

Forward-port from Eraser 6.0: On pre-Vista OSes, we really only need to set the menu item bitmap to be a callback. We do not need to compute the size of the entire menu item and then draw it all ourselves. This fixes compatibility with shells which do not implement IContextMenu2.

Fixes #380.

Location:
trunk/eraser
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser

  • trunk/eraser/Eraser.Shell/CtxMenu.cpp

    r2250 r2254  
    310310            MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; 
    311311            mii.wID = uID++; 
    312             mii.fMask = MIIM_STRING | MIIM_ID; 
     312            mii.fMask = MIIM_STRING | MIIM_ID | MIIM_BITMAP; 
    313313            if (InvokeReason != INVOKEREASON_DIRECTORY_BACKGROUND) 
    314314            { 
     
    328328            if (isVistaOrLater) 
    329329            { 
    330                 mii.fMask |= MIIM_BITMAP; 
    331330                Handle<HICON> icon(GetMenuIcon()); 
    332331                mii.hbmpItem = GetMenuBitmapFromIcon(icon); 
     
    334333            else if (InvokeReason != INVOKEREASON_DRAGDROP) 
    335334            { 
    336                 mii.fMask |= MIIM_FTYPE; 
    337                 mii.fType = MFT_OWNERDRAW; 
     335                mii.hbmpItem = HBMMENU_CALLBACK; 
    338336            } 
    339337 
     
    376374                if (mis->itemID == MenuID) 
    377375                    handleResult = OnMeasureItem(mis->itemWidth, mis->itemHeight); 
    378                 else 
    379                     handleResult = false; 
    380376                break; 
    381377            } 
     
    386382                if (dis->itemID == MenuID) 
    387383                    handleResult = OnDrawItem(dis->hDC, dis->rcItem, dis->itemAction, dis->itemState); 
    388                 else 
    389                     handleResult = false; 
    390384            } 
    391385        } 
     
    398392    bool CCtxMenu::OnMeasureItem(UINT& itemWidth, UINT& itemHeight) 
    399393    { 
    400         LOGFONT logFont; 
    401         if (!SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(logFont), &logFont, 0)) 
    402             return false; 
    403  
    404         //Measure the size of the text. 
    405         Handle<HDC> screenDC = GetDC(NULL); 
    406         Handle<HFONT> font = CreateFontIndirect(&logFont); 
    407         SelectObject(screenDC, font); 
    408         SIZE textSize; 
    409         if (!GetTextExtentPoint32(screenDC, MenuTitle, static_cast<DWORD>(wcslen(MenuTitle)), &textSize)) 
    410             return false; 
    411  
    412         itemWidth = textSize.cx; 
    413         itemHeight = textSize.cy; 
    414  
    415394        //Account for the size of the bitmap. 
    416         UINT iconWidth = GetSystemMetrics(SM_CXMENUCHECK); 
    417         itemWidth += iconWidth; 
    418         itemHeight = std::max(iconWidth, itemHeight); 
    419  
    420         //And remember the minimum size for menu items. 
    421         itemHeight = std::max((int)itemHeight, GetSystemMetrics(SM_CXMENUSIZE)); 
     395        itemWidth = 0; 
     396        itemHeight = std::max<UINT>(GetSystemMetrics(SM_CYMENUCHECK), itemHeight); 
    422397        return true; 
    423398    } 
     
    425400    bool CCtxMenu::OnDrawItem(HDC hdc, RECT rect, UINT /*action*/, UINT state) 
    426401    { 
    427         //Draw the background. 
    428         LOGBRUSH logBrush = { BS_SOLID, 
    429             (state & ODS_SELECTED) ? 
    430                 GetSysColor(COLOR_HIGHLIGHT) : GetSysColor(COLOR_MENU), 
    431             0 
    432         }; 
    433         Handle<HBRUSH> bgBrush = CreateBrushIndirect(&logBrush); 
    434         FillRect(hdc, &rect, bgBrush); 
    435  
    436         //Then the bitmap. 
    437         { 
    438             //Draw the icon with alpha and all first. 
    439             Handle<HICON> icon(GetMenuIcon()); 
    440             int iconSize = GetSystemMetrics(SM_CXMENUCHECK); 
    441             int iconMargin = GetSystemMetrics(SM_CXEDGE); 
    442             DrawState(hdc, NULL, NULL, reinterpret_cast<LPARAM>(static_cast<HICON>(icon)), 
    443                 NULL, rect.left + iconMargin, rect.top + (rect.bottom - rect.top - iconSize) / 2, 
    444                 0, 0, DST_ICON | ((state & ODS_DISABLED) ? DSS_DISABLED : 0)); 
    445              
    446             //Move the rectangle's left bound to the text starting position 
    447             rect.left += iconMargin * 2 + iconSize; 
    448         } 
    449          
    450         //Draw the text. 
    451         SetBkMode(hdc, TRANSPARENT); 
    452         LOGFONT logFont; 
    453         if (!SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(logFont), &logFont, 0)) 
    454             return false; 
    455  
    456         SIZE textSize; 
    457         if (!GetTextExtentPoint32(hdc, MenuTitle, static_cast<DWORD>(wcslen(MenuTitle)), &textSize)) 
    458             return false; 
    459  
    460         COLORREF oldColour = SetTextColor(hdc,  
    461             (state & ODS_DISABLED) ? GetSysColor(COLOR_GRAYTEXT) :          //Disabled menu item 
    462             (state & ODS_SELECTED) ? GetSysColor(COLOR_HIGHLIGHTTEXT) :     //Highlighted menu item 
    463                 GetSysColor(COLOR_MENUTEXT));                               //Normal menu item 
    464         UINT flags = DST_PREFIXTEXT; 
    465         if (state & ODS_NOACCEL) 
    466             flags |= DSS_HIDEPREFIX; 
    467         ::DrawState(hdc, NULL, NULL, reinterpret_cast<LPARAM>(MenuTitle), wcslen(MenuTitle), 
    468             rect.left, rect.top + (rect.bottom - rect.top - textSize.cy) / 2, textSize.cx, textSize.cy, flags); 
    469         SetTextColor(hdc, oldColour); 
     402        //Get the icon and calculate its size. 
     403        Handle<HICON> icon(GetMenuIcon()); 
     404        int iconSize = GetSystemMetrics(SM_CXMENUCHECK); 
     405        int iconMargin = GetSystemMetrics(SM_CXEDGE); 
     406 
     407        //Draw the bitmap. 
     408        DrawState(hdc, NULL, NULL, reinterpret_cast<LPARAM>(static_cast<HICON>(icon)), 
     409            NULL, rect.left - iconMargin - iconSize, 
     410            rect.top + (rect.bottom - rect.top - iconSize) / 2, 0, 0, 
     411            DST_ICON | ((state & ODS_DISABLED) ? DSS_DISABLED : 0)); 
     412 
    470413        return true; 
    471414    } 
Note: See TracChangeset for help on using the changeset viewer.