From ccef86c75da7844d15435f4093bf992f60786cea Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Sat, 23 Feb 2002 23:16:32 +0000
Subject: [PATCH] added EVT_MENU_OPEN and EVT_MENU_CLOSE events

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14376 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt           |  3 ++-
 docs/latex/wx/cmdevent.tex |  3 +++
 docs/latex/wx/menuevt.tex  | 33 +++++++++++++++++++++------------
 include/wx/event.h         | 21 +++++++++++++--------
 include/wx/msw/frame.h     |  1 +
 samples/menu/menu.cpp      | 33 ++++++++++++++++++++++++++++++---
 src/common/event.cpp       |  5 ++---
 src/msw/frame.cpp          | 38 ++++++++++++++++++++++++++++----------
 8 files changed, 100 insertions(+), 37 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index 9d5f89ae37..fc02199bc5 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -97,15 +97,16 @@ Unix (Base/GUI):
 
 All (GUI):
 
+- significantly improved native font support
 - wxImage::ComputeHistogram() now uses wxImageHistogram instead of type-unsafe
   wxHashTable
-- significantly improved native font support
 - added IFF image handler
 - fixed using custom renderers in wxGrid which was broken in 2.3.2
 - support for multiple images in one file added to wxImage (TIFF and ICO formats)
 - support for CUR and ANI files in wxImage added (Chris Elliott)
 - wxTextCtrl::GetRange() added
 - added wxGetFontFromUser() convenience function
+- added EVT_MENU_OPEN and EVT_MENU_CLOSE events
 
 wxMSW:
 
diff --git a/docs/latex/wx/cmdevent.tex b/docs/latex/wx/cmdevent.tex
index f129cfc0ce..a208fe97f3 100644
--- a/docs/latex/wx/cmdevent.tex
+++ b/docs/latex/wx/cmdevent.tex
@@ -47,6 +47,9 @@ characters into it than the limit previosuly set with
 which is generated by a menu item.}
 \twocolitem{{\bf EVT\_MENU\_RANGE(id1, id2, func)}}{Process a wxEVT\_COMMAND\_MENU\_RANGE command,
 which is generated by a range of menu items.}
