+
+
+ // draw the bitmap
+
+ RECT rcImg;
+ SetRect(&rcImg,
+ rect.left + data->ItemMargin.cxLeftWidth
+ + data->CheckBgMargin.cxLeftWidth
+ + data->CheckMargin.cxLeftWidth,
+ rect.top + data->ItemMargin.cyTopHeight
+ + data->CheckBgMargin.cyTopHeight
+ + data->CheckMargin.cyTopHeight,
+ rect.left + data->ItemMargin.cxLeftWidth
+ + data->CheckBgMargin.cxLeftWidth
+ + data->CheckMargin.cxLeftWidth
+ + imgWidth,
+ rect.bottom - data->ItemMargin.cyBottomHeight
+ - data->CheckBgMargin.cyBottomHeight
+ - data->CheckMargin.cyBottomHeight);
+
+ if ( IsCheckable() && !m_bmpChecked.IsOk() )
+ {
+ if ( stat & wxODChecked )
+ {
+ DrawStdCheckMark((WXHDC)hdc, &rcImg, stat);
+ }
+ }
+ else
+ {
+ wxBitmap bmp;
+
+ if ( stat & wxODDisabled )
+ {
+ bmp = GetDisabledBitmap();
+ }
+
+ if ( !bmp.IsOk() )
+ {
+ // for not checkable bitmaps we should always use unchecked one
+ // because their checked bitmap is not set
+ bmp = GetBitmap(!IsCheckable() || (stat & wxODChecked));
+
+#if wxUSE_IMAGE
+ if ( bmp.IsOk() && stat & wxODDisabled )
+ {
+ // we need to grey out the bitmap as we don't have any specific
+ // disabled bitmap
+ wxImage imgGrey = bmp.ConvertToImage().ConvertToGreyscale();
+ if ( imgGrey.IsOk() )
+ bmp = wxBitmap(imgGrey);
+ }
+#endif // wxUSE_IMAGE
+ }
+
+ if ( bmp.IsOk() )
+ {
+ wxMemoryDC dcMem(&dc);
+ dcMem.SelectObjectAsSource(bmp);
+
+ // center bitmap
+ int nBmpWidth = bmp.GetWidth(),
+ nBmpHeight = bmp.GetHeight();
+
+ int x = rcImg.left + (imgWidth - nBmpWidth) / 2;
+ int y = rcImg.top + (rcImg.bottom - rcImg.top - nBmpHeight) / 2;
+ dc.Blit(x, y, nBmpWidth, nBmpHeight, &dcMem, 0, 0, wxCOPY, true);
+ }
+ }
+
+ return true;
+
+}
+
+namespace
+{
+
+// helper function for draw coloured check mark
+void DrawColorCheckMark(HDC hdc, int x, int y, int cx, int cy, HDC hdcCheckMask, int idxColor)
+{
+ const COLORREF colBlack = RGB(0, 0, 0);
+ const COLORREF colWhite = RGB(255, 255, 255);
+
+ HDCTextColChanger changeTextCol(hdc, colBlack);
+ HDCBgColChanger changeBgCol(hdc, colWhite);
+ HDCBgModeChanger changeBgMode(hdc, TRANSPARENT);
+
+ // memory DC for color bitmap
+ MemoryHDC hdcMem(hdc);
+ CompatibleBitmap hbmpMem(hdc, cx, cy);
+ SelectInHDC selMem(hdcMem, hbmpMem);
+
+ RECT rect = { 0, 0, cx, cy };
+ ::FillRect(hdcMem, &rect, ::GetSysColorBrush(idxColor));
+
+ const COLORREF colCheck = ::GetSysColor(idxColor);
+ if ( colCheck == colWhite )
+ {
+ ::BitBlt(hdc, x, y, cx, cy, hdcCheckMask, 0, 0, MERGEPAINT);
+ ::BitBlt(hdc, x, y, cx, cy, hdcMem, 0, 0, SRCAND);
+ }
+ else
+ {
+ if ( colCheck != colBlack )
+ {
+ const DWORD ROP_DSna = 0x00220326; // dest = (NOT src) AND dest
+ ::BitBlt(hdcMem, 0, 0, cx, cy, hdcCheckMask, 0, 0, ROP_DSna);
+ }
+
+ ::BitBlt(hdc, x, y, cx, cy, hdcCheckMask, 0, 0, SRCAND);
+ ::BitBlt(hdc, x, y, cx, cy, hdcMem, 0, 0, SRCPAINT);
+ }
+}
+
+} // anonymous namespace
+
+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 = *rc;
+ data->CheckMargin.UnapplyFrom(rcBg);
+
+ POPUPCHECKBACKGROUNDSTATES stateCheckBg = (stat & wxODDisabled)
+ ? MCB_DISABLED
+ : MCB_NORMAL;
+
+ theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPCHECKBACKGROUND,
+ stateCheckBg, &rcBg, NULL);
+
+ POPUPCHECKSTATES stateCheck;
+ if ( GetKind() == wxITEM_CHECK )
+ {
+ stateCheck = (stat & wxODDisabled) ? MC_CHECKMARKDISABLED
+ : MC_CHECKMARKNORMAL;
+ }
+ else
+ {
+ stateCheck = (stat & wxODDisabled) ? MC_BULLETDISABLED
+ : MC_BULLETNORMAL;
+ }
+
+ theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPCHECK,
+ stateCheck, rc, NULL);
+ }
+ else
+#endif // wxUSE_UXTHEME
+ {
+ int cx = rc->right - rc->left;
+ int cy = rc->bottom - rc->top;
+
+ // first create mask of check mark
+ MemoryHDC hdcMask(hdc);
+ MonoBitmap hbmpMask(cx, cy);
+ SelectInHDC selMask(hdcMask,hbmpMask);
+
+ // then draw a check mark into it
+ UINT stateCheck = (GetKind() == wxITEM_CHECK) ? DFCS_MENUCHECK
+ : DFCS_MENUBULLET;
+ RECT rect = { 0, 0, cx, cy };
+ ::DrawFrameControl(hdcMask, &rect, DFC_MENU, stateCheck);
+
+ // first draw shadow if disabled
+ if ( (stat & wxODDisabled) && !(stat & wxODSelected) )
+ {
+ DrawColorCheckMark(hdc, rc->left + 1, rc->top + 1,
+ cx, cy, hdcMask, COLOR_3DHILIGHT);
+ }
+
+ // then draw a check mark
+ int color = COLOR_MENUTEXT;
+ if ( stat & wxODDisabled )
+ color = COLOR_BTNSHADOW;
+ else if ( stat & wxODSelected )
+ color = COLOR_HIGHLIGHTTEXT;
+
+ DrawColorCheckMark(hdc, rc->left, rc->top, cx, cy, hdcMask, color);
+ }
+}
+
+void wxMenuItem::GetFontToUse(wxFont& font) const
+{
+ font = GetFont();
+ if ( !font.IsOk() )
+ font = MenuDrawData::Get()->Font;
+}
+
+void wxMenuItem::GetColourToUse(wxODStatus stat, wxColour& colText, wxColour& colBack) const
+{
+#if wxUSE_UXTHEME
+ wxUxThemeEngine* theme = MenuDrawData::GetUxThemeEngine();
+ if ( theme )
+ {
+ wxUxThemeHandle hTheme(GetMenu()->GetWindow(), L"MENU");
+
+ if ( stat & wxODDisabled)
+ {
+ wxRGBToColour(colText, theme->GetThemeSysColor(hTheme, COLOR_GRAYTEXT));
+ }
+ else
+ {
+ colText = GetTextColour();
+ if ( !colText.IsOk() )
+ wxRGBToColour(colText, theme->GetThemeSysColor(hTheme, COLOR_MENUTEXT));
+ }
+
+ if ( stat & wxODSelected )
+ {
+ wxRGBToColour(colBack, theme->GetThemeSysColor(hTheme, COLOR_HIGHLIGHT));
+ }
+ else
+ {
+ colBack = GetBackgroundColour();
+ if ( !colBack.IsOk() )
+ wxRGBToColour(colBack, theme->GetThemeSysColor(hTheme, COLOR_MENU));
+ }
+ }
+ else
+#endif // wxUSE_UXTHEME
+ {
+ wxOwnerDrawn::GetColourToUse(stat, colText, colBack);
+ }
+}
+#endif // wxUSE_OWNER_DRAWN
+
+// ----------------------------------------------------------------------------
+// wxMenuItemBase
+// ----------------------------------------------------------------------------
+
+wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
+ int id,
+ const wxString& name,
+ const wxString& help,
+ wxItemKind kind,
+ wxMenu *subMenu)
+{
+ return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);