bool wxMenuItem::IsChecked() const { wxCHECK_MSG( m_menuItem, false, wxT("invalid menu item") ); wxCHECK_MSG( IsCheckable(), false, wxT("can't get state of uncheckable item!") ); return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(m_menuItem)) != 0; }
bool wxMenuItem::IsChecked() const { wxCHECK_MSG( m_menuItem, false, wxT("invalid menu item") ); wxCHECK_MSG( IsCheckable(), false, wxT("can't get state of uncheckable item!") ); return ((GtkCheckMenuItem*)m_menuItem)->active != 0; }
void wxMenuItem::Check(bool bDoCheck) { wxCHECK_RET( IsCheckable() && !IsSeparator(), wxT("only checkable items may be checked") ); if ( m_isChecked != bDoCheck ) { if ( GetKind() == wxITEM_RADIO ) { if ( bDoCheck ) { wxMenuItemBase::Check( bDoCheck ) ; UpdateItemStatus() ; // get the index of this item in the menu const wxMenuItemList& items = m_parentMenu->GetMenuItems(); int pos = items.IndexOf(this); wxCHECK_RET( pos != wxNOT_FOUND, wxT("menuitem not found in the menu items list?") ); // get the radio group range int start, end; if ( m_isRadioGroupStart ) { // we already have all information we need start = pos; end = m_radioGroup.end; } else // next radio group item { // get the radio group end from the start item start = m_radioGroup.start; end = items.Item(start)->GetData()->m_radioGroup.end; } // also uncheck all the other items in this radio group wxMenuItemList::compatibility_iterator node = items.Item(start); for ( int n = start; n <= end && node; n++ ) { if ( n != pos ) ((wxMenuItem*)node->GetData())->UncheckRadio(); node = node->GetNext(); } } } else { wxMenuItemBase::Check( bDoCheck ) ; UpdateItemStatus() ; } } }
void wxMenuItem::UpdateItemStatus() { if ( !m_parentMenu ) return ; if ( IsSeparator() ) return ; if ( IsCheckable() && IsChecked() ) GetPeer()->Check( true ); else GetPeer()->Check( false ); GetPeer()->Enable( IsEnabled() ); }
void wxMenuItem::DestroyItem(bool full) { if (GetId() == -3) { ; // Nothing } else if (!m_text.empty() && !m_subMenu) { if (m_buttonWidget) { if (IsCheckable()) XtRemoveCallback ((Widget) m_buttonWidget, XmNvalueChangedCallback, wxMenuItemCallback, (XtPointer) this); else XtRemoveCallback ((Widget) m_buttonWidget, XmNactivateCallback, wxMenuItemCallback, (XtPointer) this); XtRemoveCallback ((Widget) m_buttonWidget, XmNarmCallback, wxMenuItemArmCallback, (XtPointer) this); XtRemoveCallback ((Widget) m_buttonWidget, XmNdisarmCallback, wxMenuItemDisarmCallback, (XtPointer) this); } } else if (IsSeparator()) { ; // Nothing } else if (GetSubMenu()) { if (m_buttonWidget) { XtRemoveCallback ((Widget) m_buttonWidget, XmNcascadingCallback, wxMenuItemArmCallback, (XtPointer) this); } m_subMenu->DestroyMenu(full); if (full) m_buttonWidget = NULL; } if (m_buttonWidget && full) { XtDestroyWidget ((Widget) m_buttonWidget); m_buttonWidget = (WXWidget) 0; } }
void wxMenuItem::UpdateItemStatus() { if ( !m_parentMenu ) return ; if ( IsSeparator() ) return ; #if TARGET_CARBON if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macPreferencesMenuItemId) { if ( !IsEnabled() ) DisableMenuCommand( NULL , kHICommandPreferences ) ; else EnableMenuCommand( NULL , kHICommandPreferences ) ; } if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macExitMenuItemId) { if ( !IsEnabled() ) DisableMenuCommand( NULL , kHICommandQuit ) ; else EnableMenuCommand( NULL , kHICommandQuit ) ; } #endif { MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ; MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ; if ( mhandle == NULL || index == 0) return ; UMAEnableMenuItem( mhandle , index , m_isEnabled ) ; if ( IsCheckable() && IsChecked() ) ::SetItemMark( mhandle , index , 0x12 ) ; // checkmark else ::SetItemMark( mhandle , index , 0 ) ; // no mark UMASetMenuItemText( mhandle , index , wxStripMenuCodes(m_text) , wxFont::GetDefaultEncoding() ) ; wxAcceleratorEntry *entry = wxAcceleratorEntry::Create( m_text ) ; UMASetMenuItemShortcut( mhandle , index , entry ) ; delete entry ; } }
void wxMenuItem::Check(bool bDoCheck) { wxCHECK_RET( IsCheckable(), "only checkable items may be checked" ); if ( m_isChecked != bDoCheck ) { if ( m_buttonWidget ) { wxASSERT_MSG( XtIsSubclass((Widget)m_buttonWidget, xmToggleButtonGadgetClass), wxT("checkable menu item must be a toggle button") ); XtVaSetValues((Widget)m_buttonWidget, XmNset, (Boolean)bDoCheck, NULL); } wxMenuItemBase::Check(bDoCheck); } }
bool wxMenuItem::OnDrawItem( wxDC& rDC, const wxRect& rRect, wxODAction eAction, wxODStatus eStatus ) { // // Select the font and draw the text // --------------------------------- // CHARBUNDLE vCbnd; wxPMDCImpl *impl = (wxPMDCImpl*) rDC.GetImpl(); HPS hPS= impl->GetHPS(); wxFont vFont; wxColour vColBack; wxColour vColText; COLORREF vRef; RECTL vRect = {rRect.x + 4, rRect.y + 1, rRect.x + (rRect.width - 2), rRect.y + rRect.height}; memset(&vCbnd, 0, sizeof(CHARBUNDLE)); GetFontToUse(vFont); GetColourToUse(eStatus, vColText, vColBack); rDC.SetFont(vFont); rDC.SetTextBackground(vColBack); rDC.SetTextForeground(vColText); rDC.SetBackgroundMode(wxTRANSPARENT); vCbnd.lColor = vColText.GetPixel(); vCbnd.lBackColor = vColBack.GetPixel(); ::GpiSetAttrs( hPS ,PRIM_CHAR ,CBB_BACK_COLOR | CBB_COLOR ,0 ,&vCbnd ); ::GpiSetBackMix( hPS ,BM_LEAVEALONE ); // // Paint the background // ::WinFillRect(hPS, &vRect, vColBack.GetPixel()); // // Determine where to draw and leave space for a check-mark. // int nX = rRect.x + GetMarginWidth(); // // Unfortunately, unlike Win32, PM has no owner drawn specific text // drawing methods like ::DrawState that can cleanly handle accel // mnemonics and deal, automatically, with various states, so we have // to handle them ourselves. Notice Win32 can't handle \t in ownerdrawn // strings either. We cannot handle mnemonics either. We display // them, though, in the hope we can figure them out some day. // // // Display main text and accel text separately to align better // wxString sTgt = wxT("\t"); wxString sFullString = GetItemLabel(); // need to save the original text wxString sAccel; int nIndex; size_t nWidth; size_t nCharWidth; size_t nHeight; bool bFoundMnemonic = false; bool bFoundAccel = false; // // Deal with the tab, extracting the Accel text // nIndex = sFullString.Find(sTgt); if (nIndex != -1) { bFoundAccel = true; sAccel = sFullString.Mid(nIndex + 1); sFullString.Remove(nIndex); } // // Deal with the mnemonic character // sTgt = wxT("~"); nIndex = sFullString.Find(sTgt); if (nIndex != -1) { wxString sTmp = sFullString; bFoundMnemonic = true; sTmp.Remove(nIndex); rDC.GetTextExtent( sTmp ,(wxCoord *)&nWidth ,(wxCoord *)&nHeight ); sTmp = sFullString[(size_t)(nIndex + 1)]; rDC.GetTextExtent( sTmp ,(wxCoord *)&nCharWidth ,(wxCoord *)&nHeight ); sFullString.Replace(sTgt.c_str(), wxEmptyString, true); } // // Draw the main item text sans the accel text // POINTL vPntStart = {nX, rRect.y + 4}; ::GpiCharStringAt( impl->GetHPS() ,&vPntStart ,sFullString.length() ,sFullString.char_str() ); if (bFoundMnemonic) { // // Underline the mnemonic -- still won't work, but at least it "looks" right // wxPen vPen; POINTL vPntEnd = {nX + nWidth + nCharWidth - 3, rRect.y + 2}; //CharWidth is bit wide vPntStart.x = nX + nWidth - 1; vPntStart.y = rRect.y + 2; // Make it look pretty! vPen = wxPen(vColText, 1, wxSOLID); // Assuming we are always black rDC.SetPen(vPen); ::GpiMove(hPS, &vPntStart); ::GpiLine(hPS, &vPntEnd); } // // Now draw the accel text // if (bFoundAccel) { size_t nWidth; size_t nHeight; rDC.GetTextExtent( sAccel ,(wxCoord *)&nWidth ,(wxCoord *)&nHeight ); // // Back off the starting position from the right edge // vPntStart.x = rRect.width - (nWidth + 7); vPntStart.y = rRect.y + 4; ::GpiCharStringAt( impl->GetHPS() ,&vPntStart ,sAccel.length() ,sAccel.char_str() ); } // // Draw the bitmap // --------------- // if (IsCheckable() && !m_bmpChecked.IsOk()) { if (eStatus & wxODChecked) { RECTL vRect; HBITMAP hBmpCheck = ::WinGetSysBitmap(HWND_DESKTOP, SBMP_MENUCHECK); vRect.xLeft = rRect.x; vRect.xRight = rRect.x + GetMarginWidth(); vRect.yBottom = rRect.y; vRect.yTop = rRect.y + m_nHeight - 3; ::WinDrawBitmap( hPS // PS for this menuitem ,hBmpCheck // system checkmark ,NULL // draw the whole bitmap ,(PPOINTL)&vRect // destination -- bottom left corner of the menuitem area ,0L // ignored ,0L // draw a bitmap ,DBM_NORMAL // draw normal size ); } } else { // // For uncheckable item we use only the 'checked' bitmap // wxBitmap vBmp(GetBitmap(IsCheckable() ? ((eStatus & wxODChecked) != 0) : TRUE)); if (vBmp.IsOk()) { wxMemoryDC vDCMem(&rDC); wxMemoryDC* pOldDC = (wxMemoryDC*)vBmp.GetSelectedInto(); if(pOldDC != NULL) { vBmp.SetSelectedInto(NULL); } vDCMem.SelectObject(vBmp); // // Center bitmap // int nBmpWidth = vBmp.GetWidth(); int nBmpHeight = vBmp.GetHeight(); // // There should be enough space! // wxASSERT((nBmpWidth <= rRect.width) && (nBmpHeight <= rRect.height)); int nHeightDiff = m_nHeight - nBmpHeight; rDC.Blit( rRect.x + (GetMarginWidth() - nBmpWidth) / 2 ,rRect.y + nHeightDiff / 2 ,nBmpWidth ,nBmpHeight ,&vDCMem ,0 ,0 ,wxCOPY ,true ); if (eStatus & wxODSelected) { POINTL vPnt1 = {rRect.x + 1, rRect.y + 3}; // Leave a little background border POINTL vPnt2 = {rRect.x + GetMarginWidth(), rRect.y + m_nHeight - 3}; LINEBUNDLE vLine; vLine.lColor = vColBack.GetPixel(); ::GpiSetAttrs( hPS ,PRIM_LINE ,LBB_COLOR ,0 ,&vLine ); ::GpiMove(hPS, &vPnt1); ::GpiBox( hPS ,DRO_OUTLINE ,&vPnt2 ,0L ,0L ); } vBmp.SetSelectedInto(NULL); } } return true; } // end of wxOwnerDrawn::OnDrawItem
void wxMenuItem::Check( bool bCheck ) { bool bOk; wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") ); if (m_isChecked == bCheck) return; HMENU hMenu = GetHmenuOf(m_parentMenu); if (GetKind() == wxITEM_RADIO) { // // It doesn't make sense to uncheck a radio item - what would this do? // if (!bCheck) return; // // Get the index of this item in the menu // const wxMenuItemList& rItems = m_parentMenu->GetMenuItems(); int nPos = rItems.IndexOf(this); wxCHECK_RET( nPos != wxNOT_FOUND ,wxT("menuitem not found in the menu items list?") ); // // Get the radio group range // int nStart; int nEnd; if (m_bIsRadioGroupStart) { // // We already have all information we need // nStart = nPos; nEnd = m_vRadioGroup.m_nEnd; } else // next radio group item { // // Get the radio group end from the start item // nStart = m_vRadioGroup.m_nStart; nEnd = rItems.Item(nStart)->GetData()->m_vRadioGroup.m_nEnd; } // // Also uncheck all the other items in this radio group // wxMenuItemList::compatibility_iterator node = rItems.Item(nStart); for (int n = nStart; n <= nEnd && node; n++) { if (n == nPos) { ::WinSendMsg( hMenu ,MM_SETITEMATTR ,MPFROM2SHORT(n, TRUE) ,MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED) ); } if (n != nPos) { node->GetData()->m_isChecked = FALSE; ::WinSendMsg( hMenu ,MM_SETITEMATTR ,MPFROM2SHORT(n, TRUE) ,MPFROM2SHORT(MIA_CHECKED, FALSE) ); } node = node->GetNext(); } } else // check item { if (bCheck) bOk = (bool)::WinSendMsg( hMenu ,MM_SETITEMATTR ,MPFROM2SHORT(GetRealId(), TRUE) ,MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED) ); else bOk = (bool)::WinSendMsg( hMenu ,MM_SETITEMATTR ,MPFROM2SHORT(GetRealId(), TRUE) ,MPFROM2SHORT(MIA_CHECKED, FALSE) ); } if (!bOk) { wxLogLastError(wxT("CheckMenuItem")); } wxMenuItemBase::Check(bCheck); } // end of wxMenuItem::Check
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; }
void wxMenuItem::Check(bool check) { wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") ); if ( m_isChecked == check ) return; if ( m_parentMenu ) { int flags = check ? MF_CHECKED : MF_UNCHECKED; HMENU hmenu = GetHMenuOf(m_parentMenu); if ( GetKind() == wxITEM_RADIO ) { // it doesn't make sense to uncheck a radio item -- what would this // do? if ( !check ) return; // get the index of this item in the menu const wxMenuItemList& items = m_parentMenu->GetMenuItems(); int pos = items.IndexOf(this); wxCHECK_RET( pos != wxNOT_FOUND, wxT("menuitem not found in the menu items list?") ); // get the radio group range int start, end; if ( !m_parentMenu->MSWGetRadioGroupRange(pos, &start, &end) ) { wxFAIL_MSG( wxT("Menu radio item not part of radio group?") ); return; } #ifdef __WIN32__ // calling CheckMenuRadioItem() with such parameters hangs my system // (NT4 SP6) and I suspect this could happen to the others as well, // so don't do it! wxCHECK_RET( start != -1 && end != -1, wxT("invalid ::CheckMenuRadioItem() parameter(s)") ); if ( !::CheckMenuRadioItem(hmenu, start, // the first radio group item end, // the last one pos, // the one to check MF_BYPOSITION) ) { wxLogLastError(wxT("CheckMenuRadioItem")); } #endif // __WIN32__ // also uncheck all the other items in this radio group wxMenuItemList::compatibility_iterator node = items.Item(start); for ( int n = start; n <= end && node; n++ ) { if ( n != pos ) { node->GetData()->m_isChecked = false; } node = node->GetNext(); } } else // check item { if ( ::CheckMenuItem(hmenu, GetMSWId(), MF_BYCOMMAND | flags) == (DWORD)-1 ) { wxFAIL_MSG(wxT("CheckMenuItem() failed, item not in the menu?")); } } } wxMenuItemBase::Check(check); }
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")); } }
void wxMenuItem::CreateItem (WXWidget menu, wxMenuBar * menuBar, wxMenu * topMenu, size_t index) { m_menuBar = menuBar; m_topMenu = topMenu; if (GetId() == -3) { // Id=-3 identifies a Title item. m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (wxStripMenuCodes(m_text), xmLabelGadgetClass, (Widget) menu, NULL); } else if (!IsSeparator() && !m_subMenu) { wxString txt = m_text; if (m_text.IsEmpty()) { wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?")); txt = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC); } wxString strName = wxStripMenuCodes(txt); if (IsCheckable()) { m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (strName, xmToggleButtonGadgetClass, (Widget) menu, #ifdef XmNpositionIndex XmNpositionIndex, index, #endif NULL); XtVaSetValues ((Widget) m_buttonWidget, XmNset, (Boolean) IsChecked(), NULL); } else m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (strName, xmPushButtonGadgetClass, (Widget) menu, #ifdef XmNpositionIndex XmNpositionIndex, index, #endif NULL); char mnem = wxFindMnemonic (m_text); if (mnem != 0) XtVaSetValues ((Widget) m_buttonWidget, XmNmnemonic, mnem, NULL); //// TODO: proper accelerator treatment. What does wxFindAccelerator //// look for? strName = m_text; char *accel = wxFindAccelerator (strName); if (accel) XtVaSetValues ((Widget) m_buttonWidget, XmNaccelerator, accel, NULL); // TODO: What does this do? XmString accel_str = wxFindAcceleratorText (strName); if (accel_str) { XtVaSetValues ((Widget) m_buttonWidget, XmNacceleratorText, accel_str, NULL); XmStringFree (accel_str); } if (IsCheckable()) XtAddCallback ((Widget) m_buttonWidget, XmNvalueChangedCallback, (XtCallbackProc) wxMenuItemCallback, (XtPointer) this); else XtAddCallback ((Widget) m_buttonWidget, XmNactivateCallback, (XtCallbackProc) wxMenuItemCallback, (XtPointer) this); XtAddCallback ((Widget) m_buttonWidget, XmNarmCallback, (XtCallbackProc) wxMenuItemArmCallback, (XtPointer) this); XtAddCallback ((Widget) m_buttonWidget, XmNdisarmCallback, (XtCallbackProc) wxMenuItemDisarmCallback, (XtPointer) this); } else if (IsSeparator()) { m_buttonWidget = (WXWidget) XtVaCreateManagedWidget ("separator", xmSeparatorGadgetClass, (Widget) menu, #ifndef XmNpositionIndex XmNpositionIndex, index, #endif NULL); } else if (m_subMenu) { m_buttonWidget = m_subMenu->CreateMenu (menuBar, menu, topMenu, index, m_text, true); m_subMenu->SetButtonWidget(m_buttonWidget); XtAddCallback ((Widget) m_buttonWidget, XmNcascadingCallback, (XtCallbackProc) wxMenuItemArmCallback, (XtPointer) this); } if (m_buttonWidget) XtSetSensitive ((Widget) m_buttonWidget, (Boolean) IsEnabled()); }