2011-04-25 28 views
3

wxWidgets應用程序顯示主窗口狀態欄中正常菜單項的幫助字符串。不幸的是,它似乎沒有顯示它們與wxWindow::PopupMenu命令調用的菜單,我需要它。如何顯示wxWidgets彈出式菜單的幫助字符串?

我試着給父窗口添加一個EVT_MENU_HIGHLIGHT_ALL處理程序,但它沒有被調用。

需要一些方法來處理或重定向消息以顯示幫助文本。我錯過了什麼?

回答

1

我試着通過wxFrame而不是當前窗口調用它(一個wxListCtrl)。這有幫助,但並不多:當鼠標移動到彈出式菜單項上時,它會清除狀態欄,但不會顯示幫助文本。

當我挖掘到wxWidgets源代碼時,我發現原因:我的彈出菜單的項目不在菜單欄上。 wxWidgets將菜單項的ID發送到菜單欄以獲取文本,在這種情況下顯然失敗。

花了一番努力,但我想通了,解決問題的方式:(findStatusBar是一個方便的功能定位程序的框架窗口和調用GetStatusBar

//////////////////////////////////////////////////////////////////////////// 
// In a header file... 

class PopupMenu: public wxMenu { 
    public: // 
    PopupMenu(): mPushed(false) { } 

    void OnOpen(wxMenuEvent &evt); 
    void OnClose(wxMenuEvent &evt); 
    void OnShowMenuHelp(wxMenuEvent &evt); 

    private: // 
    bool mPushed; 

    DECLARE_EVENT_TABLE() 
}; 

//////////////////////////////////////////////////////////////////////////// 
// In a cpp file... 

BEGIN_EVENT_TABLE(PopupMenu, wxMenu) 
    EVT_MENU_OPEN(PopupMenu::OnOpen) 
    EVT_MENU_CLOSE(PopupMenu::OnClose) 
    EVT_MENU_HIGHLIGHT(wxID_ANY, PopupMenu::OnShowMenuHelp) 
END_EVENT_TABLE() 

void PopupMenu::OnOpen(wxMenuEvent &evt) { 
    if (!mPushed) { 
     // Clear it 
     findStatusBar()->PushStatusText(wxString()); 
     mPushed = true; 
    } 
} 

void PopupMenu::OnClose(wxMenuEvent &evt) { 
    if (mPushed) { 
     findStatusBar()->PopStatusText(); 
     mPushed = false; 
    } 
} 

void PopupMenu::OnShowMenuHelp(wxMenuEvent &evt) { 
    if (mPushed) { 
     findStatusBar()->SetStatusText(GetHelpString(evt.GetMenuId())); 
    } else { 
     findStatusBar()->PushStatusText(GetHelpString(evt.GetMenuId())); 
     mPushed = true; 
    } 
} 

現在我只需從PopupMenu中獲取我需要的任何彈出窗口的類。結果是完美的。

解決此問題的方法可能更簡單,但如果不在菜單欄上放置彈出式菜單項,我無法找到它。

+0

此代碼是否適用於彈出窗口中的任何菜單項?我無法爲彈出窗口上的每個選項管理突出顯示事件。 – jgsogo 2013-05-27 16:36:57

+0

據我所知,它應該。儘管如此,舊版本的wxWidgets可能已經改變了現有的版本。 – 2013-05-28 02:45:27

+0

使用wxWidgets 3.0.2,沒有任何PopupMenu方法因爲某種原因運行... – 2017-02-03 09:22:59

0

頭野人的解決方案並沒有爲我工作wxWidgets的3.0.2,但我發現一個不同:使用Bind臨時寄存器包含點擊器上的一個wxFramewxEVT_MENU_HIGHLIGHT事件處理程序。完整示例:

class FunctionMenuWindow : public wxWindow 
{ 
public: 
    int option; 

    FunctionMenuWindow(wxWindow *parent) : wxWindow(parent, -1), option(0), mPushed(false) 
    { 
     this  ->Bind(wxEVT_MENU   , &FunctionMenuWindow::OnMenu  , this, wxID_ANY); 
     theMainWin->Bind(wxEVT_MENU_OPEN  , &FunctionMenuWindow::OnOpen  , this, wxID_ANY); 
     theMainWin->Bind(wxEVT_MENU_CLOSE , &FunctionMenuWindow::OnClose , this, wxID_ANY); 
     theMainWin->Bind(wxEVT_MENU_HIGHLIGHT, &FunctionMenuWindow::OnHighlight, this, wxID_ANY); 
    } 

    ~FunctionMenuWindow() 
    { 
     theMainWin->Unbind(wxEVT_MENU_OPEN  , &FunctionMenuWindow::OnOpen  , this, wxID_ANY); 
     theMainWin->Unbind(wxEVT_MENU_CLOSE , &FunctionMenuWindow::OnClose , this, wxID_ANY); 
     theMainWin->Unbind(wxEVT_MENU_HIGHLIGHT, &FunctionMenuWindow::OnHighlight, this, wxID_ANY); 
    } 

private: 
    void OnMenu(wxCommandEvent& event) 
    { 
     option = event.GetId(); 
    } 

    void OnOpen(wxMenuEvent &evt) 
    { 
     this->mMenu = evt.GetMenu(); 
     if (!mPushed) 
     { 
      theMainWin->GetStatusBar()->PushStatusText(wxString()); 
      mPushed = true; 
     } 
    } 

    void OnClose(wxMenuEvent &evt) 
    { 
     if (mPushed) 
     { 
      theMainWin->GetStatusBar()->PopStatusText(); 
      mPushed = false; 
     } 
    } 

    const wxString GetHelpString(wxMenuEvent &evt) 
    { 
     if (evt.GetMenuId() < 0) 
      return wxString(); 
     else 
      return mMenu->GetHelpString(evt.GetMenuId()); 
    } 

    void OnHighlight(wxMenuEvent &evt) 
    { 
     if (mPushed) 
      theMainWin->GetStatusBar()->SetStatusText(GetHelpString(evt)); 
     else 
     { 
      theMainWin->GetStatusBar()->PushStatusText(GetHelpString(evt)); 
      mPushed = true; 
     } 
    } 

    bool mPushed; 
    wxMenu* mMenu; 
}; 

/////////////////////////////////////////////////////////////////// 

void ShowMenu() 
{ 
    FunctionMenuWindow funcWindow(theMainWin); 
    wxMenu *menu = new wxMenu; 

    // ... set up wxMenu ... 

    funcWindow.PopupMenu(menu); 

    switch(funcWindow.option) 
    { 
     // ... switch by wxID as usual ... 
    } 
}