From: Vadim Zeitlin Date: Sat, 23 Jan 2010 13:22:07 +0000 (+0000) Subject: Fix off by 1 errors in owner-drawn menu drawing code in wxMSW. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/03cc29918fa6d727cf4d635126adaeaca405f9af?ds=inline Fix off by 1 errors in owner-drawn menu drawing code in wxMSW. The label was offset by 1 pixel vertically and the check marks were 1 pixel too wide compared to the native ones under XP, correct this. Closes #11420 (again). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63227 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp index b9bc84585b..fb0369196d 100644 --- a/src/msw/menuitem.cpp +++ b/src/msw/menuitem.cpp @@ -779,7 +779,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 +833,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 +868,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,11 +1017,19 @@ 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() ) { @@ -1127,14 +1141,22 @@ void wxMenuItem::DrawStdCheckMark(HDC hdc, const RECT* rc, wxODStatus stat) { 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 )