From d65c269b3f665e15a8ae1b8fff063b2ec0ef19a7 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Mon, 18 Mar 2002 19:41:35 +0000
Subject: [PATCH] 1. implemented radio menu items for wxGTK 2. changed (in most
 cases blindly) code for all the others 3. added wx/features.h 4. update
 wxMenu[Item] docs

----------------------------------------------------------------------
Committing in .

Modified Files:
	distrib/msw/tmake/filelist.txt docs/changes.txt
	docs/latex/wx/menu.tex docs/latex/wx/menuitem.tex
	include/wx/defs.h include/wx/menu.h include/wx/menuitem.h
	include/wx/gtk/menu.h include/wx/gtk/menuitem.h
	include/wx/mac/menuitem.h include/wx/motif/menuitem.h
	include/wx/msw/menuitem.h include/wx/os2/MENUITEM.H
	include/wx/univ/menuitem.h samples/menu/menu.cpp
	src/common/menucmn.cpp src/gtk/menu.cpp src/mac/menuitem.cpp
	src/motif/menuitem.cpp src/msw/menuitem.cpp
	src/os2/MENUITEM.CPP src/univ/menu.cpp
Added Files:
	include/wx/features.h
----------------------------------------------------------------------


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14674 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 distrib/msw/tmake/filelist.txt |   1 +
 docs/changes.txt               |   1 +
 docs/latex/wx/menu.tex         | 131 ++++++++++++++++++++++++++++++++-
 docs/latex/wx/menuitem.tex     |  21 ++++--
 include/wx/defs.h              |  13 ++++
 include/wx/features.h          |  24 ++++++
 include/wx/gtk/menu.h          |   4 +
 include/wx/gtk/menuitem.h      |   2 +-
 include/wx/gtk1/menu.h         |   4 +
 include/wx/gtk1/menuitem.h     |   2 +-
 include/wx/mac/menuitem.h      |   2 +-
 include/wx/menu.h              | 127 ++++++++++++++++++++++++++------
 include/wx/menuitem.h          |  30 ++++++--
 include/wx/motif/menuitem.h    |  10 +--
 include/wx/msw/menuitem.h      |   2 +-
 include/wx/os2/menuitem.h      |   2 +-
 include/wx/univ/menuitem.h     |   2 +-
 samples/menu/menu.cpp          |  45 ++++++++++-
 src/common/menucmn.cpp         |  19 +++++
 src/gtk/menu.cpp               |  73 ++++++++++++++----
 src/gtk1/menu.cpp              |  73 ++++++++++++++----
 src/mac/carbon/menuitem.cpp    |  26 +++----
 src/mac/menuitem.cpp           |  26 +++----
 src/motif/menuitem.cpp         |  27 +++----
 src/msw/menuitem.cpp           |  20 ++---
 src/os2/menuitem.cpp           |  19 ++---
 src/univ/menu.cpp              |  16 +---
 27 files changed, 551 insertions(+), 171 deletions(-)
 create mode 100644 include/wx/features.h

diff --git a/distrib/msw/tmake/filelist.txt b/distrib/msw/tmake/filelist.txt
index 0138b3af38..b92fbd87b9 100644
--- a/distrib/msw/tmake/filelist.txt
+++ b/distrib/msw/tmake/filelist.txt
@@ -807,6 +807,7 @@ encconv.h	WXH	Base
 event.h	WXH	Base
 expr.h	WXH
 fdrepdlg.h	WXH
+features.h	WXH	Base
 ffile.h	WXH	Base
 file.h	WXH	Base
 fileconf.h	WXH	Base
diff --git a/docs/changes.txt b/docs/changes.txt
index 9c684d2142..5e431cf5fc 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -107,6 +107,7 @@ Unix (Base/GUI):
 
 All (GUI):
 
+- implemented radio menu items
 - significantly improved native font support
 - wxImage::ComputeHistogram() now uses wxImageHistogram instead of type-unsafe
   wxHashTable
diff --git a/docs/latex/wx/menu.tex b/docs/latex/wx/menu.tex
index fa1bf18c49..e53ab4519e 100644
--- a/docs/latex/wx/menu.tex
+++ b/docs/latex/wx/menu.tex
@@ -77,7 +77,7 @@ and recreation of internal data structures.
 \membersection{wxMenu::Append}\label{wxmenuappend}
 
 \func{void}{Append}{\param{int}{ id}, \param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""},\rtfsp
-\param{const bool}{ checkable = FALSE}}
+\param{wxItemKind}{ kind = wxItem\_Normal}}
 
 Adds a string item to the end of the menu.
 
@@ -101,7 +101,8 @@ such as bitmaps and fonts.
 
 \docparam{menu}{Pull-right submenu.}
 
-\docparam{checkable}{If TRUE, this item is checkable.}
+\docparam{kind}{May be {\tt wxItem\_Separator}, {\tt wxItem\_Normal}, 
+{\tt wxItem\_Check} or {\tt wxItem\_Radio}}
 
 \docparam{helpString}{An optional help string associated with the item.
 By default, \helpref{wxFrame::OnMenuHighlight}{wxframeonmenuhighlight} displays
@@ -118,6 +119,8 @@ creation of a menu or menubar.
 \wxheading{See also}
 
 \helpref{wxMenu::AppendSeparator}{wxmenuappendseparator},\rtfsp
+\helpref{wxMenu::AppendCheckItem}{wxmenuappendcheckitem},\rtfsp
+\helpref{wxMenu::AppendRadioItem}{wxmenuappendradioitem},\rtfsp
 \helpref{wxMenu::Insert}{wxmenuinsert},\rtfsp
 \helpref{wxMenu::SetLabel}{wxmenusetlabel}, \helpref{wxMenu::GetHelpString}{wxmenugethelpstring},\rtfsp
 \helpref{wxMenu::SetHelpString}{wxmenusethelpstring}, \helpref{wxMenuItem}{wxmenuitem}
@@ -131,6 +134,35 @@ implements the following methods:\par
 \end{twocollist}}
 }
 
