Rein Klazes : user32: When all items in a menu have either a bitmap or text but not both, then texts should be aligned with the bitmaps.

Alexandre Julliard julliard at winehq.org
Mon Aug 3 11:16:11 CDT 2009


Module: wine
Branch: master
Commit: c18cd1b46fdedd713b0c4113f0f57d433021c5af
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c18cd1b46fdedd713b0c4113f0f57d433021c5af

Author: Rein Klazes <wijn at online.nl>
Date:   Mon Jul 27 08:20:58 2009 +0200

user32: When all items in a menu have either a bitmap or text but not both, then texts should be aligned with the bitmaps.

---

 dlls/user32/menu.c       |   22 ++++++----
 dlls/user32/tests/menu.c |  106 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 119 insertions(+), 9 deletions(-)

diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 203340a..5299c60 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -112,7 +112,7 @@ typedef struct {
     DWORD	dwContextHelpID;
     DWORD	dwMenuData;	/* application defined value */
     HMENU       hSysMenuOwner;  /* Handle to the dummy sys menu holder */
-    SIZE        maxBmpSize;     /* Maximum size of the bitmap items */
+    WORD        textOffset;     /* Offset of text when items have both bitmaps and text */
 } POPUPMENU, *LPPOPUPMENU;
 
 /* internal flags for menu tracking */
@@ -1071,8 +1071,7 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
             /* Keep the size of the bitmap in callback mode to be able
              * to draw it correctly */
             lpitem->bmpsize = size;
-            lppop->maxBmpSize.cx = max( lppop->maxBmpSize.cx, size.cx);
-            lppop->maxBmpSize.cy = max( lppop->maxBmpSize.cy, size.cy);
+            lppop->textOffset = max( lppop->textOffset, size.cx);
             lpitem->rect.right += size.cx + 2;
             itemheight = size.cy + 2;
         }
@@ -1166,6 +1165,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
     MENUITEM *lpitem;
     HDC hdc;
     UINT start, i;
+    int textandbmp = FALSE;
     int orgX, orgY, maxX, maxTab, maxTabWidth, maxHeight;
 
     lppop->Width = lppop->Height = 0;
@@ -1177,8 +1177,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
     start = 0;
     maxX = 2 + 1;
 
-    lppop->maxBmpSize.cx = 0;
-    lppop->maxBmpSize.cy = 0;
+    lppop->textOffset = 0;
 
     while (start < lppop->nItems)
     {
@@ -1203,6 +1202,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
 		maxTab = max( maxTab, lpitem->xTab );
 		maxTabWidth = max(maxTabWidth,lpitem->rect.right-lpitem->xTab);
 	    }
+            if( lpitem->text && lpitem->hbmpItem) textandbmp = TRUE;
 	}
 
 	  /* Finish the column (set all items to the largest width found) */
@@ -1218,6 +1218,12 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
     }
 
     lppop->Width  = maxX;
+    /* if none of the items have both text and bitmap then
+     * the text and bitmaps are all aligned on the left. If there is at
+     * least one item with both text and bitmap then bitmaps are
+     * on the left and texts left aligned with the right hand side
+     * of the bitmaps */
+    if( !textandbmp) lppop->textOffset = 0;
 
     /* space for 3d border */
     lppop->Height += MENU_BOTTOM_MARGIN;
@@ -1264,8 +1270,7 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect,
     maxY = lprect->top+1;
     start = 0;
     helpPos = ~0U;
