2017-05-02 6 views
0

Voici le morceau de code qui me donne un problème:PopupMenu de MenuBar quand un clic droit

void CMainFrame::DisplayActionsPopupMenu() 
{ 
    // get "Actions" menu 
    wxMenuBar* pMenuBar = GetMenuBar(); 
    ASSERT(pMenuBar != NULL); 
    int nIndex = pMenuBar->FindMenu("Actions"); 
    ASSERT(nIndex != wxNOT_FOUND); 
    wxMenu *pMenuActions = pMenuBar->GetMenu(nIndex); 
    ASSERT(pMenuActions != NULL); 
    // display a popup menu for actions 
    PopupMenu(pMenuActions); 
} 

Ce que j'essaie de faire ici est d'afficher un popupmenu quand un clic droit et je veux que ce soit le même comme le deuxième menu dans la barre de menu de mon projet.

Il a travaillé quand je compilé avec wxWidgets v2.8

Maintenant j'ai essayé avec v3.0 et est l'erreur ici:

../src/common/menucmn.cpp(715): assert "!IsAttached()" failed in SetInvokingWindow(): menus attached to menu bar can't have invoking window 

Que dois-je faire pour résoudre ce problème?

+0

pouvez-vous poster le backtrace complet? – Igor

+0

J'ai posté la solution. Merci @Igor! –

Répondre

1

Enfin, j'ai trouvé qu'avec la version > 3.0 wxWidgets, vous ne pouvez pas obtenir les éléments de wxMenuBar qui est attaché à votre cadre. Donc vous devez provisoirement vous désattacher et le rattacher.

Voici comment vous donc:

1 - Initialiser le nouveau wxMenu avec la barre de menus. Dans mon cas:

wxMenuBar* pMenuBar = GetMenuBar(); 
ASSERT(pMenuBar != NULL); 
cout<<pMenuBar->IsAttached()<<endl; 
int nIndex = pMenuBar->FindMenu("Actions"); 
ASSERT(nIndex != wxNOT_FOUND); 
wxMenu *pMenuActions = pMenuBar->GetMenu(nIndex); 

2 - Vérifier s'il est attaché:

if(pMenuActions->IsAttached()){ 
    pMenuActions->Detach(); 
} 

3 - Lorsque vous avez terminé, remettre en place le wxMenu au wxMenuBar

pMenuActions->Attach(pMenuBar); 
2

Je pense qu'une solution plus robuste que la réponse existante consistant à détacher et à rattacher le menu serait simplement de créer un nouveau menu, par exemple quelque chose comme ceci:

std::unique_ptr<wxMenu> CreateActionsMenu() { ... } 

// In your frame ctor or wherever you initialize your menu bar. 
MyFrame::MyFrame() { 
    wxMenuBar* const mb = new wxMenuBar; 
    mb->Append(CreateActionsMenu().release(), "&Actions"); 
    SetMenuBar(mb); 
} 

// In your event handler function showing the popup menu. 
void MyFrame::OnShowPopup(wxCommandEvent&) { 
    auto menu = CreateActionsMenu(); 
    PopupMenu(menu.get()); 
} 

Création d'un menu est relativement rapide et il devrait y avoir aucun problème à faire juste avant de le montrer (même si, bien sûr, vous pouvez également mettre en cache pour plus tard si elle est vraiment énorme ou autrement cher construction).