Menus [5/6]: Accept more flags in SetMenuItemInfo and ModifyMenu

Michael Kaufmann hallo at michael-kaufmann.ch
Wed Apr 19 14:51:26 CDT 2006


This makes the MDI buttons appear in Word 95.

Changelog:
  - Use new masks to detect valid menu types and styles
  - Accept MFT_MENU{BAR}BREAK, MFT_RADIOCHECK, MFT_RIGHTJUSTIFY, and 
MFT_RIGHTORDER in SetMenuItemInfo
  - InsertMenu, AppendMenu, ModifiyMenu: Accept MF_HILITE flag
  - Resource parsing: Remove MF_END (because it has the same value as 
MF_HILITE)
  - SetMenuItemInfo: Only use the lower word of the bitmap handle as 
documented in MSDN (Word 95 depends on this)
  - The type MFT_RADIOCHECK cannot be set if only the checkmarks are 
modified with SetMenuItemInfo

-------------- next part --------------
--- menu.c	2006-04-19 21:12:53.000000000 +0200
+++ menu-new.c	2006-04-19 21:12:47.000000000 +0200
@@ -159,11 +159,13 @@
 #define IS_SYSTEM_MENU(menu)  \
 	(!((menu)->wFlags & MF_POPUP) && ((menu)->wFlags & MF_SYSMENU))
 
-#define TYPE_MASK (MFT_STRING | MFT_BITMAP | MFT_OWNERDRAW | MFT_SEPARATOR | \
-		   MFT_MENUBARBREAK | MFT_MENUBREAK | MFT_RADIOCHECK | \
-		   MFT_RIGHTORDER | MFT_RIGHTJUSTIFY | \
-		   MF_POPUP | MF_SYSMENU | MF_HELP)
+#define MENUITEMINFO_TYPE_MASK \
+		(MFT_STRING | MFT_BITMAP | MFT_OWNERDRAW | MFT_SEPARATOR | \
+		MFT_MENUBARBREAK | MFT_MENUBREAK | MFT_RADIOCHECK | \
+		MFT_RIGHTORDER | MFT_RIGHTJUSTIFY /* same as MF_HELP */ )
+#define TYPE_MASK  (MENUITEMINFO_TYPE_MASK | MF_POPUP | MF_SYSMENU)
 #define STATE_MASK (~TYPE_MASK)
+#define MENUITEMINFO_STATE_MASK (STATE_MASK & ~(MF_BYPOSITION | MF_MOUSESELECT))
 
 #define WIN_ALLOWED_MENU(style) ((style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
 
@@ -2048,8 +2050,10 @@
       flags |= MF_POPUP; /* keep popup */
 
     item->fType = flags & TYPE_MASK;
-    item->fState = (flags & STATE_MASK) &
-        ~(MF_HILITE | MF_MOUSESELECT | MF_BYPOSITION);
+
+    /* MF_HILITE is not listed as a valid flag for ModifyMenu,
+       but Windows accepts it */
+    item->fState = flags & MENUITEMINFO_STATE_MASK & ~MFS_DEFAULT;
 
     /* Don't call SetRectEmpty here! */
 
@@ -2121,10 +2125,14 @@
 {
     WORD flags, id = 0;
     LPCSTR str;
+    BOOL end_flag;
 
     do
     {
         flags = GET_WORD(res);
+        end_flag = flags & MF_END;
+        /* Remove MF_END because it has the same value as MF_HILITE */
+        flags &= ~MF_END;
         res += sizeof(WORD);
         if (!(flags & MF_POPUP))
         {
@@ -2149,7 +2157,7 @@
             else AppendMenuW( hMenu, flags, id,
                                 *(LPCWSTR)str ? (LPCWSTR)str : NULL );
         }
-    } while (!(flags & MF_END));
+    } while (!end_flag);
     return res;
 }
 
@@ -2309,7 +2317,7 @@
         if (menu->wFlags & MF_POPUP) hdc = GetDC( menu->hWnd );
         else hdc = GetDCEx( menu->hWnd, 0, DCX_CACHE | DCX_WINDOW);
 
-        SelectObject( hdc, get_menu_font(FALSE));
+        SelectObject( hdc, get_menu_font( item->fState & MFS_DEFAULT ));
 
         item->fState |= MF_HILITE;
         MENU_DrawMenuItem( menu->hWnd, hmenu, hwndOwner, hdc, item, menu->Height, !(menu->wFlags & MF_POPUP), ODA_DRAWENTIRE );
