Fix for menus assigned to multiple windows

Michael Kaufmann hallo at michael-kaufmann.ch
Wed Sep 8 14:33:08 CDT 2004


This is the non-disputed part of my patch at 
http://www.winehq.org/hypermail/wine-devel/2004/09/0229.html

It allows a menu to be used in multiple windows. A test program is 
available at the same URL.
-------------- next part --------------
Index: dlls/user/menu.c
===================================================================
RCS file: /home/wine/wine/dlls/user/menu.c,v
retrieving revision 1.1
diff -u -r1.1 menu.c
--- dlls/user/menu.c	31 Aug 2004 01:10:08 -0000	1.1
+++ dlls/user/menu.c	8 Sep 2004 19:12:27 -0000
@@ -83,15 +83,14 @@
     HWND        hWnd;         /* Window containing the menu */
     MENUITEM    *items;       /* Array of menu items */
     UINT        FocusedItem;  /* Currently focused item */
-    HWND	hwndOwner;    /* window receiving the messages for ownerdraw */
     BOOL        bTimeToHide;  /* Request hiding when receiving a second click in the top-level menu item */
     /* ------------ MENUINFO members ------ */
-    DWORD	dwStyle;	/* Extended mennu style */
-    UINT	cyMax;		/* max hight of the whole menu, 0 is screen hight */
-    HBRUSH	hbrBack;	/* brush for menu background */
+    DWORD	dwStyle;	/* Extended menu style */
+    UINT	cyMax;		/* Max height of the whole menu, 0 is screen height */
+    HBRUSH	hbrBack;	/* Brush for menu background */
     DWORD	dwContextHelpID;
-    DWORD	dwMenuData;	/* application defined value */
-    HMENU       hSysMenuOwner;  /* Handle to the dummy sys menu holder */
+    DWORD	dwMenuData;	/* Application-defined value */
+    HMENU	hSysMenuOwner;  /* Handle to the dummy system menu holder */
 } POPUPMENU, *LPPOPUPMENU;
 
 /* internal flags for menu tracking */
@@ -171,6 +170,10 @@
  * be tracked at the same time.  */
 static HWND top_popup;
 
+/* Use a global owner window while tracking the menu.
+ * This window receives ownerdraw messages.  */
+static HWND owner_window;
+
   /* Flag set by EndMenu() to force an exit from menu tracking */
 static BOOL fEndMenu = FALSE;
 
@@ -181,6 +184,7 @@
 /*********************************************************************
  * menu class descriptor
  */
+
 const struct builtin_class_descr MENU_builtin_class =
 {
     POPUPMENU_CLASS_ATOMA,         /* name */
@@ -1405,8 +1409,9 @@
 		UINT u;
 
 		for (u = menu->nItems, item = menu->items; u > 0; u--, item++)
-		    MENU_DrawMenuItem( hwnd, hmenu, menu->hwndOwner, hdc, item,
-				       menu->Height, FALSE, ODA_DRAWENTIRE );
+		  
+		    MENU_DrawMenuItem( hwnd, hmenu, owner_window, hdc, item,
+		  		       menu->Height, FALSE, ODA_DRAWENTIRE );
 
 	    }
 	} else
@@ -1473,10 +1478,6 @@
 	menu->FocusedItem = NO_SELECTED_ITEM;
     }
 
-    /* store the owner for DrawItem */
-    menu->hwndOwner = hwndOwner;
-
-
     MENU_PopupMenuCalcSize( menu, hwndOwner );
 
     /* adjust popup menu pos so that it fits within the desktop */
@@ -2837,7 +2838,11 @@
  */
 static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
 {
+    POPUPMENU* menu;
+
     TRACE("hwnd=%p hmenu=%p\n", hWnd, hMenu);
+        
+    if (!(menu = MENU_GetMenu( hMenu ))) return FALSE;
 
     HideCaret(0);
 
@@ -2849,9 +2854,8 @@
 
     if (!(wFlags & TPM_NONOTIFY))
     {
-       POPUPMENU *menu;
        SendMessageW( hWnd, WM_INITMENU, (WPARAM)hMenu, 0 );
-       if ((menu = MENU_GetMenu( hMenu )) && (!menu->Height))
+       if (!menu->Height)
        { /* app changed/recreated menu bar entries in WM_INITMENU
             Recalculate menu sizes else clicks will not work */
           SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
@@ -2859,6 +2863,13 @@
 
        }
     }
+    
+    /* Multiple windows can use the same menu.
+     * The menu needs to know its owner window for the
+     * current tracking operation.  */
+    owner_window = hWnd;  /* for DrawItem */
+    menu->hWnd = hWnd;    /* for MENU_TrackMenu and many other functions */
+    
     return TRUE;
 }
 /***********************************************************************
@@ -2970,6 +2981,8 @@
 {
     BOOL ret = FALSE;
 
+    if (!IsMenu( hMenu )) return FALSE;
+    
     MENU_InitTracking(hWnd, hMenu, TRUE, wFlags);
 
     /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
@@ -3728,7 +3741,6 @@
     if (!hMenu || !(lppop = MENU_GetMenu( hMenu ))) return FALSE;
 
     lppop->Height = 0; /* Make sure we call MENU_MenuBarCalcSize */
-    lppop->hwndOwner = hWnd;
     SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
                   SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
     return TRUE;


More information about the wine-patches mailing list