+\membersection{wxMenu::AppendCheckItem}\label{wxmenuappendcheckitem}
+
+\func{void}{AppendCheckItem}{\param{int}{ id},\rtfsp
+\param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""}}
+
+Adds a checkable item to the end of the menu.
+
+\wxheading{See also}
+
+\helpref{wxMenu::Append}{wxmenuappend},\rtfsp
+\helpref{wxMenu::InsertCheckItem}{wxmenuinsertcheckitem}
+
+\membersection{wxMenu::AppendRadioItem}\label{wxmenuappendradioitem}
+
+\func{void}{AppendRadioItem}{\param{int}{ id},\rtfsp
+\param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""}}
+
+Adds a radio item to the end of the menu. All consequent radio items form a
+group and when an item in the group is checked, all the others are
+automatically unchecked.
+
+{\bf NB:} Currently only implemented under Windows and GTK, use
+{\tt #if wxHAS\_RADIO\_MENU\_ITEMS} to test for availability of this feature.
+
+\wxheading{See also}
+
+\helpref{wxMenu::Append}{wxmenuappend},\rtfsp
+\helpref{wxMenu::InsertRadioItem}{wxmenuinsertradioitem}
+
 \membersection{wxMenu::AppendSeparator}\label{wxmenuappendseparator}
 
 \func{void}{AppendSeparator}{\void}
@@ -139,7 +171,8 @@ Adds a separator to the end of the menu.
 
 \wxheading{See also}
 
-\helpref{wxMenu::Append}{wxmenuappend}
+\helpref{wxMenu::Append}{wxmenuappend},\rtfsp
+\helpref{wxMenu::InsertSeparator}{wxmenuinsertseparator}
 
 \membersection{wxMenu::Break}\label{wxmenubreak}
 
@@ -329,13 +362,53 @@ This is relevant only to popup menus.
 
 \func{bool}{Insert}{\param{size\_t }{pos}, \param{wxMenuItem *}{item}}
 
+\func{void}{Insert}{\param{size\_t }{pos}, \param{int}{ id},\rtfsp
+\param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""},\rtfsp
+\param{wxItemKind}{ kind = wxItem\_Normal}}
+
 Inserts the given {\it item} before the position {\it pos}. Inserting the item
 at the position \helpref{GetMenuItemCount}{wxmenugetmenuitemcount} is the same
 as appending it.
 
 \wxheading{See also}
 
-\helpref{wxMenu::Append}{wxmenuappend}
+\helpref{wxMenu::Append}{wxmenuappend},\rtfsp
+\helpref{wxMenu::Prepend}{wxmenuprepend}
+
+\membersection{wxMenu::InsertCheckItem}\label{wxmenuinsertcheckitem}
+
+\func{void}{InsertCheckItem}{\param{size\_t }{pos}, \param{int}{ id},\rtfsp
+\param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""}}
+
+Inserts a checkable item at the given position.
+
+\wxheading{See also}
+
+\helpref{wxMenu::Insert}{wxmenuinsert},\rtfsp
+\helpref{wxMenu::AppendCheckItem}{wxmenuappendcheckitem}
+
+\membersection{wxMenu::InsertRadioItem}\label{wxmenuinsertradioitem}
+
+\func{void}{InsertRadioItem}{\param{size\_t }{pos}, \param{int}{ id},\rtfsp
+\param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""}}
+
+Inserts a radio item at the given position.
+
+\wxheading{See also}
+
+\helpref{wxMenu::Insert}{wxmenuinsert},\rtfsp
+\helpref{wxMenu::AppendRadioItem}{wxmenuappendradioitem}
+
+\membersection{wxMenu::InsertSeparator}\label{wxmenuinsertseparator}
+
+\func{void}{InsertSeparator}{\param{size\_t }{pos}}
+
+Inserts a separator at the given position.
+
+\wxheading{See also}
+
+\helpref{wxMenu::Insert}{wxmenuinsert},\rtfsp
+\helpref{wxMenu::AppendSeparator}{wxmenuappendseparator}
 
 \membersection{wxMenu::IsChecked}\label{wxmenuischecked}
 
@@ -373,6 +446,56 @@ TRUE if the menu item is enabled, FALSE otherwise.
 
 \helpref{wxMenu::Enable}{wxmenuenable}
 
+\membersection{wxMenu::Prepend}\label{wxmenuprepend}
+
+\func{bool}{Prepend}{\param{size\_t }{pos}, \param{wxMenuItem *}{item}}
+
+\func{void}{Prepend}{\param{int}{ id},\rtfsp
+\param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""},\rtfsp
+\param{wxItemKind}{ kind = wxItem\_Normal}}
+
+Inserts the given {\it item} at the position $0$.
+
+\wxheading{See also}
+
+\helpref{wxMenu::Append}{wxmenuappend},\rtfsp
+\helpref{wxMenu::Inserts}{wxmenuinsert}
+
+\membersection{wxMenu::PrependCheckItem}\label{wxmenuprependcheckitem}
+
+\func{void}{PrependCheckItem}{\param{int}{ id},\rtfsp
+\param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""}}
+
+Inserts a checkable item at the position $0$.
+
+\wxheading{See also}
+
+\helpref{wxMenu::Prepend}{wxmenuprepend},\rtfsp
+\helpref{wxMenu::AppendCheckItem}{wxmenuappendcheckitem}
+
+\membersection{wxMenu::PrependRadioItem}\label{wxmenuprependradioitem}
+
+\func{void}{PrependRadioItem}{\param{int}{ id},\rtfsp
+\param{const wxString\& }{ item}, \param{const wxString\& }{helpString = ""}}
+
+Inserts a radio item at the position $0$.
+
+\wxheading{See also}
+
+\helpref{wxMenu::Prepend}{wxmenuprepend},\rtfsp
+\helpref{wxMenu::AppendRadioItem}{wxmenuappendradioitem}
+
+\membersection{wxMenu::PrependSeparator}\label{wxmenuprependseparator}
+
+\func{void}{PrependSeparator}{\param{size\_t }{pos}}
+
+Inserts a separator at the position $0$.
+
+\wxheading{See also}
+
+\helpref{wxMenu::Prepend}{wxmenuprepend},\rtfsp
+\helpref{wxMenu::AppendSeparator}{wxmenuappendseparator}
+
 \membersection{wxMenu::Remove}\label{wxmenuremove}
 
 \func{wxMenuItem *}{Remove}{\param{int }{id}}
diff --git a/docs/latex/wx/menuitem.tex b/docs/latex/wx/menuitem.tex
index f9f49bb8ae..f59dbd68f8 100644
--- a/docs/latex/wx/menuitem.tex
+++ b/docs/latex/wx/menuitem.tex
@@ -1,8 +1,11 @@
 \section{\class{wxMenuItem}}\label{wxmenuitem}
 
-A menu item represents an item in a popup menu. Note that the majority of this
-class is only implemented under Windows so far, but everything except fonts, colours and
-bitmaps can be achieved via wxMenu on all platforms.
+A menu item represents an item in a menu. Note that you usually don't have to
+deal with it directly as \helpref{wxMenu}{wxmenu} methods usually construct an
+object of this class for you.
+
+Also please note that the methods related to fonts and bitmaps are currently
+only implemented for Windows.
 
 \wxheading{Derived from}
 
@@ -23,7 +26,7 @@ wxOwnerDrawn (Windows only)\\
 
 \func{}{wxMenuItem}{\param{wxMenu*}{ parentMenu = NULL}, \param{int}{ id = ID\_SEPARATOR},
  \param{const wxString\& }{text = ""},  \param{const wxString\& }{helpString = ""},
- \param{bool }{checkable = FALSE}, \param{wxMenu*}{ subMenu = NULL}, }
+ \param{wxItemKind }{kind = wxItem\_Normal}, \param{wxMenu*}{ subMenu = NULL}, }
 
 Constructs a wxMenuItem object.
 