+\twocolitem{{\bf EVT\_CONTEXT\_MENU(func)}}{Process the event generated
+when the user has requested a popup menu to appear by pressing a special
+keyboard key (under Windows) or by right clicking the mouse.}
 \twocolitem{{\bf EVT\_SLIDER(id, func)}}{Process a wxEVT\_COMMAND\_SLIDER\_UPDATED command,
 which is generated by a wxSlider control.}
 \twocolitem{{\bf EVT\_RADIOBOX(id, func)}}{Process a wxEVT\_COMMAND\_RADIOBOX\_SELECTED command,
diff --git a/docs/latex/wx/menuevt.tex b/docs/latex/wx/menuevt.tex
index 51cba035cf..aa6f00b5c9 100644
--- a/docs/latex/wx/menuevt.tex
+++ b/docs/latex/wx/menuevt.tex
@@ -19,21 +19,19 @@ functions that take a wxMenuEvent argument.
 
 \twocolwidtha{7cm}
 \begin{twocollist}\itemsep=0pt
-\twocolitem{{\bf EVT\_MENU\_CHAR(func)}}{Process a wxEVT\_MENU\_CHAR event (a keypress
-when a menu is showing). Windows only; not yet implemented.}
-\twocolitem{{\bf EVT\_MENU\_INIT(func)}}{Process a wxEVT\_MENU\_INIT event (the menu
-is about to pop up). Windows only; not yet implemented.}
-\twocolitem{{\bf EVT\_MENU\_HIGHLIGHT(func)}}{Process a wxEVT\_MENU\_HIGHLIGHT event (a menu
-item is being highlighted). Windows only; not yet implemented.}
-\twocolitem{{\bf EVT\_POPUP\_MENU(func)}}{Process a wxEVT\_POPUP\_MENU event (a menu
-item is being highlighted). Windows only; not yet implemented.}
-\twocolitem{{\bf EVT\_CONTEXT\_MENU(func)}}{Process a wxEVT\_CONTEXT\_MENU event (F1 has
-been pressed with a particular menu item highlighted). Windows only; not yet implemented.}
+\twocolitem{{\bf EVT\_MENU\_OPEN(func)}}{A menu is about to be opened.}
+\twocolitem{{\bf EVT\_MENU\_CLOSE(func)}}{A menu has been just closed.}
+\twocolitem{{\bf EVT\_MENU\_HIGHLIGHT(id, func)}}{The menu item with the
+speicifed id has been highlighted: used to show help prompts in the status bar
+by \helpref{wxFrame}{wxframe}}
+\twocolitem{{\bf EVT\_MENU\_HIGHLIGHT\_ALL(func)}}{A menu item has been
+highlighted, i.e. the currently selected menu item has changed.}
 \end{twocollist}%
 
 \wxheading{See also}
 
-\helpref{wxWindow::OnMenuHighlight}{wxwindowonmenuhighlight}, \helpref{Event handling overview}{eventhandlingoverview}
+\helpref{Command events}{wxcommandevent},\\
+\helpref{Event handling overview}{eventhandlingoverview}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
@@ -53,5 +51,16 @@ The relevant menu identifier.
 
 \constfunc{int}{GetMenuId}{\void}
 
-Returns the menu identifier associated with the event.
+Returns the menu identifier associated with the event. This method should be
+only used with the {\tt HIGHLIGHT} events.
+
+\membersection{wxMenuEvent::IsPopup}\label{wxmenueventispopup}
+
+\constfunc{bool}{IsPopup}{\void}
+
+Returns {\tt TRUE} if the menu which is being opened or closed is a popup menu, 
+{\tt FALSE} if it is a normal one.
+
+This method should be only used with the {\tt OPEN} and {\tt CLOSE} events.
+
 
diff --git a/include/wx/event.h b/include/wx/event.h
index cedaf922eb..e4b6b81fd3 100644
--- a/include/wx/event.h
+++ b/include/wx/event.h
@@ -224,10 +224,10 @@ BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_EVENT_TYPE(wxEVT_ERASE_BACKGROUND, 417)
     DECLARE_EVENT_TYPE(wxEVT_NC_PAINT, 418)
     DECLARE_EVENT_TYPE(wxEVT_PAINT_ICON, 419)
-    DECLARE_EVENT_TYPE(wxEVT_MENU_CHAR, 420)
-    DECLARE_EVENT_TYPE(wxEVT_MENU_INIT, 421)
+    DECLARE_EVENT_TYPE(wxEVT_MENU_OPEN, 420)
+    DECLARE_EVENT_TYPE(wxEVT_MENU_CLOSE, 421)
     DECLARE_EVENT_TYPE(wxEVT_MENU_HIGHLIGHT, 422)
-    DECLARE_EVENT_TYPE(wxEVT_POPUP_MENU_INIT, 423)
+    // DECLARE_EVENT_TYPE(wxEVT_POPUP_MENU_INIT, 423) -- free slot
     DECLARE_EVENT_TYPE(wxEVT_CONTEXT_MENU, 424)
     DECLARE_EVENT_TYPE(wxEVT_SYS_COLOUR_CHANGED, 425)
     DECLARE_EVENT_TYPE(wxEVT_DISPLAY_CHANGED, 426)
@@ -1048,26 +1048,29 @@ private:
 
 // Miscellaneous menu event class
 /*
- wxEVT_MENU_CHAR,
- wxEVT_MENU_INIT,
+ wxEVT_MENU_OPEN,
+ wxEVT_MENU_CLOSE,
  wxEVT_MENU_HIGHLIGHT,
- wxEVT_POPUP_MENU_INIT,
 */
 
 class WXDLLEXPORT wxMenuEvent : public wxEvent
 {
 public:
     wxMenuEvent(wxEventType type = wxEVT_NULL, int id = 0)
-      { m_eventType = type; m_menuId = id; m_id = id; }
+        : wxEvent(id, type)
+        { m_menuId = id; }
 
+    // only for wxEVT_MENU_HIGHLIGHT
     int GetMenuId() const { return m_menuId; }
 
+    // only for wxEVT_MENU_OPEN/CLOSE
+    bool IsPopup() const { return m_menuId == -1; }
+
     virtual wxEvent *Clone() const { return new wxMenuEvent(*this); }
 
 private:
     int m_menuId;
 
-private:
     DECLARE_DYNAMIC_CLASS(wxMenuEvent)
 };
 
@@ -1973,6 +1976,8 @@ typedef void (wxEvtHandler::*wxContextMenuEventFunction)(wxContextMenuEvent&);
 #define EVT_KEY_DOWN(func)  DECLARE_EVENT_TABLE_ENTRY( wxEVT_KEY_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCharEventFunction) & func, (wxObject *) NULL ),
 #define EVT_KEY_UP(func)  DECLARE_EVENT_TABLE_ENTRY( wxEVT_KEY_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCharEventFunction) & func, (wxObject *) NULL ),
 #define EVT_CHAR_HOOK(func)  DECLARE_EVENT_TABLE_ENTRY( wxEVT_CHAR_HOOK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCharEventFunction) & func, NULL ),
+#define EVT_MENU_OPEN(func)  DECLARE_EVENT_TABLE_ENTRY( wxEVT_MENU_OPEN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMenuEventFunction) & func, (wxObject *) NULL ),
+#define EVT_MENU_CLOSE(func)  DECLARE_EVENT_TABLE_ENTRY( wxEVT_MENU_CLOSE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMenuEventFunction) & func, (wxObject *) NULL ),
 #define EVT_MENU_HIGHLIGHT(id, func)  DECLARE_EVENT_TABLE_ENTRY( wxEVT_MENU_HIGHLIGHT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxMenuEventFunction) & func, (wxObject *) NULL ),
 #define EVT_MENU_HIGHLIGHT_ALL(func)  DECLARE_EVENT_TABLE_ENTRY( wxEVT_MENU_HIGHLIGHT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMenuEventFunction) & func, (wxObject *) NULL ),
 #define EVT_SET_FOCUS(func)  DECLARE_EVENT_TABLE_ENTRY( wxEVT_SET_FOCUS, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxFocusEventFunction) & func, (wxObject *) NULL ),
diff --git a/include/wx/msw/frame.h b/include/wx/msw/frame.h
index 300931980a..b3f81e6c79 100644
--- a/include/wx/msw/frame.h
+++ b/include/wx/msw/frame.h
@@ -91,6 +91,7 @@ public:
     bool HandleSize(int x, int y, WXUINT flag);
     bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control);
     bool HandleMenuSelect(WXWORD nItem, WXWORD nFlags, WXHMENU hMenu);
