Вот фрагмент кода, который вызывает у меня проблему:
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);
}
Здесь я пытаюсь отобразить всплывающее меню при щелчке правой кнопкой мыши, и я хочу, чтобы оно было таким же, как и второе меню в меню моего проекта.
Это сработало, когда я скомпилировал с wxWidgets v2.8
Сейчас я попробовал с v3.0 и вот ошибка:
../src/common/menucmn.cpp(715): assert "!IsAttached()" failed in SetInvokingWindow(): menus attached to menu bar can't have invoking window
Что я должен сделать, чтобы это исправить?
Я думаю, что более надежным решением, чем существующий ответ, состоящий в отсоединении и присоединении меню, было бы просто создать вместо него новое меню, например что-то вроде этого:
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());
}
Создание меню является относительно быстрым, и не должно быть никаких проблем с его выполнением непосредственно перед его показом (хотя, конечно, вы также можете кэшировать его на потом, если оно действительно огромное или иным образом дорогое).
Наконец я обнаружил, что с > 3.0 wxWidgets версия, вы не можете получить элементы из wxMenuBar, который прикреплен к вашему фрейму. Таким образом, вы должны временно отсоединить и снова прикрепить его.
Вот как бы вы это сделали:
1 — Инициализируйте новое wxMenu с помощью панели меню. В моем случае:
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 — Проверьте, если он прикреплен:
if(pMenuActions->IsAttached()){
pMenuActions->Detach();
}
3 — Когда вы закончите, присоедините wxMenu к wxMenuBar
pMenuActions->Attach(pMenuBar);