]> git.saurik.com Git - wxWidgets.git/commitdiff
Applied patch [ 1039456 ] [wxOS2]Popup menu problems
authorJulian Smart <julian@anthemion.co.uk>
Thu, 7 Oct 2004 18:35:50 +0000 (18:35 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Thu, 7 Oct 2004 18:35:50 +0000 (18:35 +0000)
By Dave Parsons
Fixes problems including:

titles do not display,
title id is already allocated to the menu separator,
menus show in totally the wrong position,
possible to call DoPopupMenu with out of range parameters,
showing a menu enters an infinite loop with 100% cpu usage,
ProcessEvent is called destroying the return value from
HandleMouseEvent.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@29710 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/os2/menu.cpp
src/os2/window.cpp

index a834dd5e855bbd9d46248f215f862e53b9dc3beb..ca8af4aa8e39287bbb6751d70f10733184312863 100644 (file)
@@ -47,7 +47,7 @@ extern wxMenu*                      wxCurrentPopupMenu;
 //
 // The (popup) menu title has this special id
 //
-static const int                    idMenuTitle = -2;
+static const int                    idMenuTitle = -3;
 
 //
 // The unique ID for Menus
@@ -280,7 +280,7 @@ bool wxMenu::DoInsertOrAppend(
         rItem.id = pItem->GetId();
     }
 
-    BYTE*                           pData;
+    BYTE*                           pData=NULL;
 
 #if wxUSE_OWNER_DRAWN
     if (pItem->IsOwnerDrawn())
@@ -304,10 +304,18 @@ bool wxMenu::DoInsertOrAppend(
     }
     else
     {
-        //
-        // Menu is just a normal string (passed in data parameter)
-        //
-        rItem.afStyle |= MIS_TEXT;
+        if (pItem->GetId() == idMenuTitle)
+        {
+            // Item is an unselectable title to be passed via pData
+            rItem.afStyle = MIS_STATIC;
+        }
+        else
+        {
+            //
+            // Menu is just a normal string (passed in data parameter)
+            //
+            rItem.afStyle |= MIS_TEXT;
+        }
         pData = (char*)pItem->GetText().c_str();
     }
 
index 6c57b9aa91ddcf612968e21c2285c628f2ba7b89..e104adeddf51891cc0af31f4e58dc75b57cad810 100644 (file)
@@ -1951,10 +1951,15 @@ bool wxWindowOS2::DoPopupMenu(
     HWND                            hWndParent = GetHwnd();
     HWND                            hMenu = GetHmenuOf(pMenu);
     bool                            bIsWaiting = TRUE;
+    int                             nHeight;
+
+    // Protect against recursion
+    if (wxCurrentPopupMenu)
+        return false;
 
     pMenu->SetInvokingWindow(this);
     pMenu->UpdateUI();
-    
+
     if ( nX == -1 && nY == -1 )
     {
         wxPoint mouse = wxGetMousePosition();
@@ -1965,6 +1970,8 @@ bool wxWindowOS2::DoPopupMenu(
         DoClientToScreen( &nX
                          ,&nY
                         );
+        DoGetSize(0,&nHeight);
+        nY = nHeight - nY;
     }
     wxCurrentPopupMenu = pMenu;
 
@@ -1981,13 +1988,12 @@ bool wxWindowOS2::DoPopupMenu(
     {
         QMSG                            vMsg;
 
-        if (vMsg.msg == WM_MENUEND || vMsg.msg == WM_COMMAND)
-        {
+        ::WinGetMsg(vHabmain,&vMsg, (HWND)0, 0, 0);
+        if (vMsg.msg == WM_COMMAND)
             bIsWaiting = FALSE;
-        }
         ::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
-
     }
+
     wxCurrentPopupMenu = NULL;
     pMenu->SetInvokingWindow(NULL);
     return TRUE;
@@ -2958,6 +2964,20 @@ MRESULT wxWindowOS2::OS2WindowProc(
                 mResult = (MRESULT)TRUE;
             }
             break;
+
+#if wxUSE_MENUS_NATIVE
+         case WM_MENUEND:
+            if (wxCurrentPopupMenu)
+            {
+                if (GetHmenuOf(wxCurrentPopupMenu) == (HWND)lParam)
+                {
+                    // Break out of msg loop in DoPopupMenu
+                    ::WinPostMsg((HWND)lParam,WM_COMMAND,wParam,0);
+                }
+            }
+            break;
+#endif // wxUSE_MENUS_NATIVE
+
     }
     if (!bProcessed)
     {
@@ -4047,7 +4067,7 @@ bool wxWindowOS2::HandleMouseEvent(
 
     //
     // The mouse events take consecutive IDs from WM_MOUSEFIRST to
-    // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
+    // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
     // from the message id and take the value in the table to get wxWin event
     // id
     //
@@ -4065,26 +4085,30 @@ bool wxWindowOS2::HandleMouseEvent(
         wxEVT_MIDDLE_DCLICK
     };
 
-    wxMouseEvent                    vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
-
-    InitMouseEvent( vEvent
-                   ,nX
-                   ,nY
-                   ,uFlags
-                  );
-
-    bProcessed = GetEventHandler()->ProcessEvent(vEvent);
-    if (!bProcessed)
+    // Bounds check
+    if ((uMsg >= WM_MOUSEMOVE) && (uMsg <= WM_BUTTON3DBLCLK))
     {
-        HPOINTER                    hCursor = (HPOINTER)GetCursor().GetHCURSOR();
+        wxMouseEvent               vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
 
-        if (hCursor != NULLHANDLE)
+        InitMouseEvent( vEvent
+                       ,nX
+                       ,nY
+                       ,uFlags
+                       );
+
+        bProcessed = GetEventHandler()->ProcessEvent(vEvent);
+        if (!bProcessed)
         {
-            ::WinSetPointer(HWND_DESKTOP, hCursor);
-            bProcessed = TRUE;
+            HPOINTER               hCursor = (HPOINTER)GetCursor().GetHCURSOR();
+
+            if (hCursor != NULLHANDLE)
+            {
+                ::WinSetPointer(HWND_DESKTOP, hCursor);
+                bProcessed = TRUE;
+            }
         }
     }
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return bProcessed;
 } // end of wxWindowOS2::HandleMouseEvent
 
 bool wxWindowOS2::HandleMouseMove(