+    bool HandleMenuLoop(const wxEventType& evtType, WXWORD isPopup);
 
     // tooltip management
 #if wxUSE_TOOLTIPS
diff --git a/samples/menu/menu.cpp b/samples/menu/menu.cpp
index b60d0c74c9..942d2df319 100644
--- a/samples/menu/menu.cpp
+++ b/samples/menu/menu.cpp
@@ -88,13 +88,27 @@ protected:
     void OnGetLabelMenu(wxCommandEvent& event);
     void OnSetLabelMenu(wxCommandEvent& event);
 
-    void OnRightUp(wxMouseEvent& event);
+#ifdef __WXMSW__
+    void OnContextMenu(wxContextMenuEvent& event)
+        { ShowContextMenu(ScreenToClient(event.GetPosition())); }
+#else
+    void OnRightUp(wxMouseEvent& event)
+        { ShowContextMenu(event.GetPosition()); }
+#endif
+
+    void OnMenuOpen(wxMenuEvent& event)
+        { LogMenuOpenOrClose(event, _T("opened")); }
+    void OnMenuClose(wxMenuEvent& event)
+        { LogMenuOpenOrClose(event, _T("closed")); }
 
     void OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event);
 
     void OnSize(wxSizeEvent& event);
 
 private:
+    void LogMenuOpenOrClose(const wxMenuEvent& event, const wxChar *what);
+    void ShowContextMenu(const wxPoint& pos);
+
     wxMenu *CreateDummyMenu(wxString *title);
 
     wxMenuItem *GetLastMenuItem() const;
@@ -208,7 +222,14 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
 
     EVT_UPDATE_UI(Menu_Menu_Check, MyFrame::OnUpdateCheckMenuItemUI)
 
+#ifdef __WXMSW__
+    EVT_CONTEXT_MENU(MyFrame::OnContextMenu)
+#else
     EVT_RIGHT_UP(MyFrame::OnRightUp)
+#endif
+
+    EVT_MENU_OPEN(MyFrame::OnMenuOpen)
+    EVT_MENU_CLOSE(MyFrame::OnMenuClose)
 
     EVT_SIZE(MyFrame::OnSize)
 END_EVENT_TABLE()
@@ -703,7 +724,7 @@ void MyFrame::OnGetMenuItemInfo(wxCommandEvent& WXUNUSED(event))
     }
 }
 
