Changeset 2253 for branches/eraser6/6.0


Ignore:
Timestamp:
10/24/2010 7:50:10 AM (4 years ago)
Author:
lowjoel
Message:

Fixes #380. 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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/6.0/ShellExt/CtxMenu.cpp

    r2225 r2253  
    344344            MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; 
    345345            mii.wID = uID++; 
    346             mii.fMask = MIIM_SUBMENU | MIIM_STRING | MIIM_ID; 
     346            mii.fMask = MIIM_SUBMENU | MIIM_STRING | MIIM_ID | MIIM_BITMAP; 
    347347            mii.hSubMenu = hSubmenu; 
    348348            mii.dwTypeData = const_cast<wchar_t*>(MenuTitle); 
     
    353353            if (isVistaOrLater) 
    354354            { 
    355                 mii.fMask |= MIIM_BITMAP; 
    356355                Handle<HICON> icon(GetMenuIcon()); 
    357356                mii.hbmpItem = GetMenuBitmapFromIcon(icon); 
     
    359358            else if (InvokeReason != INVOKEREASON_DRAGDROP) 
    360359            { 
    361                 mii.fMask |= MIIM_FTYPE; 
    362                 mii.fType = MFT_OWNERDRAW; 
     360                mii.hbmpItem = HBMMENU_CALLBACK; 
    363361            } 
    364362 
     
    401399                if (mis->itemID == MenuID) 
    402400                    handleResult = OnMeasureItem(mis->itemWidth, mis->itemHeight); 
    403                 else 
    404                     handleResult = false; 
    405401                break; 
    406402            } 
     
    411407                if (dis->itemID == MenuID) 
    412408                    handleResult = OnDrawItem(dis->hDC, dis->rcItem, dis->itemAction, dis->itemState); 
    413                 else 
    414                     handleResult = false; 
    415409            } 
    416410        } 
     
    423417    bool CCtxMenu::OnMeasureItem(UINT& itemWidth, UINT& itemHeight) 
    424418    { 
    425         LOGFONT logFont; 
    426         if (!SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(logFont), &logFont, 0)) 
    427             return false; 
    428  
    429         //Measure the size of the text. 
    430         Handle<HDC> screenDC = GetDC(NULL); 
    431         Handle<HFONT> font = CreateFontIndirect(&logFont); 
    432         SelectObject(screenDC, font); 
    433         SIZE textSize; 
    434         if (!GetTextExtentPoint32(screenDC, MenuTitle, static_cast<DWORD>(wcslen(MenuTitle)), &textSize)) 
    435             return false; 
    436  
    437         itemWidth = textSize.cx; 
    438         itemHeight = textSize.cy; 
    439  
    440419        //Account for the size of the bitmap. 
    441         UINT iconWidth = GetSystemMetrics(SM_CXMENUCHECK); 
    442         itemWidth += iconWidth; 
    443         itemHeight = std::max(iconWidth, itemHeight); 
    444  
    445         //And remember the minimum size for menu items. 
    446         itemHeight = std::max((int)itemHeight, GetSystemMetrics(SM_CXMENUSIZE)); 
     420        itemWidth = 0; 
     421        itemHeight = std::max<UINT>(GetSystemMetrics(SM_CYMENUCHECK), itemHeight); 
    447422        return true; 
    448423    } 
     
    450425    bool CCtxMenu::OnDrawItem(HDC hdc, RECT rect, UINT /*action*/, UINT state) 
    451426    { 
    452         //Draw the background. 
    453         LOGBRUSH logBrush = { BS_SOLID, 
    454             (state & ODS_SELECTED) ? 
    455                 GetSysColor(COLOR_HIGHLIGHT) : GetSysColor(COLOR_MENU), 
    456             0 
    457         }; 
    458         Handle<HBRUSH> bgBrush = CreateBrushIndirect(&logBrush); 
    459         FillRect(hdc, &rect, bgBrush); 
    460  
    461         //Then the bitmap. 
    462         { 
    463             //Draw the icon with alpha and all first. 
    464             Handle<HICON> icon(GetMenuIcon()); 
    465             int iconSize = GetSystemMetrics(SM_CXMENUCHECK); 
    466             int iconMargin = GetSystemMetrics(SM_CXEDGE); 
    467             DrawState(hdc, NULL, NULL, reinterpret_cast<LPARAM>(static_cast<HICON>(icon)), 
    468                 NULL, rect.left + iconMargin, rect.top + (rect.bottom - rect.top - iconSize) / 2, 
    469                 0, 0, DST_ICON | ((state & ODS_DISABLED) ? DSS_DISABLED : 0)); 
    470              
    471             //Move the rectangle's left bound to the text starting position 
    472             rect.left += iconMargin * 2 + iconSize; 
    473         } 
    474          
    475         //Draw the text. 
    476         SetBkMode(hdc, TRANSPARENT); 
    477         LOGFONT logFont; 
    478         if (!SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(logFont), &logFont, 0)) 
    479             return false; 
    480  
    481         SIZE textSize; 
    482         if (!GetTextExtentPoint32(hdc, MenuTitle, static_cast<DWORD>(wcslen(MenuTitle)), &textSize)) 
    483             return false; 
    484  
    485         COLORREF oldColour = SetTextColor(hdc,  
    486             (state & ODS_DISABLED) ? GetSysColor(COLOR_GRAYTEXT) :          //Disabled menu item 
    487             (state & ODS_SELECTED) ? GetSysColor(COLOR_HIGHLIGHTTEXT) :     //Highlighted menu item 
    488                 GetSysColor(COLOR_MENUTEXT));                               //Normal menu item 
    489         UINT flags = DST_PREFIXTEXT; 
    490         if (state & ODS_NOACCEL) 
    491             flags |= DSS_HIDEPREFIX; 
    492         ::DrawState(hdc, NULL, NULL, reinterpret_cast<LPARAM>(MenuTitle), wcslen(MenuTitle), 
    493             rect.left, rect.top + (rect.bottom - rect.top - textSize.cy) / 2, textSize.cx, textSize.cy, flags); 
    494         SetTextColor(hdc, oldColour); 
     427        //Get the icon and calculate its size. 
     428        Handle<HICON> icon(GetMenuIcon()); 
     429        int iconSize = GetSystemMetrics(SM_CXMENUCHECK); 
     430        int iconMargin = GetSystemMetrics(SM_CXEDGE); 
     431 
     432        //Draw the bitmap. 
     433        DrawState(hdc, NULL, NULL, reinterpret_cast<LPARAM>(static_cast<HICON>(icon)), 
     434            NULL, rect.left - iconMargin - iconSize, 
     435            rect.top + (rect.bottom - rect.top - iconSize) / 2, 0, 0, 
     436            DST_ICON | ((state & ODS_DISABLED) ? DSS_DISABLED : 0)); 
     437 
    495438        return true; 
    496439    } 
Note: See TracChangeset for help on using the changeset viewer.