From c82be69b51b8f8aabb5bd667b063dba399c6d894 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Thu, 7 Oct 2004 18:35:50 +0000 Subject: [PATCH] Applied patch [ 1039456 ] [wxOS2]Popup menu problems 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 | 20 +++++++++----- src/os2/window.cpp | 66 +++++++++++++++++++++++++++++++--------------- 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/src/os2/menu.cpp b/src/os2/menu.cpp index a834dd5e85..ca8af4aa8e 100644 --- a/src/os2/menu.cpp +++ b/src/os2/menu.cpp @@ -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(); } diff --git a/src/os2/window.cpp b/src/os2/window.cpp index 6c57b9aa91..e104adeddf 100644 --- a/src/os2/window.cpp +++ b/src/os2/window.cpp @@ -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( -- 2.45.2