@@ -37,7 +40,8 @@ Constructs a wxMenuItem object.
 
 \docparam{helpString}{Optional help string that will be shown on the status bar.}
 
-\docparam{checkable}{TRUE if this menu item is checkable.}
+\docparam{kind}{May be {\tt wxItem\_Separator}, {\tt wxItem\_Normal}, 
+{\tt wxItem\_Check} or {\tt wxItem\_Radio}}
 
 \docparam{subMenu}{If non-NULL, indicates that the menu item is a submenu.}
 
@@ -95,6 +99,13 @@ Returns the help string associated with the menu item.
 
 Returns the menu item identifier.
 
+\membersection{wxMenuItem::GetKind}\label{wxmenuitemgetkind}
+
+\constfunc{wxItemKind}{GetKind}{\void}
+
+Returns the item kind, one of {\tt wxItem\_Separator}, {\tt wxItem\_Normal}, 
+{\tt wxItem\_Check} or {\tt wxItem\_Radio}.
+
 \membersection{wxMenuItem::GetLabel}\label{wxmenuitemgetlabel}
 
 \constfunc{wxString}{GetLabel}{\void}
diff --git a/include/wx/defs.h b/include/wx/defs.h
index 910fa95d84..29d83cd4bb 100644
--- a/include/wx/defs.h
+++ b/include/wx/defs.h
@@ -35,6 +35,9 @@
 #endif // Unix/!Unix
 #endif
 
+// include the feature test macros
+#include "wx/features.h"
+
 // suppress some Visual C++ warnings
 #ifdef __VISUALC__
 #   pragma warning(disable:4201)    // nonstandard extension used: nameless struct/union
@@ -1276,6 +1279,16 @@ enum wxBorder
 // constants
 // ----------------------------------------------------------------------------
 
+// menu and toolbar item kinds
+enum wxItemKind
+{
+    wxItem_Separator = -1,
+    wxItem_Normal,
+    wxItem_Check,
+    wxItem_Radio,
+    wxItem_Max
+};
+
 // hit test results
 enum wxHitTest
 {
diff --git a/include/wx/features.h b/include/wx/features.h
new file mode 100644
index 0000000000..096497184d
--- /dev/null
+++ b/include/wx/features.h
@@ -0,0 +1,24 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx/features.h
+// Purpose:     test macros for the features which might be available in some
+//              wxWindows ports but not others
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     18.03.02
+// RCS-ID:      $Id$
+// Copyright:   (c) 2002 Vadim Zeitlin <vadim@wxwindows.org>
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_FEATURES_H_
+#define _WX_FEATURES_H_
+
+// radio menu items are currently only implemented in wxGTK
+#if defined(__WXGTK__) // || defined(__WXMSW__)
+    #define wxHAS_RADIO_MENU_ITEMS
+#else
+    #undef wxHAS_RADIO_MENU_ITEMS
+#endif
+
+#endif // _WX_FEATURES_H_
+
diff --git a/include/wx/gtk/menu.h b/include/wx/gtk/menu.h
index f36c816d2a..ee22d137b9 100644
--- a/include/wx/gtk/menu.h
+++ b/include/wx/gtk/menu.h
@@ -107,6 +107,10 @@ private:
     // common part of Append and Insert
     bool GtkAppend(wxMenuItem *item);
 
+    // if the last menu item was a radio one, this field contains its path,
+    // otherwise it is empty
+    wxString m_pathLastRadio;
+
     DECLARE_DYNAMIC_CLASS(wxMenu)
 };
 
diff --git a/include/wx/gtk/menuitem.h b/include/wx/gtk/menuitem.h
index 2a10795fb9..6a2ed681ae 100644
--- a/include/wx/gtk/menuitem.h
+++ b/include/wx/gtk/menuitem.h
@@ -27,7 +27,7 @@ public:
                int id = wxID_SEPARATOR,
                const wxString& text = wxEmptyString,
                const wxString& help = wxEmptyString,
-               bool isCheckable = FALSE,
+               wxItemKind kind = wxItem_Normal,
                wxMenu *subMenu = (wxMenu *)NULL);
     ~wxMenuItem();
 
diff --git a/include/wx/gtk1/menu.h b/include/wx/gtk1/menu.h
index f36c816d2a..ee22d137b9 100644
--- a/include/wx/gtk1/menu.h
+++ b/include/wx/gtk1/menu.h
@@ -107,6 +107,10 @@ private:
     // common part of Append and Insert
     bool GtkAppend(wxMenuItem *item);
 
+    // if the last menu item was a radio one, this field contains its path,
+    // otherwise it is empty
+    wxString m_pathLastRadio;
+
     DECLARE_DYNAMIC_CLASS(wxMenu)
 };
 
diff --git a/include/wx/gtk1/menuitem.h b/include/wx/gtk1/menuitem.h
index 2a10795fb9..6a2ed681ae 100644
--- a/include/wx/gtk1/menuitem.h
+++ b/include/wx/gtk1/menuitem.h
@@ -27,7 +27,7 @@ public:
                int id = wxID_SEPARATOR,
                const wxString& text = wxEmptyString,
                const wxString& help = wxEmptyString,
-               bool isCheckable = FALSE,
+               wxItemKind kind = wxItem_Normal,
                wxMenu *subMenu = (wxMenu *)NULL);
     ~wxMenuItem();
 
diff --git a/include/wx/mac/menuitem.h b/include/wx/mac/menuitem.h
index 6a35c72294..9011439e22 100644
--- a/include/wx/mac/menuitem.h
+++ b/include/wx/mac/menuitem.h
@@ -43,7 +43,7 @@ public:
                int id = wxID_SEPARATOR,
                const wxString& name = wxEmptyString,
                const wxString& help = wxEmptyString,
-               bool isCheckable = FALSE,
+               wxItemKind kind = wxItem_Normal,
                wxMenu *subMenu = (wxMenu *)NULL);
     virtual ~wxMenuItem();
 
diff --git a/include/wx/menu.h b/include/wx/menu.h
index 932d2ab152..b1b357c694 100644
--- a/include/wx/menu.h
+++ b/include/wx/menu.h
@@ -75,18 +75,34 @@ public:
     // menu construction
     // -----------------
 
-    // append a normal item to the menu
+    // append any kind of item (normal/check/radio/separator)
     void Append(int id,
                 const wxString& text,
                 const wxString& help = wxEmptyString,
-                bool isCheckable = FALSE)
+                wxItemKind kind = wxItem_Normal)
     {
-        DoAppend(wxMenuItem::New((wxMenu *)this, id, text, help, isCheckable));
+        DoAppend(wxMenuItem::New((wxMenu *)this, id, text, help, kind));
     }
 
     // append a separator to the menu
     void AppendSeparator() { Append(wxID_SEPARATOR, wxEmptyString); }
 