-void MyFrame::OnRightUp(wxMouseEvent &event)
+void MyFrame::ShowContextMenu(const wxPoint& pos)
 {
     wxMenu menu("Test popup");
 
@@ -719,7 +740,7 @@ void MyFrame::OnRightUp(wxMouseEvent &event)
     menu.Check(Menu_Popup_ToBeChecked, TRUE);
     menu.Enable(Menu_Popup_ToBeGreyed, FALSE);
 
-    PopupMenu(&menu, event.GetX(), event.GetY());
+    PopupMenu(&menu, pos.x, pos.y);
 
     // test for destroying items in popup menus
 #if 0 // doesn't work in wxGTK!
@@ -729,6 +750,12 @@ void MyFrame::OnRightUp(wxMouseEvent &event)
 #endif // 0
 }
 
+void MyFrame::LogMenuOpenOrClose(const wxMenuEvent& event, const wxChar *what)
+{
+    wxLogStatus(this, _T("A %smenu has been %s."),
+                event.IsPopup() ? _T("popup ") : _T(""), what);
+}
+
 void MyFrame::OnSize(wxSizeEvent& event)
 {
     if ( !m_textctrl )
diff --git a/src/common/event.cpp b/src/common/event.cpp
index c81e168b15..df2d8c4477 100644
--- a/src/common/event.cpp
+++ b/src/common/event.cpp
@@ -219,10 +219,9 @@ DEFINE_EVENT_TYPE(wxEVT_PAINT)
 DEFINE_EVENT_TYPE(wxEVT_ERASE_BACKGROUND)
 DEFINE_EVENT_TYPE(wxEVT_NC_PAINT)
 DEFINE_EVENT_TYPE(wxEVT_PAINT_ICON)
-DEFINE_EVENT_TYPE(wxEVT_MENU_CHAR)
-DEFINE_EVENT_TYPE(wxEVT_MENU_INIT)
+DEFINE_EVENT_TYPE(wxEVT_MENU_OPEN)
+DEFINE_EVENT_TYPE(wxEVT_MENU_CLOSE)
 DEFINE_EVENT_TYPE(wxEVT_MENU_HIGHLIGHT)
-DEFINE_EVENT_TYPE(wxEVT_POPUP_MENU_INIT)
 DEFINE_EVENT_TYPE(wxEVT_CONTEXT_MENU)
 DEFINE_EVENT_TYPE(wxEVT_SYS_COLOUR_CHANGED)
 DEFINE_EVENT_TYPE(wxEVT_DISPLAY_CHANGED)
diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp
index 920e95879b..c4ab391cd8 100644
--- a/src/msw/frame.cpp
+++ b/src/msw/frame.cpp
@@ -763,7 +763,17 @@ bool wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu)
     }
 
     wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item);
-    event.SetEventObject( this );
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxFrame::HandleMenuLoop(const wxEventType& evtType, WXWORD isPopup)
+{
+    // we don't have the menu id here, so we use the id to specify if the event
+    // was from a popup menu or a normal one
+    wxMenuEvent event(evtType, isPopup ? -1 : 0);
+    event.SetEventObject(this);
 
     return GetEventHandler()->ProcessEvent(event);
 }
@@ -785,6 +795,10 @@ long wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
             processed = !Close();
             break;
 
+        case WM_SIZE:
+            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
+            break;
+
         case WM_COMMAND:
             {
                 WORD id, cmd;
@@ -796,6 +810,10 @@ long wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
             }
             break;
 
+        case WM_PAINT:
+            processed = HandlePaint();
+            break;
+
 #ifndef __WXMICROWIN__
         case WM_MENUSELECT:
             {
@@ -806,13 +824,17 @@ long wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
                 processed = HandleMenuSelect(item, flags, hmenu);
             }
             break;
-#endif
 
-        case WM_PAINT:
-            processed = HandlePaint();
+#ifndef __WIN16__
+        case WM_ENTERMENULOOP:
+            processed = HandleMenuLoop(wxEVT_MENU_OPEN, wParam);
             break;
 
-#ifndef __WXMICROWIN__
+        case WM_EXITMENULOOP:
+            processed = HandleMenuLoop(wxEVT_MENU_CLOSE, wParam);
+            break;
+#endif // __WIN16__
+
         case WM_QUERYDRAGICON:
             {
                 HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
@@ -821,11 +843,7 @@ long wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
                 processed = rc != 0;
             }
             break;
-#endif
-
-        case WM_SIZE:
-            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
-            break;
+#endif // !__WXMICROWIN__
     }
 
     if ( !processed )
-- 
2.50.0

