wxMenuToolBar allows you to create easy pop-up menus inside of your tool-bar. In addition, it provides a simple pop-up menu button which you can use anywhere (like in a panel, dialog box, etc.). It has been tested on both Microsoft-Windows (MSW) and Mac OS/X (MAC) and it works, and looks great.
Macintosh Download: MTBSample.dmg.gz
What's provided in the download:

The sample program running on MS-Windows

The sample program running on Mac OS/X
wxMenuToolBar contains the following methods:
wxMenuToolBar(wxFrame* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTB_HORIZONTAL | wxNO_BORDER, const wxString& name = wxPanelNameStr);wxMenuToolBar constructor. Constructs the entire tool-bar.void AddMenuButtonTool(int toolId, const wxString& label, const wxBitmap& bitmap1, const wxString& shortHelpString = "");Adds a toolbar button which pops-up a menu. You choose the graphics for the toolbar button. On Windows, the toolbar button behaves exactly like any other toolbar button (i.e. when you mouse over it, tool tips, etc.). On Macintosh, unfortunately, Menu Button Tools do not provide tool-tips.wxMenuButton *AddMenuPulldownTool(int toolId, const wxString& label, const wxString& shortHelpString = "");Adds a special pulldown button which pops-up a menu. The button displays as a small black triangle on the toolbar. This button is typically used with some other button to it's left (like the forward/backward buttons in Firefox).
In addition, wxMenuButton contains the following constructor routines:
wxMenuButton(wxToolBar *toolBar, int ID); wxMenuButton(wxWindow *window, int ID); void Create(wxToolBar *toolBar, int ID); void Create(wxWindow *window, int ID);wxMenuButton constructors. It positions the menu slightly differently depending on whether it is a child of a toolbar, or some other menu. Use the Create() routines for two phase button creation.
Specifically, include an EVT_COMMAND() in your event table, like this:
EVT_COMMAND(MY_BUTTON_ID, wxEVT_FILL_MENU, MyClass::MyFillRoutine)
Your resulting MyClass::MyFillRoutine() should look something like this:
void MyClass::MyFillRoutine(wxCommandEvent& event) {
wxMenu *menu = (wxMenu *)event.GetClientData();
if(menu->GetMenuItemCount() <= 0) {
menu->Append(MY_ID1, wxT("My Menu Item 1"));
menu->AppendSeparator();
menu->Append(MY_ID2, wxT("My Menu Item 2"));
// etc.
}
}
The following is a more comprehensive example:
// *** Declaring the events
//
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
// wxEVT_FILL_MENU will be transmitted whenever the menu is going to be displayed.
// This gives you the opportunity to fill the menu with entries, or to change the entries.
EVT_COMMAND (mtbID_NEW, wxEVT_FILL_MENU, MyFrame::FillNewMenu)
// Once the user choose a menu item, it will fire an EVT_MENU event with the
// id if the menu item you provided when you filled up the menu
EVT_MENU (mtbID_NEW_ITEM, MyFrame::ProcessNewItem)
END_EVENT_TABLE()
// Example routine for filling up the menu
void MyFrame::FillNewMenu(wxCommandEvent& event)
{
// The menu pointer is transmitted as part of the event's ClientData
wxMenu *menu = (wxMenu *)event.GetClientData();
if(menu->GetMenuItemCount() <= 0) {
menu->Append(mtbID_NEW_ITEM, wxT("New Item 1"));
menu->AppendSeparator();
menu->Append(mtbID_DUMMY, wxT("New Item 2"));
menu->Append(mtbID_DUMMY, wxT("New Item 3"));
menu->Append(mtbID_DUMMY, wxT("New Item 4"));
}
}
// Processing selected menu items occurs just like handling any other menu
void MyFrame::ProcessNewItem(wxCommandEvent& event)
{
wxMessageBox(wxT("Process New Item 1"), _T("Process New Item 1"), wxOK | wxICON_INFORMATION, this);
}
|
Fortunately, with a minor change in the wxWidgets source code, you can fix this. You will need to make the change and then recompile the wxWidgets libraries.
The change needs to be made to src\msw\window.cpp, as follows:
bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y) { . . . #if defined(__WXWINCE__) UINT flags = 0; #else UINT flags = TPM_RIGHTBUTTON; flags = TPM_LEFTBUTTON; // <<< ADD THIS LINE #endif ::TrackPopupMenu(hMenu, flags , point.x, point.y, 0, hWnd, NULL);
And that's it. Simple, no? Trust me, you'll be more than happy with the change.
Click here to contact Paul (please do).