+    // append a check item
+    void AppendCheckItem(int id,
+                         const wxString& text,
+                         const wxString& help = wxEmptyString)
+    {
+        Append(id, text, help, wxItem_Check);
+    }
+
+    // append a radio item
+    void AppendRadioItem(int id,
+                         const wxString& text,
+                         const wxString& help = wxEmptyString)
+    {
+        Append(id, text, help, wxItem_Radio);
+    }
+
     // append a submenu
     void Append(int id,
                 const wxString& text,
@@ -105,13 +121,15 @@ public:
 
     // insert an item before given position
     bool Insert(size_t pos, wxMenuItem *item);
+
+    // insert an item before given position
     void Insert(size_t pos,
                 int id,
                 const wxString& text,
                 const wxString& help = wxEmptyString,
-                bool isCheckable = FALSE)
+                wxItemKind kind = wxItem_Normal)
     {
-        Insert(pos, wxMenuItem::New((wxMenu *)this, id, text, help, isCheckable));
+        Insert(pos, wxMenuItem::New((wxMenu *)this, id, text, help, kind));
     }
 
     // insert a separator
@@ -120,6 +138,24 @@ public:
         Insert(pos, wxMenuItem::New((wxMenu *)this));
     }
 
+    // insert a check item
+    void InsertCheckItem(size_t pos,
+                         int id,
+                         const wxString& text,
+                         const wxString& help = wxEmptyString)
+    {
+        Insert(pos, id, text, help, wxItem_Check);
+    }
+
+    // insert a radio item
+    void InsertRadioItem(size_t pos,
+                         int id,
+                         const wxString& text,
+                         const wxString& help = wxEmptyString)
+    {
+        Insert(pos, id, text, help, wxItem_Radio);
+    }
+
     // insert a submenu
     void Insert(size_t pos,
                 int id,
@@ -136,21 +172,38 @@ public:
         Insert(0u, item);
     }
 
+    // prepend any item to the menu
     void Prepend(int id,
                  const wxString& text,
                  const wxString& help = wxEmptyString,
-                 bool isCheckable = FALSE)
+                 wxItemKind kind = wxItem_Normal)
     {
-        Insert(0u, id, text, help, isCheckable);
+        Insert(0u, id, text, help, kind);
     }
 
-    // insert a separator
+    // prepend a separator
     void PrependSeparator()
     {
         InsertSeparator(0u);
     }
 
-    // insert a submenu
+    // prepend a check item
+    void PrependCheckItem(int id,
+                          const wxString& text,
+                          const wxString& help = wxEmptyString)
+    {
+        InsertCheckItem(0u, id, text, help);
+    }
+
+    // prepend a radio item
+    void PrependRadioItem(int id,
+                          const wxString& text,
+                          const wxString& help = wxEmptyString)
+    {
+        InsertRadioItem(0u, id, text, help);
+    }
+
+    // prepend a submenu
     void Prepend(int id,
                  const wxString& text,
                  wxMenu *submenu,
@@ -241,8 +294,51 @@ public:
     void SetParent(wxMenu *parent) { m_menuParent = parent; }
     wxMenu *GetParent() const { return m_menuParent; }
 
-#if WXWIN_COMPATIBILITY
+    // implementation only from now on
+    // -------------------------------
+
+    // unlike FindItem(), this function doesn't recurse but only looks through
+    // our direct children and also may return the index of the found child if
+    // pos != NULL
+    wxMenuItem *FindChildItem(int id, size_t *pos = NULL) const;
+
+    // called to generate a wxCommandEvent, return TRUE if it was processed,
+    // FALSE otherwise
+    //
+    // the checked parameter may have boolean value or -1 for uncheckable items
+    bool SendEvent(int id, int checked = -1);
+
     // compatibility: these functions are deprecated, use the new ones instead
+    // -----------------------------------------------------------------------
+
+    // use the versions taking wxItem_XXX now instead, they're more readable
+    // and allow adding the radio items as well
+    void Append(int id,
+                const wxString& text,
+                const wxString& help,
+                bool isCheckable)
+    {
+        Append(id, text, help, isCheckable ? wxItem_Check : wxItem_Normal);
+    }
+
+    void Insert(size_t pos,
+                int id,
+                const wxString& text,
+                const wxString& help,
+                bool isCheckable)
+    {
+        Insert(pos, id, text, help, isCheckable ? wxItem_Check : wxItem_Normal);
+    }
+
+    void Prepend(int id,
+                 const wxString& text,
+                 const wxString& help,
+                 bool isCheckable)
+    {
+        Insert(0u, id, text, help, isCheckable);
+    }
+
+#if WXWIN_COMPATIBILITY
     bool Enabled(int id) const { return IsEnabled(id); }
     bool Checked(int id) const { return IsChecked(id); }
 
@@ -260,17 +356,6 @@ public:
     wxFunction m_callback;
 #endif // wxUSE_MENU_CALLBACK
 
-    // unlike FindItem(), this function doesn't recurse but only looks through
-    // our direct children and also may return the index of the found child if
-    // pos != NULL
-    wxMenuItem *FindChildItem(int id, size_t *pos = NULL) const;
-
-    // called to generate a wxCommandEvent, return TRUE if it was processed,
-    // FALSE otherwise
-    //
-    // the checked parameter may have boolean value or -1 for uncheckable items
-    bool SendEvent(int id, int checked = -1);
-
 protected:
     // virtuals to override in derived classes
     // ---------------------------------------
diff --git a/include/wx/menuitem.h b/include/wx/menuitem.h
index 9a74c6e07e..dac0c55cf5 100644
--- a/include/wx/menuitem.h
+++ b/include/wx/menuitem.h
@@ -41,7 +41,7 @@ public:
                            int id = wxID_SEPARATOR,
                            const wxString& text = wxEmptyString,
                            const wxString& help = wxEmptyString,
-                           bool isCheckable = FALSE,
+                           wxItemKind kind = wxItem_Normal,
                            wxMenu *subMenu = (wxMenu *)NULL);
 
     // destruction: wxMenuItem will delete its submenu
@@ -69,8 +69,10 @@ public:
     static wxString GetLabelFromText(const wxString& text);
 
     // what kind of menu item we are
-    virtual void SetCheckable(bool checkable) { m_isCheckable = checkable; }
-    bool IsCheckable() const { return m_isCheckable; }
+    wxItemKind GetKind() const { return m_kind; }
+
+    virtual void SetCheckable(bool checkable) { m_kind = wxItem_Check; }
+    bool IsCheckable() const { return m_kind == wxItem_Check; }
 
     bool IsSubMenu() const { return m_subMenu != NULL; }
     void SetSubMenu(wxMenu *menu) { m_subMenu = menu; }
@@ -105,18 +107,34 @@ public:
     void SetName(const wxString& str) { SetText(str); }
     const wxString& GetName() const { return GetText(); }
 
+    static wxMenuItem *New(wxMenu *parentMenu,
+                           int id,
+                           const wxString& text,
+                           const wxString& help,
+                           bool isCheckable,
+                           wxMenu *subMenu = (wxMenu *)NULL)
+    {
+        return New(parentMenu, id, text, help,
+                   isCheckable ? wxItem_Check : wxItem_Normal, subMenu);
+    }
+
 protected:
     int           m_id;             // numeric id of the item >= 0 or -1
     wxMenu       *m_parentMenu,     // the menu we belong to
                  *m_subMenu;        // our sub menu or NULL
     wxString      m_text,           // label of the item
                   m_help;           // the help string for the item
