BOOL CXTPSyntaxEditTipWnd::CalcItemRect(int iItem, CRect& rItem) { ASSERT_VALID(this); if (m_pListBox->GetItemRect(iItem, &rItem) == LB_ERR) return FALSE; if (IsOwnerDrawn()) return FALSE; CString csItem; m_pListBox->GetText(iItem, csItem); m_pListBox->ClientToScreen(rItem); if (csItem.IsEmpty()) return FALSE; CWindowDC dc(NULL); CXTPFontDC fontDC(&dc, m_pListBox->GetFont()); int iAdjust = dc.GetTextExtent(csItem).cx + (::GetSystemMetrics(SM_CXEDGE)*2); m_rWindow.CopyRect(rItem); m_rWindow.right = max(rItem.right, rItem.left + iAdjust); return TRUE; }
bool wxOwnerDrawnBase::OnMeasureItem(size_t *width, size_t *height) { if ( IsOwnerDrawn() ) { wxMemoryDC dc; wxFont font; GetFontToUse(font); dc.SetFont(font); // item name/text without mnemonics wxString name = wxStripMenuCodes(GetName(), wxStrip_Mnemonics); wxCoord w, h; dc.GetTextExtent(name, &w, &h); *width = w + m_margin; *height = h; } else { *width = 0; *height = 0; } return true; }
void wxCheckBox::DoSet3StateValue(wxCheckBoxState state) { m_state = state; if ( !IsOwnerDrawn() ) ::SendMessage(GetHwnd(), BM_SETCHECK, (WPARAM) state, 0); else // owner drawn buttons don't react to this message Refresh(); }
void CXTPSyntaxEditTipWnd::OnPaint() { CPaintDC dc(this); // device context for painting CXTPClientRect rClient(this); if (IsOwnerDrawn()) OwnerDrawTip(&dc, rClient); else DrawTip(&dc, rClient); }
bool wxToggleButton::GetValue() const { if ( IsOwnerDrawn() ) { return m_state; } else { return ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0) == BST_CHECKED; } }
void wxToggleButton::SetValue(bool val) { m_state = val; if ( IsOwnerDrawn() ) { Refresh(); } else { ::SendMessage(GetHwnd(), BM_SETCHECK, val, 0); } }
// draw the item bool wxOwnerDrawn::OnDrawItem(wxDC& dc, const wxRect& rc, wxODAction, wxODStatus stat) { // we do nothing if item isn't ownerdrawn if ( !IsOwnerDrawn() ) return true; wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); HDC hdc = GetHdcOf(*impl); RECT rect; wxCopyRectToRECT(rc, rect); { // set the font and colors wxFont font; GetFontToUse(font); wxColour colText, colBack; GetColourToUse(stat, colText, colBack); SelectInHDC selFont(hdc, GetHfontOf(font)); wxMSWImpl::wxTextColoursChanger textCol(hdc, colText, colBack); wxMSWImpl::wxBkModeChanger bkMode(hdc, wxBRUSHSTYLE_TRANSPARENT); AutoHBRUSH hbr(wxColourToPalRGB(colBack)); SelectInHDC selBrush(hdc, hbr); ::FillRect(hdc, &rect, hbr); // using native API because it recognizes '&' wxString text = GetName(); SIZE sizeRect; ::GetTextExtentPoint32(hdc, text.c_str(), text.length(), &sizeRect); int flags = DST_PREFIXTEXT; if ( (stat & wxODDisabled) && !(stat & wxODSelected) ) flags |= DSS_DISABLED; if ( (stat & wxODHidePrefix) ) flags |= DSS_HIDEPREFIX; int x = rc.x + GetMarginWidth(); int y = rc.y + (rc.GetHeight() - sizeRect.cy) / 2; int cx = rc.GetWidth() - GetMarginWidth(); int cy = sizeRect.cy; ::DrawState(hdc, NULL, NULL, wxMSW_CONV_LPARAM(text), text.length(), x, y, cx, cy, flags); } // reset to default the font, colors and brush if (stat & wxODHasFocus) ::DrawFocusRect(hdc, &rect); return true; }
void wxMenuItem::SetItemLabel( const wxString& rText ) { // // Don't do anything if label didn't change // wxString sText = wxPMTextToLabel(rText); if (m_text == sText) return; // wxMenuItemBase will do stock ID checks wxMenuItemBase::SetItemLabel(sText); HWND hMenu = GetHmenuOf(m_parentMenu); wxCHECK_RET(hMenu, wxT("menuitem without menu")); #if wxUSE_ACCEL m_parentMenu->UpdateAccel(this); #endif // wxUSE_ACCEL USHORT uId = (USHORT)GetRealId(); MENUITEM vItem; USHORT uFlagsOld; if (!::WinSendMsg( hMenu ,MM_QUERYITEM ,MPFROM2SHORT(uId, TRUE) ,(MPARAM)&vItem )) { wxLogLastError(wxT("GetMenuState")); } else { uFlagsOld = vItem.afStyle; if (IsSubMenu()) { uFlagsOld |= MIS_SUBMENU; } char* pData; #if wxUSE_OWNER_DRAWN if (IsOwnerDrawn()) { uFlagsOld |= MIS_OWNERDRAW; pData = (char*)this; } else #endif //owner drawn { uFlagsOld |= MIS_TEXT; pData = (char*) m_text.wx_str(); } // // Set the style // if (!::WinSendMsg( hMenu ,MM_SETITEM ,MPFROM2SHORT(uId, TRUE) ,(MPARAM)&vItem )) { wxLogLastError(wxT("ModifyMenu")); } // // Set the text // if (::WinSendMsg( hMenu ,MM_SETITEMTEXT ,MPFROMSHORT(uId) ,(MPARAM)pData )) { wxLogLastError(wxT("ModifyMenu")); } } } // end of wxMenuItem::SetText
bool wxCheckBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item; if ( !IsOwnerDrawn() || dis->CtlType != ODT_BUTTON ) return wxCheckBoxBase::MSWOnDraw(item); // calculate the rectangles for the check mark itself and the label HDC hdc = dis->hDC; RECT& rect = dis->rcItem; RECT rectCheck, rectLabel; rectCheck.top = rectLabel.top = rect.top; rectCheck.bottom = rectLabel.bottom = rect.bottom; const int checkSize = GetBestSize().y; const int MARGIN = 3; const bool isRightAligned = HasFlag(wxALIGN_RIGHT); if ( isRightAligned ) { rectCheck.right = rect.right; rectCheck.left = rectCheck.right - checkSize; rectLabel.right = rectCheck.left - MARGIN; rectLabel.left = rect.left; } else // normal, left-aligned checkbox { rectCheck.left = rect.left; rectCheck.right = rectCheck.left + checkSize; rectLabel.left = rectCheck.right + MARGIN; rectLabel.right = rect.right; } // show we draw a focus rect? const bool isFocused = m_isPressed || FindFocus() == this; // draw the checkbox itself: note that this should really, really be in // wxRendererNative but unfortunately we can't add a new virtual function // to it without breaking backwards compatibility // classic Win32 version -- this can be useful when we move this into // wxRendererNative #if defined(__WXWINCE__) || !wxUSE_UXTHEME UINT state = DFCS_BUTTONCHECK; if ( !IsEnabled() ) state |= DFCS_INACTIVE; switch ( Get3StateValue() ) { case wxCHK_CHECKED: state |= DFCS_CHECKED; break; case wxCHK_UNDETERMINED: state |= DFCS_PUSHED; break; default: wxFAIL_MSG( _T("unexpected Get3StateValue() return value") ); // fall through case wxCHK_UNCHECKED: // no extra styles needed break; } if ( wxFindWindowAtPoint(wxGetMousePosition()) == this ) state |= DFCS_HOT; if ( !::DrawFrameControl(hdc, &rectCheck, DFC_BUTTON, state) ) { wxLogLastError(_T("DrawFrameControl(DFC_BUTTON)")); } #else // XP version wxUxThemeEngine *themeEngine = wxUxThemeEngine::GetIfActive(); if ( !themeEngine ) return false; wxUxThemeHandle theme(this, L"BUTTON"); if ( !theme ) return false; int state; switch ( Get3StateValue() ) { case wxCHK_CHECKED: state = CBS_CHECKEDNORMAL; break; case wxCHK_UNDETERMINED: state = CBS_MIXEDNORMAL; break; default: wxFAIL_MSG( _T("unexpected Get3StateValue() return value") ); // fall through case wxCHK_UNCHECKED: state = CBS_UNCHECKEDNORMAL; break; } if ( !IsEnabled() ) state += CBS_DISABLED_OFFSET; else if ( m_isPressed ) state += CBS_PRESSED_OFFSET; else if ( m_isHot ) state += CBS_HOT_OFFSET; HRESULT hr = themeEngine->DrawThemeBackground ( theme, hdc, BP_CHECKBOX, state, &rectCheck, NULL ); if ( FAILED(hr) ) { wxLogApiError(_T("DrawThemeBackground(BP_CHECKBOX)"), hr); } #endif // 0/1 // draw the text const wxString& label = GetLabel(); // first we need to measure it UINT fmt = DT_NOCLIP; // drawing underlying doesn't look well with focus rect (and the native // control doesn't do it) if ( isFocused ) fmt |= DT_HIDEPREFIX; if ( isRightAligned ) fmt |= DT_RIGHT; // TODO: also use DT_HIDEPREFIX if the system is configured so // we need to get the label real size first if we have to draw a focus rect // around it if ( isFocused ) { if ( !::DrawText(hdc, label, label.length(), &rectLabel, fmt | DT_CALCRECT) ) { wxLogLastError(_T("DrawText(DT_CALCRECT)")); } } if ( !IsEnabled() ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT)); } if ( !::DrawText(hdc, label, label.length(), &rectLabel, fmt) ) { wxLogLastError(_T("DrawText()")); } // finally draw the focus if ( isFocused ) { rectLabel.left--; rectLabel.right++; if ( !::DrawFocusRect(hdc, &rectLabel) ) { wxLogLastError(_T("DrawFocusRect()")); } } return true; }
bool wxCheckBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item; if ( !IsOwnerDrawn() || dis->CtlType != ODT_BUTTON ) return wxCheckBoxBase::MSWOnDraw(item); // calculate the rectangles for the check mark itself and the label HDC hdc = dis->hDC; RECT& rect = dis->rcItem; RECT rectCheck, rectLabel; rectLabel.top = rect.top + (rect.bottom - rect.top - GetBestSize().y) / 2; rectLabel.bottom = rectLabel.top + GetBestSize().y; const int MARGIN = 3; const int CXMENUCHECK = ::GetSystemMetrics(SM_CXMENUCHECK); // the space between the checkbox and the label is included in the // check-mark bitmap const int checkSize = wxMin(CXMENUCHECK - MARGIN, GetSize().y); rectCheck.top = rect.top + (rect.bottom - rect.top - checkSize) / 2; rectCheck.bottom = rectCheck.top + checkSize; const bool isRightAligned = HasFlag(wxALIGN_RIGHT); if ( isRightAligned ) { rectLabel.right = rect.right - CXMENUCHECK; rectLabel.left = rect.left; rectCheck.left = rectLabel.right + ( CXMENUCHECK + MARGIN - checkSize ) / 2; rectCheck.right = rectCheck.left + checkSize; } else // normal, left-aligned checkbox { rectCheck.left = rect.left + ( CXMENUCHECK - MARGIN - checkSize ) / 2; rectCheck.right = rectCheck.left + checkSize; rectLabel.left = rect.left + CXMENUCHECK; rectLabel.right = rect.right; } // shall we draw a focus rect? const bool isFocused = m_isPressed || FindFocus() == this; // draw the checkbox itself wxDCTemp dc(hdc); int flags = 0; if ( !IsEnabled() ) flags |= wxCONTROL_DISABLED; switch ( Get3StateValue() ) { case wxCHK_CHECKED: flags |= wxCONTROL_CHECKED; break; case wxCHK_UNDETERMINED: flags |= wxCONTROL_PRESSED; break; default: wxFAIL_MSG( wxT("unexpected Get3StateValue() return value") ); // fall through case wxCHK_UNCHECKED: // no extra styles needed break; } if ( wxFindWindowAtPoint(wxGetMousePosition()) == this ) flags |= wxCONTROL_CURRENT; wxRendererNative::Get(). DrawCheckBox(this, dc, wxRectFromRECT(rectCheck), flags); // draw the text const wxString& label = GetLabel(); // first we need to measure it UINT fmt = DT_NOCLIP; // drawing underlying doesn't look well with focus rect (and the native // control doesn't do it) if ( isFocused ) fmt |= DT_HIDEPREFIX; if ( isRightAligned ) fmt |= DT_RIGHT; // TODO: also use DT_HIDEPREFIX if the system is configured so // we need to get the label real size first if we have to draw a focus rect // around it if ( isFocused ) { RECT oldLabelRect = rectLabel; // needed if right aligned if ( !::DrawText(hdc, label.t_str(), label.length(), &rectLabel, fmt | DT_CALCRECT) ) { wxLogLastError(wxT("DrawText(DT_CALCRECT)")); } if ( isRightAligned ) { // move the label rect to the right const int labelWidth = rectLabel.right - rectLabel.left; rectLabel.right = oldLabelRect.right; rectLabel.left = rectLabel.right - labelWidth; } } if ( !IsEnabled() ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT)); } if ( !::DrawText(hdc, label.t_str(), label.length(), &rectLabel, fmt) ) { wxLogLastError(wxT("DrawText()")); } // finally draw the focus if ( isFocused ) { rectLabel.left--; rectLabel.right++; if ( !::DrawFocusRect(hdc, &rectLabel) ) { wxLogLastError(wxT("DrawFocusRect()")); } } return true; }
bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc, wxODAction WXUNUSED(act), wxODStatus stat) { const MenuDrawData* data = MenuDrawData::Get(); wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); HDC hdc = GetHdcOf(*impl); RECT rect; wxCopyRectToRECT(rc, rect); int imgWidth = wxMax(GetMarginWidth(), data->CheckSize.cx); if ( IsOwnerDrawn() ) { // font and colors to use wxFont font; GetFontToUse(font); wxColour colText, colBack; GetColourToUse(stat, colText, colBack); // calculate metrics of item parts RECT rcSelection = rect; data->ItemMargin.ApplyTo(rcSelection); RECT rcSeparator = rcSelection; data->SeparatorMargin.ApplyTo(rcSeparator); RECT rcGutter = rcSelection; rcGutter.right = data->ItemMargin.cxLeftWidth + data->CheckBgMargin.cxLeftWidth + data->CheckMargin.cxLeftWidth + imgWidth + data->CheckMargin.cxRightWidth + data->CheckBgMargin.cxRightWidth; RECT 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 // If a custom background colour is explicitly specified, we should use // it instead of the default theme background. wxUxThemeEngine* const theme = GetBackgroundColour().IsOk() ? NULL : MenuDrawData::GetUxThemeEngine(); if ( theme ) { POPUPITEMSTATES state; if ( stat & wxODDisabled ) { state = (stat & wxODSelected) ? MPI_DISABLEDHOT : MPI_DISABLED; } else if ( stat & wxODSelected ) { state = MPI_HOT; } else { state = MPI_NORMAL; } wxUxThemeHandle hTheme(GetMenu()->GetWindow(), L"MENU"); if ( theme->IsThemeBackgroundPartiallyTransparent(hTheme, MENU_POPUPITEM, state) ) { theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPBACKGROUND, 0, &rect, NULL); } theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPGUTTER, 0, &rcGutter, NULL); if ( IsSeparator() ) { rcSeparator.left = rcGutter.right; theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPSEPARATOR, 0, &rcSeparator, NULL); return true; } theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPITEM, state, &rcSelection, NULL); } else #endif // wxUSE_UXTHEME { if ( IsSeparator() ) { DrawEdge(hdc, &rcSeparator, EDGE_ETCHED, BF_TOP); return true; } AutoHBRUSH hbr(colBack.GetPixel()); SelectInHDC selBrush(hdc, hbr); ::FillRect(hdc, &rcSelection, hbr); } // draw text label // using native API because it recognizes '&' HDCTextColChanger changeTextCol(hdc, colText.GetPixel()); HDCBgColChanger changeBgCol(hdc, colBack.GetPixel()); HDCBgModeChanger changeBgMode(hdc, TRANSPARENT); SelectInHDC selFont(hdc, GetHfontOf(font)); // item text name without mnemonic for calculating size wxString text = GetName(); SIZE textSize; ::GetTextExtentPoint32(hdc, text.c_str(), text.length(), &textSize); // item text name with mnemonic text = GetItemLabel().BeforeFirst('\t'); int flags = DST_PREFIXTEXT; // themes menu is using specified color for disabled labels if ( data->MenuLayout() == MenuDrawData::Classic && (stat & wxODDisabled) && !(stat & wxODSelected) ) flags |= DSS_DISABLED; if ( (stat & wxODHidePrefix) && !data->AlwaysShowCues ) flags |= DSS_HIDEPREFIX; int x = rcText.left; int y = rcText.top + (rcText.bottom - rcText.top - textSize.cy) / 2; ::DrawState(hdc, NULL, NULL, wxMSW_CONV_LPARAM(text), text.length(), x, y, 0, 0, flags); // ::SetTextAlign(hdc, TA_RIGHT) doesn't work with DSS_DISABLED or DSS_MONO // as the last parameter in DrawState() (at least with Windows98). So we have // to take care of right alignment ourselves. wxString accel = GetItemLabel().AfterFirst(wxT('\t')); if ( !accel.empty() ) { SIZE accelSize; ::GetTextExtentPoint32(hdc, accel.c_str(), accel.length(), &accelSize); flags = DST_TEXT; // themes menu is using specified color for disabled labels if ( data->MenuLayout() == MenuDrawData::Classic && (stat & wxODDisabled) && !(stat & wxODSelected) ) flags |= DSS_DISABLED; x = rcText.right - data->ArrowMargin.GetTotalX() - data->ArrowSize.cx - data->ArrowBorder; // right align accel on FullTheme menu, left otherwise if ( data->MenuLayout() == MenuDrawData::FullTheme) x -= accelSize.cx; else x -= m_parentMenu->GetMaxAccelWidth(); y = rcText.top + (rcText.bottom - rcText.top - accelSize.cy) / 2; ::DrawState(hdc, NULL, NULL, wxMSW_CONV_LPARAM(accel), accel.length(), x, y, 0, 0, flags); } } // 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; }
bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height) { const MenuDrawData* data = MenuDrawData::Get(); if ( IsOwnerDrawn() ) { *width = data->ItemMargin.GetTotalX(); *height = data->ItemMargin.GetTotalY(); if ( IsSeparator() ) { *width += data->SeparatorSize.cx + data->SeparatorMargin.GetTotalX(); *height += data->SeparatorSize.cy + data->SeparatorMargin.GetTotalY(); return true; } wxString str = GetName(); wxMemoryDC dc; wxFont font; GetFontToUse(font); dc.SetFont(font); wxCoord w, h; dc.GetTextExtent(str, &w, &h); *width = data->TextBorder + w + data->AccelBorder; *height = h; w = m_parentMenu->GetMaxAccelWidth(); if ( w > 0 ) *width += w + data->ArrowBorder; *width += data->Offset; *width += data->ArrowMargin.GetTotalX() + data->ArrowSize.cx; } else // don't draw the text, just the bitmap (if any) { *width = 0; *height = 0; } // bitmap if ( IsOwnerDrawn() ) { // 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 // bitmap in menu (GetMarginWidth()) unless std check mark is wider, // then it's is set to std mark's width int imgWidth = wxMax(GetMarginWidth(), data->CheckSize.cx) + data->CheckMargin.GetTotalX(); *width += imgWidth + data->CheckBgMargin.GetTotalX(); } if ( m_bmpChecked.IsOk() || m_bmpUnchecked.IsOk() ) { // get size of bitmap always return valid value (0 for invalid bitmap), // so we don't needed check if bitmap is valid ;) size_t heightBmp = wxMax(m_bmpChecked.GetHeight(), m_bmpUnchecked.GetHeight()); size_t widthBmp = wxMax(m_bmpChecked.GetWidth(), m_bmpUnchecked.GetWidth()); if ( IsOwnerDrawn() ) { heightBmp += data->CheckMargin.GetTotalY(); } else { // we must allocate enough space for the bitmap *width += widthBmp; } // Is BMP height larger than text height? if ( *height < heightBmp ) *height = heightBmp; } // make sure that this item is at least as tall as the system menu height const size_t menuHeight = data->CheckMargin.GetTotalY() + data->CheckSize.cy; if (*height < menuHeight) *height = menuHeight; return true; }
void wxMenuItem::DoSetBitmap(const wxBitmap& bmp, bool bChecked) { if ( bChecked ) { if ( m_bmpChecked.IsSameAs(bmp) ) return; m_bmpChecked = bmp; } else { if ( m_bmpUnchecked.IsSameAs(bmp) ) return; m_bmpUnchecked = bmp; } #if wxUSE_OWNER_DRAWN // already marked as owner-drawn, cannot be reverted if ( IsOwnerDrawn() ) return; if ( MSWMustUseOwnerDrawn() ) { SetOwnerDrawn(true); // Parent menu has to be rearranged/recalculated in this case // (all other menu items have to be also set to owner-drawn mode). if ( m_parentMenu ) { size_t pos; wxMenuItem *item = m_parentMenu->FindChildItem(GetMSWId(), &pos); if ( item ) { wxCHECK_RET( item == this, wxS("Non unique menu item ID?") ); m_parentMenu->Remove(this); m_parentMenu->Insert(pos, this); } //else: the item hasn't been inserted into the parent menu yet } return; } #endif // wxUSE_OWNER_DRAWN // the item can be not attached to any menu yet and SetBitmap() is still // valid to call in this case and should do nothing else if ( !m_parentMenu ) return; HMENU hMenu = GetHMenuOf(m_parentMenu); if ( !hMenu ) return; const UINT id = GetMSWId(); const UINT state = ::GetMenuState(hMenu, id, MF_BYCOMMAND); if ( state == (UINT)-1 ) return; // update the bitmap of the native menu item // don't set hbmpItem for the checkable items as it would // be used for both checked and unchecked state WinStruct<MENUITEMINFO> mii; if ( IsCheckable() ) { mii.fMask = MIIM_CHECKMARKS; mii.hbmpChecked = GetHBitmapForMenu(true); mii.hbmpUnchecked = GetHBitmapForMenu(false); } else { mii.fMask = MIIM_BITMAP; mii.hbmpItem = GetHBitmapForMenu(); } if ( !::SetMenuItemInfo(hMenu, id, FALSE, &mii) ) { wxLogLastError(wxT("SetMenuItemInfo")); } }
bool gcCheckBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) { DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item; if ( !IsOwnerDrawn() || dis->CtlType != ODT_BUTTON ) return wxCheckBoxBase::MSWOnDraw(item); // calculate the rectangles for the check mark itself and the label HDC hdc = dis->hDC; RECT& rect = dis->rcItem; RECT rectCheck, rectLabel; rectCheck.top = rectLabel.top = rect.top; rectCheck.bottom = rectLabel.bottom = rect.bottom; const int checkSize = GetBestSize().y; const int MARGIN = 3; const bool isRightAligned = HasFlag(wxALIGN_RIGHT); if ( isRightAligned ) { rectCheck.right = rect.right; rectCheck.left = rectCheck.right - checkSize; rectLabel.right = rectCheck.left - MARGIN; rectLabel.left = rect.left; } else // normal, left-aligned checkbox { rectCheck.left = rect.left; rectCheck.right = rectCheck.left + checkSize; rectLabel.left = rectCheck.right + MARGIN; rectLabel.right = rect.right; } // show we draw a focus rect? const bool isFocused = IsChecked() || FindFocus() == this; // draw the checkbox itself wxDCTemp dc(hdc); int flags = 0; if ( !IsEnabled() ) flags |= wxCONTROL_DISABLED; switch ( Get3StateValue() ) { case wxCHK_CHECKED: flags |= wxCONTROL_CHECKED; break; case wxCHK_UNDETERMINED: flags |= wxCONTROL_PRESSED; break; default: wxFAIL_MSG( _T("unexpected Get3StateValue() return value") ); // fall through case wxCHK_UNCHECKED: // no extra styles needed break; } if ( wxFindWindowAtPoint(wxGetMousePosition()) == this ) flags |= wxCONTROL_CURRENT; wxRendererNative::Get(). DrawCheckBox(this, dc, wxRectFromRECT(rectCheck), flags); // draw the text const wxString& label = GetLabel(); // first we need to measure it UINT fmt = DT_NOCLIP; // drawing underlying doesn't look well with focus rect (and the native // control doesn't do it) if ( isFocused ) fmt |= DT_HIDEPREFIX; if ( isRightAligned ) fmt |= DT_RIGHT; // TODO: also use DT_HIDEPREFIX if the system is configured so // we need to get the label real size first if we have to draw a focus rect // around it if ( isFocused ) { if ( !::DrawText(hdc, label.wx_str(), label.length(), &rectLabel, fmt | DT_CALCRECT) ) { wxLogLastError(_T("DrawText(DT_CALCRECT)")); } } if ( !IsEnabled() ) { ::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT)); } if ( !::DrawText(hdc, label.wx_str(), label.length(), &rectLabel, fmt) ) { wxLogLastError(_T("DrawText()")); } //// finally draw the focus if ( isFocused ) { COLORREF colBg = wxColourToRGB(wxColor(GetGCThemeManager()->getColor("checkbox", "focus-fg"))); HBRUSH hbrush = ::CreateSolidBrush(colBg); rectLabel.left--; rectLabel.right++; ::FrameRect(hdc, &rectLabel, hbrush); ::DeleteObject(hbrush); } return true; }
void wxMenuItem::SetItemLabel(const wxString& txt) { wxString text = txt; // don't do anything if label didn't change if ( m_text == txt ) return; // wxMenuItemBase will do stock ID checks wxMenuItemBase::SetItemLabel(text); // the item can be not attached to any menu yet and SetItemLabel() is still // valid to call in this case and should do nothing else if ( !m_parentMenu ) return; #if wxUSE_ACCEL m_parentMenu->UpdateAccel(this); #endif // wxUSE_ACCEL const UINT id = GetMSWId(); HMENU hMenu = GetHMenuOf(m_parentMenu); if ( !hMenu || ::GetMenuState(hMenu, id, MF_BYCOMMAND) == (UINT)-1 ) return; #if wxUSE_OWNER_DRAWN if ( IsOwnerDrawn() ) { // we don't need to do anything for owner drawn items, they will redraw // themselves using the new text the next time they're displayed return; } #endif // owner drawn // update the text of the native menu item WinStruct<MENUITEMINFO> info; // surprisingly, calling SetMenuItemInfo() with just MIIM_STRING doesn't // work as it resets the menu bitmap, so we need to first get the old item // state and then modify it const bool isLaterThanWin95 = wxGetWinVersion() > wxWinVersion_95; info.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA; if ( isLaterThanWin95 ) info.fMask |= MIIM_BITMAP | MIIM_FTYPE; else info.fMask |= MIIM_TYPE; if ( !::GetMenuItemInfo(hMenu, id, FALSE, &info) ) { wxLogLastError(wxT("GetMenuItemInfo")); return; } if ( isLaterThanWin95 ) info.fMask |= MIIM_STRING; //else: MIIM_TYPE already specified info.dwTypeData = (LPTSTR)m_text.wx_str(); info.cch = m_text.length(); if ( !::SetMenuItemInfo(hMenu, id, FALSE, &info) ) { wxLogLastError(wxT("SetMenuItemInfo")); } }