user32: fix for the ending of menu tracking in the default handler of WM_CANCELMODE message.
Rein Klazes
wijn at online.nl
Mon Mar 9 06:55:18 CDT 2009
---
dlls/user32/controls.h | 1 +
dlls/user32/defwnd.c | 2 +-
dlls/user32/menu.c | 32 ++++++++++++++++++++++++++++----
dlls/user32/tests/menu.c | 6 ++----
4 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h
index 974cf5b..23d0959 100644
--- a/dlls/user32/controls.h
+++ b/dlls/user32/controls.h
@@ -88,6 +88,7 @@ extern void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar ) DECLSPEC
extern UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect,
HWND hwnd, BOOL suppress_draw ) DECLSPEC_HIDDEN;
extern UINT MENU_FindSubMenu( HMENU *hmenu, HMENU hSubTarget ) DECLSPEC_HIDDEN;
+extern void MENU_EndMenu( HWND) DECLSPEC_HIDDEN;
/* nonclient area */
extern LRESULT NC_HandleNCPaint( HWND hwnd , HRGN clip) DECLSPEC_HIDDEN;
diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c
index 38d8def..6800a5a 100644
--- a/dlls/user32/defwnd.c
+++ b/dlls/user32/defwnd.c
@@ -618,7 +618,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
case WM_CANCELMODE:
iMenuSysKey = 0;
- if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
+ MENU_EndMenu( hwnd);
if (GetCapture() == hwnd) ReleaseCapture();
break;
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index fc6f981..fda5965 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -176,6 +176,7 @@ static UINT ODitemheight; /* default owner drawn item height */
/* Use global popup window because there's no way 2 menus can
* be tracked at the same time. */
static HWND top_popup;
+static HMENU top_popup_hmenu;
/* Flag set by EndMenu() to force an exit from menu tracking */
static BOOL fEndMenu = FALSE;
@@ -1884,8 +1885,10 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
hwndOwner, 0, (HINSTANCE)GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
(LPVOID)hmenu );
if( !menu->hWnd ) return FALSE;
- if (!top_popup) top_popup = menu->hWnd;
-
+ if (!top_popup) {
+ top_popup = menu->hWnd;
+ top_popup_hmenu = hmenu;
+ }
/* Display the window */
SetWindowPos( menu->hWnd, HWND_TOPMOST, 0, 0, 0, 0,
@@ -1953,7 +1956,10 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
if (lppop->FocusedItem == wIndex) return;
if (lppop->wFlags & MF_POPUP) hdc = GetDC( lppop->hWnd );
else hdc = GetDCEx( lppop->hWnd, 0, DCX_CACHE | DCX_WINDOW);
- if (!top_popup) top_popup = lppop->hWnd;
+ if (!top_popup) {
+ top_popup = lppop->hWnd;
+ top_popup_hmenu = hmenu;
+ }
SelectObject( hdc, get_menu_font(FALSE));
@@ -2462,6 +2468,20 @@ HWND MENU_IsMenuActive(void)
return top_popup;
}
+/**********************************************************************
+ * MENU_EndMenu
+ *
+ * Calls EndMenu() if the hwnd parameter belongs to the menu owner
+ *
+ * Does the (menu stuff) of the default window handling of WM_CANCELMODE
+ */
+void MENU_EndMenu( HWND hwnd)
+{
+ POPUPMENU *menu;
+ menu = top_popup_hmenu ? MENU_GetMenu( top_popup_hmenu) : NULL;
+ if( menu && hwnd == menu->hwndOwner) EndMenu();
+}
+
/***********************************************************************
* MENU_PtMenu
*
@@ -3363,6 +3383,7 @@ static BOOL MENU_ExitTracking(HWND hWnd)
SendMessageW( hWnd, WM_EXITMENULOOP, 0, 0 );
ShowCaret(0);
top_popup = 0;
+ top_popup_hmenu = NULL;
return TRUE;
}
@@ -3530,7 +3551,10 @@ static LRESULT WINAPI PopupMenuWndProc( HWND hwnd, UINT message, WPARAM wParam,
case WM_DESTROY:
/* zero out global pointer in case resident popup window was destroyed. */
- if (hwnd == top_popup) top_popup = 0;
+ if (hwnd == top_popup) {
+ top_popup = 0;
+ top_popup_hmenu = NULL;
+ }
break;
case WM_SHOWWINDOW:
diff --git a/dlls/user32/tests/menu.c b/dlls/user32/tests/menu.c
index f1240b0..67e6b8b 100644
--- a/dlls/user32/tests/menu.c
+++ b/dlls/user32/tests/menu.c
@@ -2820,15 +2820,13 @@ void test_menu_cancelmode()
ret = TrackPopupMenu( menu, 0x100, 100,100, 0, hwndchild, NULL);
todo_wine {
ok(g_got_enteridle == 0, "received %d WM_ENTERIDLE messages, none expected\n", g_got_enteridle);
- ok(g_got_enteridle < 2, "received %d WM_ENTERIDLE messages, should be less then 2\n", g_got_enteridle);
}
+ ok(g_got_enteridle < 2, "received %d WM_ENTERIDLE messages, should be less then 2\n", g_got_enteridle);
/* now send the WM_CANCELMODE messages to the WRONG window */
/* those should fail ( to have any effect) */
g_hwndtosend = hwnd;
ret = TrackPopupMenu( menu, 0x100, 100,100, 0, hwndchild, NULL);
- todo_wine {
- ok( g_got_enteridle == 2, "received %d WM_ENTERIDLE messages, should be 2\n", g_got_enteridle);
- }
+ ok( g_got_enteridle == 2, "received %d WM_ENTERIDLE messages, should be 2\n", g_got_enteridle);
/* cleanup */
DestroyMenu( menu);
DestroyWindow( hwndchild);
--
1.6.1.3
--------------040600050906040003080607--
More information about the wine-patches
mailing list