-    bool          m_isCheckable;    // can be checked?
+    wxItemKind    m_kind;           // seperator/normal/check/radio item?
     bool          m_isChecked;      // is checked?
     bool          m_isEnabled;      // is enabled?
 
-    // some compilers need a default constructor here, do not remove
-    wxMenuItemBase() { }
+    // this ctor is for the derived classes only, we're never created directly
+    wxMenuItemBase(wxMenu *parentMenu = (wxMenu *)NULL,
+                   int id = wxID_SEPARATOR,
+                   const wxString& text = wxEmptyString,
+                   const wxString& help = wxEmptyString,
+                   wxItemKind kind = wxItem_Normal,
+                   wxMenu *subMenu = (wxMenu *)NULL);
 
 private:
     // and, if we have one ctor, compiler won't generate a default copy one, so
diff --git a/include/wx/motif/menuitem.h b/include/wx/motif/menuitem.h
index f6580cdad0..8a7ff97bc5 100644
--- a/include/wx/motif/menuitem.h
+++ b/include/wx/motif/menuitem.h
@@ -29,11 +29,11 @@ class wxMenuItem : public wxMenuItemBase
 public:
     // ctor & dtor
     wxMenuItem(wxMenu *parentMenu = (wxMenu *)NULL,
-        int id = wxID_SEPARATOR,
-        const wxString& text = wxEmptyString,
-        const wxString& help = wxEmptyString,
-        bool isCheckable = FALSE,
-        wxMenu *subMenu = (wxMenu *)NULL);
+               int id = wxID_SEPARATOR,
+               const wxString& text = wxEmptyString,
+               const wxString& help = wxEmptyString,
+               wxItemKind kind = wxItem_Normal,
+               wxMenu *subMenu = (wxMenu *)NULL);
     ~wxMenuItem();
     
     // accessors (some more are inherited from wxOwnerDrawn or are below)
diff --git a/include/wx/msw/menuitem.h b/include/wx/msw/menuitem.h
index c848d5840a..ee507f7399 100644
--- a/include/wx/msw/menuitem.h
+++ b/include/wx/msw/menuitem.h
@@ -39,7 +39,7 @@ public:
                int id = wxID_SEPARATOR,
                const wxString& name = wxEmptyString,
                const wxString& help = wxEmptyString,
-               bool isCheckable = FALSE,
+               wxItemKind kind = wxItem_Normal,
                wxMenu *subMenu = (wxMenu *)NULL);
     virtual ~wxMenuItem();
 
diff --git a/include/wx/os2/menuitem.h b/include/wx/os2/menuitem.h
index 33a41cef62..00ab94a4c1 100644
--- a/include/wx/os2/menuitem.h
+++ b/include/wx/os2/menuitem.h
@@ -47,7 +47,7 @@ public:
                ,int             nId = wxID_SEPARATOR
                ,const wxString& rStrName = ""
                ,const wxString& rWxHelp = ""
-               ,bool            bCheckable = FALSE
+               ,wxItemKind      kind = wxItem_Normal
                ,wxMenu*         pSubMenu = NULL
               );
     virtual ~wxMenuItem();
diff --git a/include/wx/univ/menuitem.h b/include/wx/univ/menuitem.h
index 784433f95f..ccbb528f98 100644
--- a/include/wx/univ/menuitem.h
+++ b/include/wx/univ/menuitem.h
@@ -28,7 +28,7 @@ public:
                int id = wxID_SEPARATOR,
                const wxString& name = wxEmptyString,
                const wxString& help = wxEmptyString,
-               bool isCheckable = FALSE,
+               wxItemKind kind = wxItem_Normal,
                wxMenu *subMenu = (wxMenu *)NULL);
     virtual ~wxMenuItem();
 
diff --git a/samples/menu/menu.cpp b/samples/menu/menu.cpp
index 942d2df319..bc87eebf62 100644
--- a/samples/menu/menu.cpp
+++ b/samples/menu/menu.cpp
@@ -88,6 +88,10 @@ protected:
     void OnGetLabelMenu(wxCommandEvent& event);
     void OnSetLabelMenu(wxCommandEvent& event);
 
+    void OnTestNormal(wxCommandEvent& event);
+    void OnTestCheck(wxCommandEvent& event);
+    void OnTestRadio(wxCommandEvent& event);
+
 #ifdef __WXMSW__
     void OnContextMenu(wxContextMenuEvent& event)
         { ShowContextMenu(ScreenToClient(event.GetPosition())); }
@@ -174,7 +178,13 @@ enum
     Menu_Menu_SetLabel,
     Menu_Menu_GetInfo,
 
-    Menu_Dummy_First = 400,
+    Menu_Test_Normal = 400,
+    Menu_Test_Check,
+    Menu_Test_Radio1,
+    Menu_Test_Radio2,
+    Menu_Test_Radio3,
+
+    Menu_Dummy_First = 500,
     Menu_Dummy_Second,
     Menu_Dummy_Third,
     Menu_Dummy_Fourth,
@@ -218,6 +228,12 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(Menu_Menu_SetLabel,  MyFrame::OnSetLabelMenuItem)
     EVT_MENU(Menu_Menu_GetInfo,   MyFrame::OnGetMenuItemInfo)
 
+    EVT_MENU(Menu_Test_Normal,    MyFrame::OnTestNormal)
+    EVT_MENU(Menu_Test_Check,     MyFrame::OnTestCheck)
+    EVT_MENU(Menu_Test_Radio1,    MyFrame::OnTestRadio)
+    EVT_MENU(Menu_Test_Radio2,    MyFrame::OnTestRadio)
+    EVT_MENU(Menu_Test_Radio3,    MyFrame::OnTestRadio)
+
     EVT_MENU_RANGE(Menu_Dummy_First, Menu_Dummy_Last, MyFrame::OnDummy)
 
     EVT_UPDATE_UI(Menu_Menu_Check, MyFrame::OnUpdateCheckMenuItemUI)
@@ -335,6 +351,15 @@ MyFrame::MyFrame()
     menuMenu->Append(Menu_Menu_GetInfo, "Get menu item in&fo\tAlt-F",
                      "Show the state of the last menu item");
 
+    wxMenu *testMenu = new wxMenu;
+    testMenu->Append(Menu_Test_Normal, "&Normal item");
+    testMenu->AppendSeparator();
+    testMenu->AppendCheckItem(Menu_Test_Check, "&Check item");
+    testMenu->AppendSeparator();
+    testMenu->AppendRadioItem(Menu_Test_Radio1, "Radio item &1");
+    testMenu->AppendRadioItem(Menu_Test_Radio2, "Radio item &2");
+    testMenu->AppendRadioItem(Menu_Test_Radio3, "Radio item &3");
+
     wxMenu *helpMenu = new wxMenu;
     helpMenu->Append(Menu_Help_About, "&About\tF1", "About menu sample");
 
