user32: when needed, recalculate menu size of menu bar before tracking starts.

Rein Klazes wijn at online.nl
Tue Apr 7 11:35:32 CDT 2009


Fixes bug 10845
---
 dlls/user32/menu.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index ab473ea..82b4772 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -2332,7 +2332,7 @@ static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu,
 {
     POPUPMENU *menu = MENU_GetMenu( hmenu );
 
-    TRACE("owner=%p hmenu=%p 0x%04x\n", hwndOwner, hmenu, sendMenuSelect);
+    TRACE("owner=%p hmenu=%p select 0x%04x flags %08x\n", hwndOwner, hmenu, sendMenuSelect, wFlags);
 
     if (menu && top_popup)
     {
@@ -3069,6 +3069,50 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
         return FALSE;
     }
 
+    /* recalc the menubar size if needed */
+    /* eg if the application modified the menu in the WM_INITMENU message */
+    if (!( wFlags & TPM_POPUPMENU) && !menu->Height)
+    {
+        RECT rc;
+        LONG style = GetWindowLongW( hwnd, GWL_STYLE );
+        LONG exstyle = GetWindowLongW( hwnd, GWL_EXSTYLE );
+        HDC hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW );
+        INT width = 0, height = 0;
+        SelectObject( hdc, get_menu_font(FALSE));
+        /* FIXME: calculations taken from nonclient.c and uitools.c */
+        /* unfortunately too intertwined with non-client redrawing */
+        /* I do not like to introduce another unneeded redraw here */
+        /* this code should probaby be put there */
+        GetWindowRect( hwnd, &rc);
+        SetRect( &rc, 0, 0, rc.right - rc.left, 0);
+        rc.top = GetSystemMetrics(SM_CYCAPTION);
+        if( style & WS_THICKFRAME) {
+            width += GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME);
+            height += GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME);
+        }
+        if(( style & (WS_BORDER|WS_DLGFRAME)) ||
+            (exstyle & WS_EX_DLGMODALFRAME)) {
+            width += GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
+            height += GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
+        }
+        /* HAS_THICKFRAME */
+        if(((style) & WS_THICKFRAME) && !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME)){
+            width++;
+            height++;
+        }
+        /* HAS_BIGFRAME */
+        if(((style) & (WS_THICKFRAME | WS_DLGFRAME)) || ((exstyle) & WS_EX_DLGMODALFRAME)){
+            width++;
+            height++;
+        }
+        rc.left += width;
+        rc.right -= width;
+        rc.top += height;
+        rc.bottom = rc.top + GetSystemMetrics(SM_CYMENU);
+        MENU_MenuBarCalcSize( hdc, &rc, menu, hwnd );
+        ReleaseDC( hwnd, hdc );
+    }
+
     if (wFlags & TPM_BUTTONDOWN)
     {
 	/* Get the result in order to start the tracking or not */
@@ -3361,7 +3405,8 @@ static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
     {
        SendMessageW( hWnd, WM_INITMENU, (WPARAM)hMenu, 0 );
        /* If an app changed/recreated menu bar entries in WM_INITMENU
-        * menu sizes will be recalculated once the menu created/shown.
+        * menu sizes must be recalculated.
+        * Either in MENU_TrackMenu or when the menu is created/shown.
         */
     }
     
-- 
1.6.2.1




More information about the wine-patches mailing list