-    lppop->maxBmpSize.cx = 0;
-    lppop->maxBmpSize.cy = 0;
+    lppop->textOffset = 0;
     while (start < lppop->nItems)
     {
 	lpitem = &lppop->items[start];
@@ -1658,7 +1663,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
 			DT_LEFT | DT_VCENTER | DT_SINGLELINE;
 
         if( !(menu->dwStyle & MNS_CHECKORBMP))
-            rect.left += menu->maxBmpSize.cx;
+            rect.left += menu->textOffset;
 
 	if ( lpitem->fState & MFS_DEFAULT )
 	{
@@ -1760,6 +1765,7 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu )
 
             if( (menu = MENU_GetMenu( hmenu )))
             {
+                TRACE("hmenu %p Style %08x\n", hmenu, menu->dwStyle);
                 /* draw menu items */
                 if( menu->nItems)
                 {
diff --git a/dlls/user32/tests/menu.c b/dlls/user32/tests/menu.c
index a1af944..7ffe29a 100644
--- a/dlls/user32/tests/menu.c
+++ b/dlls/user32/tests/menu.c
@@ -536,7 +536,7 @@ static void test_mbs_help( int ispop, int hassub, int mnuopt,
         mi.cbSize = sizeof(mi);
         mi.fMask = MIM_STYLE;
         pGetMenuInfo( hmenu, &mi);
-        mi.dwStyle |= mnuopt == 1 ? MNS_NOCHECK : MNS_CHECKORBMP;
+        if( mnuopt) mi.dwStyle |= mnuopt == 1 ? MNS_NOCHECK : MNS_CHECKORBMP;
         ret = pSetMenuInfo( hmenu, &mi);
         ok( ret, "SetMenuInfo failed with error %d\n", GetLastError());
     }
@@ -3067,6 +3067,109 @@ static void test_menu_circref(void)
     DestroyMenu( menu1);
 }
 
+/* test how the menu texts are aligned when the menu items have
+ * different combinations of text and bitmaps (bug #13350) */
+static void test_menualign(void)
+{
+    BYTE bmfill[300];
+    HMENU menu;
+    HBITMAP hbm1, hbm2, hbm3;
+    MENUITEMINFO mii = { sizeof(MENUITEMINFO)};
+    DWORD ret;
+    HWND hwnd;
+    MENUINFO mi = { sizeof( MENUINFO)};
+
+    if( !winetest_interactive) {
+        skip( "interactive alignment tests.\n");
+        return;
+    }
+    hwnd = CreateWindowEx(0,
+            "STATIC",
+            "Menu text alignment Test\nPlease make a selection.",
+            WS_OVERLAPPEDWINDOW,
+            100, 100,
+            300, 300,
+            NULL, NULL, 0, NULL);
+    ShowWindow( hwnd, SW_SHOW);
+    /* create bitmaps */
+    memset( bmfill, 0xcc, sizeof( bmfill));
+    hbm1 = CreateBitmap( 10,10,1,1,bmfill);
+    hbm2 = CreateBitmap( 20,20,1,1,bmfill);
+    hbm3 = CreateBitmap( 50,6,1,1,bmfill);
+    ok( hbm1 && hbm2 && hbm3, "Creating bitmaps failed\n");
+    menu = CreatePopupMenu();
+    ok( menu != NULL, "CreatePopupMenu() failed\n");
+    if( pGetMenuInfo) {
+        mi.fMask = MIM_STYLE;
+        ret = pGetMenuInfo( menu, &mi);
+        ok( menu != NULL, "GetMenuInfo() failed\n");
+        ok( 0 == mi.dwStyle, "menuinfo style is %x\n", mi.dwStyle);
+    }
+    /* test 1 */
+    mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID;
+    mii.wID = 1;
+    mii.hbmpItem = hbm1;
+    mii.dwTypeData = (LPSTR) " OK: menu texts are correctly left-aligned.";
+    ret = InsertMenuItem( menu, -1, TRUE, &mii);
+    ok( ret, "InsertMenuItem() failed\n");
+    mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID ;
+    mii.wID = 2;
+    mii.hbmpItem = hbm2;
+    mii.dwTypeData = (LPSTR) " FAIL: menu texts are NOT left-aligned.";
+    ret = InsertMenuItem( menu, -1, TRUE, &mii);
+    ok( ret, "InsertMenuItem() failed\n");
+    ret = TrackPopupMenu( menu, TPM_RETURNCMD, 110, 200, 0, hwnd, NULL);
+    ok( ret != 2, "User indicated that menu text alignment test 1 failed %d\n", ret);
+    /* test 2*/
+    mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID;
+    mii.wID = 3;
+    mii.hbmpItem = hbm3;
+    mii.dwTypeData = NULL;
+    ret = InsertMenuItem( menu, 0, TRUE, &mii);
+    ok( ret, "InsertMenuItem() failed\n");
+    mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID;
+    mii.wID = 1;
+    mii.hbmpItem = hbm1;
+    /* make the text a bit longer, to keep it readable */
+    /* this bug is on winXP and reproduced on wine */
+    mii.dwTypeData = (LPSTR) " OK: menu texts are to the right of the bitmaps........";
+    ret = SetMenuItemInfo( menu, 1, TRUE, &mii);
+    ok( ret, "SetMenuItemInfo() failed\n");
+    mii.wID = 2;
+    mii.hbmpItem = hbm2;
+    mii.dwTypeData = (LPSTR) " FAIL: menu texts are below the first bitmap.  ";
+    ret = SetMenuItemInfo( menu, 2, TRUE, &mii);
+    ok( ret, "SetMenuItemInfo() failed\n");
+    ret = TrackPopupMenu( menu, TPM_RETURNCMD, 110, 200, 0, hwnd, NULL);
+    ok( ret != 2, "User indicated that menu text alignment test 2 failed %d\n", ret);
+    /* test 3 */
+    mii.fMask = MIIM_TYPE | MIIM_ID;
+    mii.wID = 3;
+    mii.fType = MFT_BITMAP;
+    mii.dwTypeData = (LPSTR) hbm3;
+    ret = SetMenuItemInfo( menu, 0, TRUE, &mii);
+    ok( ret, "SetMenuItemInfo() failed\n");
+    mii.fMask = MIIM_BITMAP | MIIM_STRING | MIIM_ID;
+    mii.wID = 1;
+    mii.hbmpItem = NULL;
+    mii.dwTypeData = (LPSTR) " OK: menu texts are below the bitmap.";
+    ret = SetMenuItemInfo( menu, 1, TRUE, &mii);
+    ok( ret, "SetMenuItemInfo() failed\n");
+    mii.wID = 2;
+    mii.hbmpItem = NULL;
+    mii.dwTypeData = (LPSTR) " FAIL: menu texts are NOT below the bitmap.";
+    ret = SetMenuItemInfo( menu, 2, TRUE, &mii);
+    ok( ret, "SetMenuItemInfo() failed\n");
+    ret = TrackPopupMenu( menu, TPM_RETURNCMD, 110, 200, 0, hwnd, NULL);
+    ok( ret != 2, "User indicated that menu text alignment test 3 failed %d\n", ret);
+    /* cleanup */
+    DeleteObject( hbm1);
+    DeleteObject( hbm2);
+    DeleteObject( hbm3);
+    DestroyMenu( menu);
+    DestroyWindow( hwnd);
+}
+
 START_TEST(menu)
 {
     init_function_pointers();
@@ -3082,6 +3185,7 @@ START_TEST(menu)
         test_CheckMenuRadioItem();
         test_menu_resource_layout();
         test_InsertMenu();
+        test_menualign();
     }
 
     register_menu_check_class();




More information about the wine-cvs mailing list