@@ -343,6 +368,7 @@ MyFrame::MyFrame()
     menuBar->Append(fileMenu, "&File");
     menuBar->Append(menubarMenu, "Menu&bar");
     menuBar->Append(menuMenu, "&Menu");
+    menuBar->Append(testMenu, "&Test");
     menuBar->Append(helpMenu, "&Help");
 
     // these items should be initially checked
@@ -750,6 +776,23 @@ void MyFrame::ShowContextMenu(const wxPoint& pos)
 #endif // 0
 }
 
+void MyFrame::OnTestNormal(wxCommandEvent& event)
+{
+    wxLogMessage(_T("Normal item selected"));
+}
+
+void MyFrame::OnTestCheck(wxCommandEvent& event)
+{
+    wxLogMessage(_T("Check item %schecked"),
+                 event.IsChecked() ? _T("") : _T("un"));
+}
+
+void MyFrame::OnTestRadio(wxCommandEvent& event)
+{
+    wxLogMessage(_T("Radio item %d selected"),
+                 event.GetId() - Menu_Test_Radio1 + 1);
+}
+
 void MyFrame::LogMenuOpenOrClose(const wxMenuEvent& event, const wxChar *what)
 {
     wxLogStatus(this, _T("A %smenu has been %s."),
diff --git a/src/common/menucmn.cpp b/src/common/menucmn.cpp
index 1f2b9fcbb7..ee97f56614 100644
--- a/src/common/menucmn.cpp
+++ b/src/common/menucmn.cpp
@@ -55,6 +55,25 @@ WX_DEFINE_LIST(wxMenuItemList);
 // wxMenuItem
 // ----------------------------------------------------------------------------
 
+wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu,
+                               int id,
+                               const wxString& text,
+                               const wxString& help,
+                               wxItemKind kind,
+                               wxMenu *subMenu)
+              : m_text(text),
+                m_help(help)
+{
+    wxASSERT_MSG( parentMenu != NULL, wxT("menuitem should have a menu") );
+
+    m_parentMenu  = parentMenu;
+    m_subMenu     = subMenu;
+    m_isEnabled   = TRUE;
+    m_isChecked   = FALSE;
+    m_id          = id;
+    m_kind        = kind;
+}
+
 wxMenuItemBase::~wxMenuItemBase()
 {
     delete m_subMenu;
diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp
index c41035bbc6..901d40e156 100644
--- a/src/gtk/menu.cpp
+++ b/src/gtk/menu.cpp
@@ -699,27 +699,20 @@ wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
                                 int id,
                                 const wxString& name,
                                 const wxString& help,
-                                bool isCheckable,
+                                wxItemKind kind,
                                 wxMenu *subMenu)
 {
-    return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
+    return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
 }
 
 wxMenuItem::wxMenuItem(wxMenu *parentMenu,
                        int id,
                        const wxString& text,
                        const wxString& help,
-                       bool isCheckable,
+                       wxItemKind kind,
                        wxMenu *subMenu)
+          : wxMenuItemBase(parentMenu, id, text, help, kind, subMenu)
 {
-    m_id = id;
-    m_isCheckable = isCheckable;
-    m_isChecked = FALSE;
-    m_isEnabled = TRUE;
-    m_subMenu = subMenu;
-    m_parentMenu = parentMenu;
-    m_help = help;
-
     m_labelWidget = (GtkWidget *) NULL;
     m_menuItem = (GtkWidget *) NULL;
 
@@ -948,6 +941,11 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem)
     bool appended = FALSE;
 #endif
 
+#if GTK_CHECK_VERSION(1, 2, 0)
+    // is this a radio item?
+    bool isRadio = FALSE;
+#endif // GTK+ >= 1.2
+
     if ( mitem->IsSeparator() )
     {
 #if GTK_CHECK_VERSION(1, 2, 0)
@@ -1046,16 +1044,52 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem)
         /* local buffer in multibyte form */
         char buf[200];
         strcpy( buf, "/" );
-        strcat( buf, text.mb_str() );
+        strncat( buf, text.mb_str(), WXSIZEOF(buf) - 2 );
+        buf[WXSIZEOF(buf) - 1] = '\0';
 
         GtkItemFactoryEntry entry;
         entry.path = buf;
         entry.callback = (GtkItemFactoryCallback) gtk_menu_clicked_callback;
         entry.callback_action = 0;
-        if ( mitem->IsCheckable() )
-            entry.item_type = (char *)"<CheckItem>";
-        else
-            entry.item_type = (char *)"<Item>";
+
+        wxString pathRadio;
+        const char *item_type;
+        switch ( mitem->GetKind() )
+        {
+            case wxItem_Check:
+                item_type = "<CheckItem>";
+                break;
+
+            case wxItem_Radio:
+                if ( m_pathLastRadio.empty() )
+                {
+                    // start of a new radio group
+                    item_type = "<RadioItem>";
+                    m_pathLastRadio = buf + 1;
+                }
+                else // continue the radio group
+                {
+                    pathRadio = m_pathLastRadio;
+                    pathRadio.Replace("_", "");
+                    pathRadio.Prepend("<main>/");
+                    item_type = pathRadio;
+                }
+
+                // remember that this one was a radio item to avoid resetting
+                // m_pathLastRadio below
+                isRadio = TRUE;
+                break;
+
+            default:
+                wxFAIL_MSG( _T("unexpected menu item kind") );
+                // fall through
+
+            case wxItem_Normal:
+                item_type = "<Item>";
+                break;
+        }
+
+        entry.item_type = (char *)item_type; // cast needed for GTK+
         entry.accelerator = (gchar*) NULL;
 
 #if wxUSE_ACCEL
@@ -1105,6 +1139,13 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem)
 
     mitem->SetMenuItem(menuItem);
 
+#if GTK_CHECK_VERSION(1, 2, 0)
+    if ( !isRadio )
+    {
+        m_pathLastRadio.clear();
+    }
+#endif // GTK+ >= 1.2
+
     return TRUE;
 }
 
diff --git a/src/gtk1/menu.cpp b/src/gtk1/menu.cpp
index c41035bbc6..901d40e156 100644
--- a/src/gtk1/menu.cpp
+++ b/src/gtk1/menu.cpp
@@ -699,27 +699,20 @@ wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
                                 int id,
                                 const wxString& name,
                                 const wxString& help,
-                                bool isCheckable,
+                                wxItemKind kind,
                                 wxMenu *subMenu)
 {
-    return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
+    return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
 }
 
 wxMenuItem::wxMenuItem(wxMenu *parentMenu,
                        int id,
                        const wxString& text,
                        const wxString& help,
-                       bool isCheckable,
+                       wxItemKind kind,
                        wxMenu *subMenu)
