]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/menucmn.cpp
Avoid crash when releasing the mouse in wxRibbonToolBar.
[wxWidgets.git] / src / common / menucmn.cpp
index 0d2d14bf0a78319505430224923e0a72e6ab13e3..4c7abae78dbeedb04f4e4ad023d705f2a0dc13f0 100644 (file)
@@ -30,6 +30,7 @@
     #include "wx/intl.h"
     #include "wx/log.h"
     #include "wx/menu.h"
+    #include "wx/frame.h"
 #endif
 
 #include "wx/stockitem.h"
@@ -58,6 +59,39 @@ wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu,
                                wxItemKind kind,
                                wxMenu *subMenu)
 {
+    switch ( id )
+    {
+        case wxID_ANY:
+            m_id = wxWindow::NewControlId();
+            break;
+
+        case wxID_SEPARATOR:
+            m_id = wxID_SEPARATOR;
+
+            // there is a lot of existing code just doing Append(wxID_SEPARATOR)
+            // and it makes sense to omit the following optional parameters,
+            // including the kind one which doesn't default to wxITEM_SEPARATOR,
+            // of course, so override it here
+            kind = wxITEM_SEPARATOR;
+            break;
+
+        case wxID_NONE:
+            // (popup) menu titles in wxMSW use this ID to indicate that
+            // it's not a real menu item, so we don't want the check below to
+            // apply to it
+            m_id = id;
+            break;
+
+        default:
+            // ids are limited to 16 bits under MSW so portable code shouldn't
+            // use ids outside of this range (negative ids generated by wx are
+            // fine though)
+            wxASSERT_MSG( (id >= 0 && id < SHRT_MAX) ||
+                            (id >= wxID_AUTO_LOWEST && id <= wxID_AUTO_HIGHEST),
+                          wxS("invalid id value") );
+            m_id = id;
+    }
+
     // notice that parentMenu can be NULL: the item can be attached to the menu
     // later with SetMenu()
 
@@ -65,12 +99,7 @@ wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu,
     m_subMenu     = subMenu;
     m_isEnabled   = true;
     m_isChecked   = false;
-    m_id          = id;
     m_kind        = kind;
-    if (m_id == wxID_ANY)
-        m_id = wxWindow::NewControlId();
-    if (m_id == wxID_SEPARATOR)
-        m_kind = wxITEM_SEPARATOR;
 
     SetItemLabel(text);
     SetHelp(help);
@@ -513,23 +542,18 @@ void wxMenuBase::SetInvokingWindow(wxWindow *win)
     m_invokingWindow = win;
 }
 
-wxWindow *wxMenuBase::GetInvokingWindow() const
+wxWindow *wxMenuBase::GetWindow() const
 {
-    // only the popup menu itself has a non-NULL invoking window so recurse
-    // upwards until we find it
+    // only the top level menus have non-NULL invoking window or a pointer to
+    // the menu bar so recurse upwards until we find it
     const wxMenuBase *menu = this;
     while ( menu->GetParent() )
     {
         menu = menu->GetParent();
     }
 
-    // menu is a top level menu here
-    return menu->m_invokingWindow;
-}
-
-wxWindow *wxMenuBase::GetWindow() const
-{
-    return GetMenuBar() ? GetMenuBar()->GetFrame() : GetInvokingWindow();
+    return menu->GetMenuBar() ? menu->GetMenuBar()->GetFrame()
+                              : menu->GetInvokingWindow();
 }
 
 // ----------------------------------------------------------------------------