disable UI updating during GetPopupMenuSelectionFromUser() execution to avoid unexpected clashes between the ids used in it and the update UI handlers elsewhere in the program

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57355 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2008-12-15 11:02:49 +00:00
parent fe79f76ba9
commit 565382de29
3 changed files with 43 additions and 14 deletions

View File

@ -1651,8 +1651,9 @@ private:
void NotifyWindowOnEnableChange(bool enabled); void NotifyWindowOnEnableChange(bool enabled);
#if wxUSE_MENUS #if wxUSE_MENUS
// temporary event handler used by GetPopupMenuSelectionFromUser() // temporary event handlers used by GetPopupMenuSelectionFromUser()
void InternalOnPopupMenu(wxCommandEvent& event); void InternalOnPopupMenu(wxCommandEvent& event);
void InternalOnPopupMenuUpdate(wxUpdateUIEvent& event);
// implementation of the public GetPopupMenuSelectionFromUser() method // implementation of the public GetPopupMenuSelectionFromUser() method
int DoGetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y); int DoGetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y);

View File

@ -1060,28 +1060,35 @@ public:
*/ */
wxWindow* GetParent() const; wxWindow* GetParent() const;
//@{
/** /**
This function shows a popup menu at the given position in this window and This function shows a popup menu at the given position in this window and
returns the selected id. It can be more convenient than the general purpose returns the selected id.
PopupMenu() function for simple menus proposing a choice in a list of
strings to the user. It can be more convenient than the general purpose PopupMenu() function
for simple menus proposing a choice in a list of strings to the user.
Notice that to avoid unexpected conflicts between the (usually
consecutive range of) ids used by the menu passed to this function and
the existing EVT_UPDATE_UI() handlers, this function temporarily
disables UI updates for the window, so you need to manually disable
(or toggle or ...) any items which should be disabled in the menu
before showing it.
@param menu @param menu
The menu to show The menu to show.
@param pos @param pos
The position at which to show the menu in client coordinates The position at which to show the menu in client coordinates.
@return The selected menu item id or wxID_NONE if none selected or an @return
error occurred. The selected menu item id or @c wxID_NONE if none selected or an
error occurred.
@since 2.9.0
*/ */
int GetPopupMenuSelectionFromUser(wxMenu& menu, const wxPoint& pos); int GetPopupMenuSelectionFromUser(wxMenu& menu, const wxPoint& pos);
/**
See the GetPopupMenuSelectionFromUser(wxMenu&, const wxPoint&) overload.
This overload differs only because it takes two integers for the
menu position instead of a wxPoint.
*/
int GetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y); int GetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y);
//@}
/** /**
This gets the position of the window in pixels, relative to the parent window This gets the position of the window in pixels, relative to the parent window

View File

@ -2407,6 +2407,11 @@ void wxWindowBase::InternalOnPopupMenu(wxCommandEvent& event)
gs_popupMenuSelection = event.GetId(); gs_popupMenuSelection = event.GetId();
} }
void wxWindowBase::InternalOnPopupMenuUpdate(wxUpdateUIEvent& WXUNUSED(event))
{
// nothing to do but do not skip it
}
int int
wxWindowBase::DoGetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y) wxWindowBase::DoGetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y)
{ {
@ -2417,8 +2422,24 @@ wxWindowBase::DoGetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y)
NULL, NULL,
this); this);
// it is common to construct the menu passed to this function dynamically
// using some fixed range of ids which could clash with the ids used
// elsewhere in the program, which could result in some menu items being
// unintentionally disabled or otherwise modified by update UI handlers
// elsewhere in the program code and this is difficult to avoid in the
// program itself, so instead we just temporarily suspend UI updating while
// this menu is shown
Connect(wxEVT_UPDATE_UI,
wxUpdateUIEventHandler(wxWindowBase::InternalOnPopupMenuUpdate),
NULL,
this);
PopupMenu(&menu, x, y); PopupMenu(&menu, x, y);
Disconnect(wxEVT_UPDATE_UI,
wxUpdateUIEventHandler(wxWindowBase::InternalOnPopupMenuUpdate),
NULL,
this);
Disconnect(wxEVT_COMMAND_MENU_SELECTED, Disconnect(wxEVT_COMMAND_MENU_SELECTED,
wxCommandEventHandler(wxWindowBase::InternalOnPopupMenu), wxCommandEventHandler(wxWindowBase::InternalOnPopupMenu),
NULL, NULL,