+          : wxMenuItemBase(parentMenu, id, text, help, kind, subMenu)
 {
-    m_id = id;
-    m_isCheckable = isCheckable;
-    m_isChecked = FALSE;
-    m_isEnabled = TRUE;
-    m_subMenu = subMenu;
-    m_parentMenu = parentMenu;
-    m_help = help;
-
     m_labelWidget = (GtkWidget *) NULL;
     m_menuItem = (GtkWidget *) NULL;
 
@@ -948,6 +941,11 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem)
     bool appended = FALSE;
 #endif
 
+#if GTK_CHECK_VERSION(1, 2, 0)
+    // is this a radio item?
+    bool isRadio = FALSE;
+#endif // GTK+ >= 1.2
+
     if ( mitem->IsSeparator() )
     {
 #if GTK_CHECK_VERSION(1, 2, 0)
@@ -1046,16 +1044,52 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem)
         /* local buffer in multibyte form */
         char buf[200];
         strcpy( buf, "/" );
-        strcat( buf, text.mb_str() );
+        strncat( buf, text.mb_str(), WXSIZEOF(buf) - 2 );
+        buf[WXSIZEOF(buf) - 1] = '\0';
 
         GtkItemFactoryEntry entry;
         entry.path = buf;
         entry.callback = (GtkItemFactoryCallback) gtk_menu_clicked_callback;
         entry.callback_action = 0;
-        if ( mitem->IsCheckable() )
-            entry.item_type = (char *)"<CheckItem>";
-        else
-            entry.item_type = (char *)"<Item>";
+
+        wxString pathRadio;
+        const char *item_type;
+        switch ( mitem->GetKind() )
+        {
+            case wxItem_Check:
+                item_type = "<CheckItem>";
+                break;
+
+            case wxItem_Radio:
+                if ( m_pathLastRadio.empty() )
+                {
+                    // start of a new radio group
+                    item_type = "<RadioItem>";
+                    m_pathLastRadio = buf + 1;
+                }
+                else // continue the radio group
+                {
+                    pathRadio = m_pathLastRadio;
+                    pathRadio.Replace("_", "");
+                    pathRadio.Prepend("<main>/");
+                    item_type = pathRadio;
+                }
+
+                // remember that this one was a radio item to avoid resetting
+                // m_pathLastRadio below
+                isRadio = TRUE;
+                break;
+
+            default:
+                wxFAIL_MSG( _T("unexpected menu item kind") );
+                // fall through
+
+            case wxItem_Normal:
+                item_type = "<Item>";
+                break;
+        }
+
+        entry.item_type = (char *)item_type; // cast needed for GTK+
         entry.accelerator = (gchar*) NULL;
 
 #if wxUSE_ACCEL
@@ -1105,6 +1139,13 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem)
 
     mitem->SetMenuItem(menuItem);
 
+#if GTK_CHECK_VERSION(1, 2, 0)
+    if ( !isRadio )
+    {
+        m_pathLastRadio.clear();
+    }
+#endif // GTK+ >= 1.2
+
     return TRUE;
 }
 
