user32: When all items in a menu have either a bitmap or text but not both, then texts should be aligned with the bitmaps.
Rein Klazes
wijn at online.nl
Mon Jul 27 01:20:58 CDT 2009
Test is interactive only. Fixes bug #13350.
---
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 5311b43..3b90169 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..ae1de23 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) */
+void test_menualign()
+{
+ 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();
--
1.6.3.3
More information about the wine-patches
mailing list