@@ -4357,7 +4365,7 @@
 static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
 					LPMENUITEMINFOW lpmii, BOOL unicode)
 {
-    MENUITEM *menu = MENU_FindItem (&hmenu, &item, bypos? MF_BYPOSITION : 0);
+    MENUITEM *menu = MENU_FindItem (&hmenu, &item, bypos ? MF_BYPOSITION : 0);
 
     debug_print_menuitem("GetMenuItemInfo_common: ", menu, "");
 
@@ -4371,7 +4379,7 @@
             SetLastError( ERROR_INVALID_PARAMETER);
             return FALSE;
         }
-	lpmii->fType = menu->fType & ~MF_POPUP;
+	lpmii->fType = menu->fType & MENUITEMINFO_TYPE_MASK;
         if( menu->hbmpItem) lpmii->fType |= MFT_BITMAP;
 	lpmii->hbmpItem = menu->hbmpItem; /* not on Win9x/ME */
         if( lpmii->fType & MFT_BITMAP) {
@@ -4426,13 +4434,13 @@
     }
 
     if (lpmii->fMask & MIIM_FTYPE)
-	lpmii->fType = menu->fType & ~MF_POPUP;
+	lpmii->fType = menu->fType & MENUITEMINFO_TYPE_MASK;
 
     if (lpmii->fMask & MIIM_BITMAP)
 	lpmii->hbmpItem = menu->hbmpItem;
 
     if (lpmii->fMask & MIIM_STATE)
-	lpmii->fState = menu->fState;
+	lpmii->fState = menu->fState & MENUITEMINFO_STATE_MASK;
 
     if (lpmii->fMask & MIIM_ID)
 	lpmii->wID = menu->wID;
@@ -4529,7 +4537,7 @@
 {
     if (!menu) return FALSE;
 
-    debug_print_menuitem("SetmenuItemInfo_common from: ", menu, "");
+    debug_print_menuitem("SetMenuItemInfo_common from: ", menu, "");
 
     if (lpmii->fMask & MIIM_TYPE ) {
         if( lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) {
@@ -4538,15 +4546,15 @@
             SetLastError( ERROR_INVALID_PARAMETER);
             return FALSE;
         }
-	/* make only MENU_ITEM_TYPE bits in menu->fType equal lpmii->fType */
-	menu->fType &= ~MENU_ITEM_TYPE(menu->fType);
-	menu->fType |= MENU_ITEM_TYPE(lpmii->fType);
+	/* Remove the old type bits and replace them with the new ones */
+	menu->fType &= ~MENUITEMINFO_TYPE_MASK;
+	menu->fType |= lpmii->fType & MENUITEMINFO_TYPE_MASK;
 
         if (IS_STRING_ITEM(menu->fType)) {
 	    HeapFree(GetProcessHeap(), 0, menu->text);
             set_menu_item_text( menu, lpmii->dwTypeData, unicode );
         } else if( (menu->fType) & MFT_BITMAP)
-                menu->hbmpItem = (HBITMAP)lpmii->dwTypeData;
+                menu->hbmpItem = HBITMAP_32(LOWORD(lpmii->dwTypeData));
     }
 
     if (lpmii->fMask & MIIM_FTYPE ) {
@@ -4554,8 +4562,8 @@
             SetLastError( ERROR_INVALID_PARAMETER);
             return FALSE;
         }
-	menu->fType &= ~MENU_ITEM_TYPE(menu->fType);
-	menu->fType |= MENU_ITEM_TYPE(lpmii->fType);
+	menu->fType &= ~MENUITEMINFO_TYPE_MASK;
+	menu->fType |= lpmii->fType & MENUITEMINFO_TYPE_MASK;
     }
     if (lpmii->fMask & MIIM_STRING ) {
         /* free the string when used */
@@ -4565,8 +4573,9 @@
 
     if (lpmii->fMask & MIIM_STATE)
     {
-	/* FIXME: MFS_DEFAULT do we have to reset the other menu items? */
-	menu->fState = lpmii->fState;
+         /* Other menu items having MFS_DEFAULT are not converted
+           to normal items */
+	menu->fState = lpmii->fState & MENUITEMINFO_STATE_MASK;
     }
 
     if (lpmii->fMask & MIIM_ID)
@@ -4591,9 +4600,6 @@
 
     if (lpmii->fMask & MIIM_CHECKMARKS)
     {
-        if (lpmii->fType & MFT_RADIOCHECK)
-            menu->fType |= MFT_RADIOCHECK;
-
 	menu->hCheckBit = lpmii->hbmpChecked;
 	menu->hUnCheckBit = lpmii->hbmpUnchecked;
     }


More information about the wine-patches mailing list