X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ee00931326788270a5ec1bd4aa31b19b49b386ed..ca1f7cb56322e35a5bf3d9612cd14c128246947c:/src/msw/menuitem.cpp diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp index b9bc84585b..a5233965bf 100644 --- a/src/msw/menuitem.cpp +++ b/src/msw/menuitem.cpp @@ -30,6 +30,8 @@ #include "wx/stockitem.h" #ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/dcmemory.h" #include "wx/font.h" #include "wx/bitmap.h" #include "wx/settings.h" @@ -239,6 +241,15 @@ public: static const MenuDrawData* Get() { + // notice that s_menuData can't be created as a global variable because + // it needs a window to initialize and no windows exist at the time of + // globals initialization yet + if ( !ms_instance ) + { + static MenuDrawData s_menuData; + ms_instance = &s_menuData; + } + #if wxUSE_UXTHEME bool theme = MenuLayout() == FullTheme; if ( ms_instance->Theme != theme ) @@ -249,7 +260,6 @@ public: MenuDrawData() { - ms_instance = this; Init(); } @@ -297,8 +307,6 @@ private: MenuDrawData* MenuDrawData::ms_instance = NULL; -MenuDrawData s_menuData; - void MenuDrawData::Init() { #if wxUSE_UXTHEME @@ -779,7 +787,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height) if ( IsOwnerDrawn() ) { - // width of menu icon in ownerdrawn menu + // width of menu icon with margins in ownerdrawn menu // if any bitmap is not set, the width of space reserved for icon // image is equal to the width of std check mark, // if bitmap is set, then the width is set to the width of the widest @@ -833,8 +841,7 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc, RECT rect; wxCopyRectToRECT(rc, rect); - int imgWidth = wxMax(GetMarginWidth(), data->CheckSize.cx) - + data->CheckMargin.left + data->CheckMargin.right; + int imgWidth = wxMax(GetMarginWidth(), data->CheckSize.cx); if ( IsOwnerDrawn() ) { @@ -869,12 +876,19 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc, CopyRect(&rcGutter, &rcSelection); rcGutter.right = data->ItemMargin.left + data->CheckBgMargin.left + + data->CheckMargin.left + imgWidth + + data->CheckMargin.right + data->CheckBgMargin.right; CopyRect(&rcText, &rcSelection); rcText.left = rcGutter.right + data->TextBorder; + // we draw the text label vertically centered, but this results in it + // being 1px too low compared to native menus for some reason, fix it + if ( data->MenuLayout() != MenuDrawData::FullTheme ) + rcText.top--; + #if wxUSE_UXTHEME wxUxThemeEngine* theme = MenuDrawData::GetUxThemeEngine(); if ( theme ) @@ -1011,17 +1025,25 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc, RECT rcImg; SetRect(&rcImg, - rect.left + data->ItemMargin.left + data->CheckBgMargin.left, - rect.top + data->ItemMargin.top + data->CheckBgMargin.top, - rect.left + data->ItemMargin.left + data->CheckBgMargin.left - + imgWidth, - rect.bottom - data->ItemMargin.bottom - data->CheckBgMargin.bottom); + rect.left + data->ItemMargin.left + + data->CheckBgMargin.left + + data->CheckMargin.left, + rect.top + data->ItemMargin.top + + data->CheckBgMargin.top + + data->CheckMargin.top, + rect.left + data->ItemMargin.left + + data->CheckBgMargin.left + + data->CheckMargin.left + + imgWidth, + rect.bottom - data->ItemMargin.bottom + - data->CheckBgMargin.bottom + - data->CheckMargin.bottom); if ( IsCheckable() && !m_bmpChecked.Ok() ) { if ( stat & wxODChecked ) { - DrawStdCheckMark(hdc, &rcImg, stat); + DrawStdCheckMark((WXHDC)hdc, &rcImg, stat); } } else @@ -1119,22 +1141,32 @@ void DrawColorCheckMark(HDC hdc, int x, int y, int cx, int cy, HDC hdcCheckMask, } // anonymous namespace -void wxMenuItem::DrawStdCheckMark(HDC hdc, const RECT* rc, wxODStatus stat) +void wxMenuItem::DrawStdCheckMark(WXHDC hdc_, const RECT* rc, wxODStatus stat) { + HDC hdc = (HDC)hdc_; + #if wxUSE_UXTHEME wxUxThemeEngine* theme = MenuDrawData::GetUxThemeEngine(); if ( theme ) { wxUxThemeHandle hTheme(GetMenu()->GetWindow(), L"MENU"); + const MenuDrawData* data = MenuDrawData::Get(); + + // rect for background must be without check margins + RECT rcBg; + SetRect(&rcBg, + rc->left - data->CheckMargin.left, + rc->top - data->CheckMargin.top, + rc->right + data->CheckMargin.right, + rc->bottom + data->CheckMargin.bottom); + POPUPCHECKBACKGROUNDSTATES stateCheckBg = (stat & wxODDisabled) ? MCB_DISABLED : MCB_NORMAL; theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPCHECKBACKGROUND, - stateCheckBg, rc, NULL); - - // check mark will be drawn centered on the background + stateCheckBg, &rcBg, NULL); POPUPCHECKSTATES stateCheck; if ( GetKind() == wxITEM_CHECK )