In SetMenuInfo() implement the MIM_APPLYTOSUBMENUS. Also set last error if called with invalid parameters with tests.
Rein Klazes
wijn at online.nl
Fri Feb 27 02:17:58 CST 2009
---
dlls/user32/menu.c | 57 ++++++++++-------
dlls/user32/tests/menu.c | 162 +++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 195 insertions(+), 24 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index d285ef2..bb0ff39 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -5009,45 +5009,55 @@ BOOL WINAPI GetMenuItemRect (HWND hwnd, HMENU hMenu, UINT uItem,
return TRUE;
}
-
/**********************************************************************
* SetMenuInfo (USER32.@)
*
* FIXME
- * MIM_APPLYTOSUBMENUS
* actually use the items to draw the menu
+ * (recalculate and/or redraw)
*/
-BOOL WINAPI SetMenuInfo (HMENU hMenu, LPCMENUINFO lpmi)
+static BOOL menu_SetMenuInfo( HMENU hMenu, LPCMENUINFO lpmi)
{
POPUPMENU *menu;
+ if( !(menu = MENU_GetMenu(hMenu))) return FALSE;
- TRACE("(%p %p)\n", hMenu, lpmi);
+ if (lpmi->fMask & MIM_BACKGROUND)
+ menu->hbrBack = lpmi->hbrBack;
- if (lpmi && (lpmi->cbSize==sizeof(MENUINFO)) && (menu = MENU_GetMenu(hMenu)))
- {
+ if (lpmi->fMask & MIM_HELPID)
+ menu->dwContextHelpID = lpmi->dwContextHelpID;
- if (lpmi->fMask & MIM_BACKGROUND)
- menu->hbrBack = lpmi->hbrBack;
+ if (lpmi->fMask & MIM_MAXHEIGHT)
+ menu->cyMax = lpmi->cyMax;
- if (lpmi->fMask & MIM_HELPID)
- menu->dwContextHelpID = lpmi->dwContextHelpID;
+ if (lpmi->fMask & MIM_MENUDATA)
+ menu->dwMenuData = lpmi->dwMenuData;
- if (lpmi->fMask & MIM_MAXHEIGHT)
- menu->cyMax = lpmi->cyMax;
+ if (lpmi->fMask & MIM_STYLE)
+ menu->dwStyle = lpmi->dwStyle;
- if (lpmi->fMask & MIM_MENUDATA)
- menu->dwMenuData = lpmi->dwMenuData;
+ if( lpmi->fMask & MIM_APPLYTOSUBMENUS) {
+ int i;
+ MENUITEM *item = menu->items;
+ for( i = menu->nItems; i; i--, item++)
+ if( item->fType & MF_POPUP)
+ menu_SetMenuInfo( item->hSubMenu, lpmi);
+ }
+ return TRUE;
+}
- if (lpmi->fMask & MIM_STYLE)
- {
- menu->dwStyle = lpmi->dwStyle;
- if (menu->dwStyle & MNS_AUTODISMISS) FIXME("MNS_AUTODISMISS unimplemented\n");
- if (menu->dwStyle & MNS_DRAGDROP) FIXME("MNS_DRAGDROP unimplemented\n");
- if (menu->dwStyle & MNS_MODELESS) FIXME("MNS_MODELESS unimplemented\n");
+BOOL WINAPI SetMenuInfo (HMENU hMenu, LPCMENUINFO lpmi)
+{
+ TRACE("(%p %p)\n", hMenu, lpmi);
+ if( lpmi && (lpmi->cbSize == sizeof( MENUINFO)) && (menu_SetMenuInfo( hMenu, lpmi))) {
+ if( lpmi->fMask & MIM_STYLE) {
+ if (lpmi->dwStyle & MNS_AUTODISMISS) FIXME("MNS_AUTODISMISS unimplemented\n");
+ if (lpmi->dwStyle & MNS_DRAGDROP) FIXME("MNS_DRAGDROP unimplemented\n");
+ if (lpmi->dwStyle & MNS_MODELESS) FIXME("MNS_MODELESS unimplemented\n");
}
-
- return TRUE;
+ return TRUE;
}
+ SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
@@ -5063,7 +5073,7 @@ BOOL WINAPI GetMenuInfo (HMENU hMenu, LPMENUINFO lpmi)
TRACE("(%p %p)\n", hMenu, lpmi);
- if (lpmi && (menu = MENU_GetMenu(hMenu)))
+ if (lpmi && (lpmi->cbSize == sizeof( MENUINFO)) && (menu = MENU_GetMenu(hMenu)))
{
if (lpmi->fMask & MIM_BACKGROUND)
@@ -5083,6 +5093,7 @@ BOOL WINAPI GetMenuInfo (HMENU hMenu, LPMENUINFO lpmi)
return TRUE;
}
+ SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
diff --git a/dlls/user32/tests/menu.c b/dlls/user32/tests/menu.c
index f5d2bdc..1254ac7 100644
--- a/dlls/user32/tests/menu.c
+++ b/dlls/user32/tests/menu.c
@@ -2432,6 +2432,161 @@ static void test_InsertMenu(void)
#undef compare_menu
}
+static void test_menu_getmenuinfo()
+{
+ HMENU hmenu;
+ MENUINFO mi = {0};
+ BOOL ret;
+ DWORD gle;
+
+ /* create a menu */
+ hmenu = CreateMenu();
+ assert( hmenu);
+ /* test some parameter errors */
+ SetLastError(0xdeadbeef);
+ ret = pGetMenuInfo( hmenu, NULL);
+ gle= GetLastError();
+ ok( !ret, "GetMenuInfo() should have failed\n");
+ ok( gle == ERROR_INVALID_PARAMETER, "GetMenuInfo() error got %u expected %u\n", gle, ERROR_INVALID_PARAMETER);
+ SetLastError(0xdeadbeef);
+ mi.cbSize = 0;
+ ret = pGetMenuInfo( hmenu, &mi);
+ gle= GetLastError();
+ ok( !ret, "GetMenuInfo() should have failed\n");
+ ok( gle == ERROR_INVALID_PARAMETER, "GetMenuInfo() error got %u expected %u\n", gle, ERROR_INVALID_PARAMETER);
+ SetLastError(0xdeadbeef);
+ mi.cbSize = sizeof( MENUINFO);
+ ret = pGetMenuInfo( hmenu, &mi);
+ gle= GetLastError();
+ ok( ret, "GetMenuInfo() should have succeeded\n");
+ ok( gle == 0xdeadbeef, "GetMenuInfo() error got %u\n", gle);
+ SetLastError(0xdeadbeef);
+ mi.cbSize = 0;
+ ret = pGetMenuInfo( NULL, &mi);
+ gle= GetLastError();
+ ok( !ret, "GetMenuInfo() should have failed\n");
+ ok( gle == ERROR_INVALID_PARAMETER, "GetMenuInfo() error got %u expected %u\n", gle, ERROR_INVALID_PARAMETER);
+ /* clean up */
+ DestroyMenu( hmenu);
+ return;
+}
+
+static void test_menu_setmenuinfo()
+{
+ HMENU hmenu, hsubmenu;
+ MENUINFO mi = {0};
+ MENUITEMINFOA mii = {sizeof( MENUITEMINFOA)};
+ BOOL ret;
+ DWORD gle;
+
+ /* create a menu with a submenu */
+ hmenu = CreateMenu();
+ hsubmenu = CreateMenu();
+ assert( hmenu && hsubmenu);
+ mii.fMask = MIIM_SUBMENU;
+ mii.hSubMenu = hsubmenu;
+ ret = InsertMenuItem( hmenu, 0, FALSE, &mii);
+ ok( ret, "InsertMenuItem failed with error %d\n", GetLastError());
+ /* test some parameter errors */
+ SetLastError(0xdeadbeef);
+ ret = pSetMenuInfo( hmenu, NULL);
+ gle= GetLastError();
+ ok( !ret, "SetMenuInfo() should have failed\n");
+ ok( gle == ERROR_INVALID_PARAMETER, "SetMenuInfo() error got %u expected %u\n", gle, ERROR_INVALID_PARAMETER);
+ SetLastError(0xdeadbeef);
+ mi.cbSize = 0;
+ ret = pSetMenuInfo( hmenu, &mi);
+ gle= GetLastError();
+ ok( !ret, "SetMenuInfo() should have failed\n");
+ ok( gle == ERROR_INVALID_PARAMETER, "SetMenuInfo() error got %u expected %u\n", gle, ERROR_INVALID_PARAMETER);
+ SetLastError(0xdeadbeef);
+ mi.cbSize = sizeof( MENUINFO);
+ ret = pSetMenuInfo( hmenu, &mi);
+ gle= GetLastError();
+ ok( ret, "SetMenuInfo() should have succeeded\n");
+ ok( gle == 0xdeadbeef, "SetMenuInfo() error got %u\n", gle);
+ SetLastError(0xdeadbeef);
+ mi.cbSize = 0;
+ ret = pSetMenuInfo( NULL, &mi);
+ gle= GetLastError();
+ ok( !ret, "SetMenuInfo() should have failed\n");
+ ok( gle == ERROR_INVALID_PARAMETER, "SetMenuInfo() error got %u expected %u\n", gle, ERROR_INVALID_PARAMETER);
+ /* functional tests */
+ /* menu and submenu should have the CHECKORBMP style bit cleared */
+ SetLastError(0xdeadbeef);
+ mi.cbSize = sizeof( MENUINFO);
+ mi.fMask = MIM_STYLE;
+ ret = pGetMenuInfo( hmenu, &mi);
+ gle= GetLastError();
+ ok( ret, "GetMenuInfo() should have succeeded\n");
+ ok( gle == 0xdeadbeef, "GetMenuInfo() error got %u\n", gle);
+ ok( !(mi.dwStyle & MNS_CHECKORBMP), "menustyle was not expected to have the MNS_CHECKORBMP flag\n");
+ SetLastError(0xdeadbeef);
+ mi.cbSize = sizeof( MENUINFO);
+ mi.fMask = MIM_STYLE;
+ ret = pGetMenuInfo( hsubmenu, &mi);
+ gle= GetLastError();
+ ok( ret, "GetMenuInfo() should have succeeded\n");
+ ok( gle == 0xdeadbeef, "GetMenuInfo() error got %u\n", gle);
+ ok( !(mi.dwStyle & MNS_CHECKORBMP), "menustyle was not expected to have the MNS_CHECKORBMP flag\n");
+ /* SetMenuInfo() */
+ SetLastError(0xdeadbeef);
+ mi.cbSize = sizeof( MENUINFO);
+ mi.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS;
+ mi.dwStyle = MNS_CHECKORBMP;
+ ret = pSetMenuInfo( hmenu, &mi);
+ gle= GetLastError();
+ ok( ret, "SetMenuInfo() should have succeeded\n");
+ ok( gle == 0xdeadbeef, "SetMenuInfo() error got %u\n", gle);
+ /* Now both menus should have the MNS_CHECKORBMP style bit set */
+ SetLastError(0xdeadbeef);
+ mi.cbSize = sizeof( MENUINFO);
+ mi.fMask = MIM_STYLE;
+ ret = pGetMenuInfo( hmenu, &mi);
+ gle= GetLastError();
+ ok( ret, "GetMenuInfo() should have succeeded\n");
+ ok( gle == 0xdeadbeef, "GetMenuInfo() error got %u\n", gle);
+ ok( mi.dwStyle & MNS_CHECKORBMP, "menustyle was expected to have the MNS_CHECKORBMP flag\n");
+ SetLastError(0xdeadbeef);
+ mi.cbSize = sizeof( MENUINFO);
+ mi.fMask = MIM_STYLE;
+ ret = pGetMenuInfo( hsubmenu, &mi);
+ gle= GetLastError();
+ ok( ret, "GetMenuInfo() should have succeeded\n");
+ ok( gle == 0xdeadbeef, "GetMenuInfo() error got %u\n", gle);
+ ok( mi.dwStyle & MNS_CHECKORBMP, "menustyle was expected to have the MNS_CHECKORBMP flag\n");
+ /* now repeat that without the APPLYTOSUBMENUS flag and another style bit */
+ SetLastError(0xdeadbeef);
+ mi.cbSize = sizeof( MENUINFO);
+ mi.fMask = MIM_STYLE ;
+ mi.dwStyle = MNS_NOCHECK;
+ ret = pSetMenuInfo( hmenu, &mi);
+ gle= GetLastError();
+ ok( ret, "SetMenuInfo() should have succeeded\n");
+ ok( gle == 0xdeadbeef, "SetMenuInfo() error got %u\n", gle);
+ /* Now only the top menu should have the MNS_NOCHECK style bit set */
+ SetLastError(0xdeadbeef);
+ mi.cbSize = sizeof( MENUINFO);
+ mi.fMask = MIM_STYLE;
+ ret = pGetMenuInfo( hmenu, &mi);
+ gle= GetLastError();
+ ok( ret, "GetMenuInfo() should have succeeded\n");
+ ok( gle == 0xdeadbeef, "GetMenuInfo() error got %u\n", gle);
+ ok( mi.dwStyle & MNS_NOCHECK, "menustyle was expected to have the MNS_NOCHECK flag\n");
+ SetLastError(0xdeadbeef);
+ mi.cbSize = sizeof( MENUINFO);
+ mi.fMask = MIM_STYLE;
+ ret = pGetMenuInfo( hsubmenu, &mi);
+ gle= GetLastError();
+ ok( ret, "GetMenuInfo() should have succeeded\n");
+ ok( gle == 0xdeadbeef, "GetMenuInfo() error got %u\n", gle);
+ ok( !(mi.dwStyle & MNS_NOCHECK), "menustyle was not expected to have the MNS_NOCHECK flag\n");
+ /* clean up */
+ DestroyMenu( hsubmenu);
+ DestroyMenu( hmenu);
+ return;
+}
+
START_TEST(menu)
{
init_function_pointers();
@@ -2454,7 +2609,12 @@ START_TEST(menu)
test_menu_locked_by_window();
test_menu_ownerdraw();
test_menu_bmp_and_string();
-
+ /* test Get/SetMenuInfo if available */
+ if( pGetMenuInfo && pSetMenuInfo) {
+ test_menu_getmenuinfo();
+ test_menu_setmenuinfo();
+ } else
+ win_skip("Get/SetMenuInfo are not available\n");
if( !pSendInput)
win_skip("SendInput is not available\n");
else
--
1.6.1.3
--------------030106070601070007080205--
More information about the wine-patches
mailing list