diff --git a/src/mac/carbon/menuitem.cpp b/src/mac/carbon/menuitem.cpp
index 062a2f6edd..544bfd6004 100644
--- a/src/mac/carbon/menuitem.cpp
+++ b/src/mac/carbon/menuitem.cpp
@@ -175,23 +175,15 @@ int wxMenuItem::MacBuildMenuString(StringPtr outMacItemText, SInt16 *outMacShort
 // ctor & dtor
 // -----------
 
-wxMenuItem::wxMenuItem(wxMenu *pParentMenu, int id,
-                       const wxString& text, const wxString& strHelp,
-                       bool bCheckable,
+wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
+                       int id,
+                       const wxString& text,
+                       const wxString& strHelp,
+                       wxItemKind kind,
                        wxMenu *pSubMenu) 
+          : wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu)
 {
-    wxASSERT( pParentMenu != NULL );
-
-    m_parentMenu  = pParentMenu;
-    m_subMenu     = pSubMenu;
-    m_isEnabled   = TRUE;
-    m_isChecked   = FALSE;
-    m_id          = id;
-    m_text        = text;
-    m_isCheckable = bCheckable;
-    m_help        = strHelp;
-
-
+    // VZ: what about translations?? (FIXME)
     if ( m_text ==  "E&xit"  ||m_text == "Exit"  ||m_text.Left(5) == "Exit\t" || m_text.Left(6) == "E&xit\t" )
     {
         m_text = "Quit\tCtrl+Q" ;
@@ -348,8 +340,8 @@ wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
                                 int id,
                                 const wxString& name,
                                 const wxString& help,
-                                bool isCheckable,
+                                wxItemKind kind,
                                 wxMenu *subMenu)
 {
-    return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
+    return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
 }
diff --git a/src/mac/menuitem.cpp b/src/mac/menuitem.cpp
index 062a2f6edd..544bfd6004 100644
--- a/src/mac/menuitem.cpp
+++ b/src/mac/menuitem.cpp
@@ -175,23 +175,15 @@ int wxMenuItem::MacBuildMenuString(StringPtr outMacItemText, SInt16 *outMacShort
 // ctor & dtor
 // -----------
 
-wxMenuItem::wxMenuItem(wxMenu *pParentMenu, int id,
-                       const wxString& text, const wxString& strHelp,
-                       bool bCheckable,
+wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
+                       int id,
+                       const wxString& text,
+                       const wxString& strHelp,
+                       wxItemKind kind,
                        wxMenu *pSubMenu) 
+          : wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu)
 {
-    wxASSERT( pParentMenu != NULL );
-
-    m_parentMenu  = pParentMenu;
-    m_subMenu     = pSubMenu;
-    m_isEnabled   = TRUE;
-    m_isChecked   = FALSE;
-    m_id          = id;
-    m_text        = text;
-    m_isCheckable = bCheckable;
-    m_help        = strHelp;
-
-
+    // VZ: what about translations?? (FIXME)
     if ( m_text ==  "E&xit"  ||m_text == "Exit"  ||m_text.Left(5) == "Exit\t" || m_text.Left(6) == "E&xit\t" )
     {
         m_text = "Quit\tCtrl+Q" ;
@@ -348,8 +340,8 @@ wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
                                 int id,
                                 const wxString& name,
                                 const wxString& help,
-                                bool isCheckable,
+                                wxItemKind kind,
                                 wxMenu *subMenu)
 {
-    return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
+    return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
 }
diff --git a/src/motif/menuitem.cpp b/src/motif/menuitem.cpp
index bb464edeae..c0006a0433 100644
--- a/src/motif/menuitem.cpp
+++ b/src/motif/menuitem.cpp
@@ -62,7 +62,7 @@ static void wxMenuItemDisarmCallback(Widget w, XtPointer clientData, XtPointer p
 // dynamic classes implementation
 // ----------------------------------------------------------------------------
 
-    IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
 
 // ----------------------------------------------------------------------------
 // wxMenuItem
@@ -71,23 +71,14 @@ static void wxMenuItemDisarmCallback(Widget w, XtPointer clientData, XtPointer p
 // ctor & dtor
 // -----------
 
-wxMenuItem::wxMenuItem(wxMenu *pParentMenu, int id,
-                       const wxString& strName, const wxString& strHelp,
-                       bool bCheckable,
+wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
+                       int id,
+                       const wxString& strName,
+                       const wxString& strHelp,
+                       wxItemKind kind,
                        wxMenu *pSubMenu)
+          : wxMenuItemBase(pParentMenu, id, strName, strHelp, kind, pSubMenu)
 {
-    wxASSERT_MSG( pParentMenu != NULL, wxT("menuitem should have a menu") );
-
-    // common init
-    m_parentMenu  = pParentMenu;
-    m_subMenu     = pSubMenu;
-    m_id          = id;
-    m_isEnabled   = TRUE;
-    m_isChecked   = FALSE;
-    m_help        = strHelp;
-    m_isCheckable = bCheckable;
-    m_text        = strName;
-
     // Motif-specific
     m_menuBar      = NULL;
     m_buttonWidget = (WXWidget) NULL;
@@ -170,10 +161,10 @@ wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
                                 int id,
                                 const wxString& name,
                                 const wxString& help,
-                                bool isCheckable,
+                                wxItemKind kind,
                                 wxMenu *subMenu)
 {
-    return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
+    return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
 }
 
 // ----------------------------------------------------------------------------
diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp
index 33e67a5d9f..cc38055c1f 100644
--- a/src/msw/menuitem.cpp
+++ b/src/msw/menuitem.cpp
@@ -85,10 +85,11 @@ wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
                        int id,
                        const wxString& text,
                        const wxString& strHelp,
-                       bool bCheckable,
+                       wxItemKind kind,
                        wxMenu *pSubMenu)
+          : wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu)
 #if wxUSE_OWNER_DRAWN
-                       : wxOwnerDrawn(GetLabelFromText(text), bCheckable)
+            , wxOwnerDrawn(GetLabelFromText(text), kind == wxItem_Check)
 #endif // owner drawn
 {
     wxASSERT_MSG( pParentMenu != NULL, wxT("a menu item should have a parent") );
@@ -108,15 +109,6 @@ wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
     // tell the owner drawing code to to show the accel string as well
     SetAccelString(text.AfterFirst(_T('\t')));
 #endif // wxUSE_OWNER_DRAWN
-
-    m_parentMenu  = pParentMenu;
-    m_subMenu     = pSubMenu;
-    m_isEnabled   = TRUE;
-    m_isChecked   = FALSE;
-    m_id          = id;
-    m_text        = text;
-    m_isCheckable = bCheckable;
-    m_help        = strHelp;
 }
 
 wxMenuItem::~wxMenuItem()
@@ -170,7 +162,7 @@ void wxMenuItem::Enable(bool enable)
 
 void wxMenuItem::Check(bool check)
 {
-    wxCHECK_RET( m_isCheckable, wxT("only checkable items may be checked") );
+    wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") );
 
     if ( m_isChecked == check )
         return;
@@ -256,10 +248,10 @@ wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
                                 int id,
                                 const wxString& name,
                                 const wxString& help,
-                                bool isCheckable,
+                                wxItemKind kind,
                                 wxMenu *subMenu)
 {
-    return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
+    return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
 }
 
 #endif // wxUSE_MENUS
diff --git a/src/os2/menuitem.cpp b/src/os2/menuitem.cpp
index 761e549f2c..9b5bc2fed4 100644
--- a/src/os2/menuitem.cpp
+++ b/src/os2/menuitem.cpp
@@ -110,11 +110,12 @@ wxMenuItem::wxMenuItem(
 , int                               nId
 , const wxString&                   rText
 , const wxString&                   rStrHelp
-, bool                              bCheckable
+, wxItemKind                        kind
 , wxMenu*                           pSubMenu
 )
+: wxMenuItemBase(pParentMenu, nId, rText, rStrHelp, kind, pSubMenu)
 #if wxUSE_OWNER_DRAWN
-:  wxOwnerDrawn( TextToLabel(rText)
+,  wxOwnerDrawn( TextToLabel(rText)
                 ,bCheckable
                )
 #endif // owner drawn
@@ -139,14 +140,8 @@ wxMenuItem::wxMenuItem(
     #undef  SYS_COLOR
 #endif // wxUSE_OWNER_DRAWN
 
-    m_parentMenu  = pParentMenu;
-    m_subMenu     = pSubMenu;
-    m_isEnabled   = TRUE;
-    m_isChecked   = FALSE;
-    m_id          = nId;
     m_text        = TextToLabel(rText);
-    m_isCheckable = bCheckable;
-    m_help        = rStrHelp;
+
     memset(&m_vMenuData, '\0', sizeof(m_vMenuData));
     m_vMenuData.id= nId;
 } // end of wxMenuItem::wxMenuItem
@@ -236,7 +231,7 @@ void wxMenuItem::Check(
 {
     bool                            bOk;
 
-    wxCHECK_RET( m_isCheckable, wxT("only checkable items may be checked") );
+    wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") );
     if (m_isChecked == bCheck)
         return;
     if (bCheck)
@@ -359,7 +354,7 @@ wxMenuItem* wxMenuItemBase::New(
 , int                               nId
 , const wxString&                   rName
 , const wxString&                   rHelp
-, bool                              bIsCheckable
+, wxItemKind                        kind
 , wxMenu*                           pSubMenu
 )
 {
@@ -367,7 +362,7 @@ wxMenuItem* wxMenuItemBase::New(
                           ,nId
                           ,rName
                           ,rHelp
-                          ,bIsCheckable
+                          ,kind
                           ,pSubMenu
                          );
 } // end of wxMenuItemBase::New
diff --git a/src/univ/menu.cpp b/src/univ/menu.cpp
index 16c3f95bd4..3063fa8106 100644
--- a/src/univ/menu.cpp
+++ b/src/univ/menu.cpp
@@ -1397,20 +1397,10 @@ wxMenuItem::wxMenuItem(wxMenu *parentMenu,
                        int id,
                        const wxString& text,
                        const wxString& help,
-                       bool isCheckable,
+                       wxItemKind kind,
                        wxMenu *subMenu)
+          : wxMenuItemBase(parentMenu, id, text, help, kind, subMenu)
 {
-    m_id = id;
-    m_parentMenu = parentMenu;
-    m_subMenu = subMenu;
-
-    m_text = text;
-    m_help = help;
-
-    m_isCheckable = isCheckable;
-    m_isEnabled = TRUE;
-    m_isChecked = FALSE;
-
     m_posY =
     m_height = -1;
 
@@ -1474,7 +1464,7 @@ void wxMenuItem::SetText(const wxString& text)
 
 void wxMenuItem::SetCheckable(bool checkable)
 {
-    if ( checkable != m_isCheckable )
+    if ( checkable != IsCheckable() )
     {
         wxMenuItemBase::SetCheckable(checkable);
 
-- 
2.50.0

