user32: make menu tests pass on Win 9x/ME
Rein Klazes
wijn at wanadoo.nl
Thu Jan 12 11:03:41 CST 2006
hi,
Reducing the 500+ failures to zero.
Changelog:
dlls/user : menu.c
dlls/user/tests : menu.c
- make menu tests pass on Win9x/ME;
- rename the macro IS_STRING_ITEM to IS_STRING_ITEM_ONLY, which better
reflects what it is doing: absence of other item type flags.
Rein.
-------------- next part --------------
--- wine/dlls/user/menu.c 2006-01-12 09:56:15.000000000 +0100
+++ mywine/dlls/user/menu.c 2006-01-12 16:20:06.000000000 +0100
@@ -26,6 +26,11 @@
* have been selected, i.e. their popup menu is currently displayed.
* This is probably not the meaning this style has in MS-Windows.
*
+ * Note 2: where there is a difference, these menu API's are according
+ * the behavior of Windows 2k and Windows XP. Known differences with
+ * Windows 9x/ME are documented in the comments, in case an application
+ * is found to depend on the old behavior.
+ *
* TODO:
* implements styles :
* - MNS_AUTODISMISS
@@ -147,7 +152,8 @@ typedef struct
#define MENU_ITEM_TYPE(flags) \
((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR))
-#define IS_STRING_ITEM(flags) (MENU_ITEM_TYPE ((flags)) == MF_STRING)
+/* macro to test that flags do not indicate bitmap, ownerdraw or separator */
+#define IS_STRING_ITEM_ONLY(flags) (MENU_ITEM_TYPE ((flags)) == MF_STRING)
#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
#define IS_SYSTEM_MENU(menu) \
@@ -1003,7 +1009,7 @@ static void MENU_PopupMenuCalcSize( LPPO
if (lpitem->fType & MF_MENUBARBREAK) orgX++;
maxX = max( maxX, lpitem->rect.right );
orgY = lpitem->rect.bottom;
- if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab)
+ if (IS_STRING_ITEM_ONLY(lpitem->fType) && lpitem->xTab)
{
maxTab = max( maxTab, lpitem->xTab );
maxTabWidth = max(maxTabWidth,lpitem->rect.right-lpitem->xTab);
@@ -1015,7 +1021,7 @@ static void MENU_PopupMenuCalcSize( LPPO
for (lpitem = &lppop->items[start]; start < i; start++, lpitem++)
{
lpitem->rect.right = maxX;
- if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab)
+ if (IS_STRING_ITEM_ONLY(lpitem->fType) && lpitem->xTab)
lpitem->xTab = maxTab;
}
@@ -1722,7 +1728,7 @@ static BOOL MENU_SetItemData( MENUITEM *
debug_print_menuitem("MENU_SetItemData from: ", item, "");
TRACE("flags=%x str=%p\n", flags, str);
- if (IS_STRING_ITEM(flags))
+ if (IS_STRING_ITEM_ONLY(flags))
{
LPWSTR prevText = item->text;
if (!str)
@@ -3404,7 +3410,7 @@ BOOL WINAPI InsertMenuW( HMENU hMenu, UI
{
MENUITEM *item;
- if (IS_STRING_ITEM(flags) && str)
+ if (IS_STRING_ITEM_ONLY(flags) && str)
TRACE("hMenu %p, pos %d, flags %08x, id %04x, str %s\n",
hMenu, pos, flags, id, debugstr_w(str) );
else TRACE("hMenu %p, pos %d, flags %08x, id %04x, str %p (not a string)\n",
@@ -3434,7 +3440,7 @@ BOOL WINAPI InsertMenuA( HMENU hMenu, UI
{
BOOL ret = FALSE;
- if (IS_STRING_ITEM(flags) && str)
+ if (IS_STRING_ITEM_ONLY(flags) && str)
{
INT len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
LPWSTR newstr = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
@@ -3528,7 +3534,7 @@ BOOL WINAPI ModifyMenuW( HMENU hMenu, UI
{
MENUITEM *item;
- if (IS_STRING_ITEM(flags))
+ if (IS_STRING_ITEM_ONLY(flags))
TRACE("%p %d %04x %04x %s\n", hMenu, pos, flags, id, debugstr_w(str) );
else
TRACE("%p %d %04x %04x %p\n", hMenu, pos, flags, id, str );
@@ -3547,7 +3553,7 @@ BOOL WINAPI ModifyMenuA( HMENU hMenu, UI
{
BOOL ret = FALSE;
- if (IS_STRING_ITEM(flags) && str)
+ if (IS_STRING_ITEM_ONLY(flags) && str)
{
INT len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
LPWSTR newstr = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
@@ -4076,16 +4082,19 @@ static BOOL GetMenuItemInfo_common ( HME
if( lpmii->fMask & MIIM_TYPE) {
if( lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) {
+ WARN("invalid combination of fMask bits used\n");
+ /* this does not happen on Win9x/ME */
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
lpmii->fType = menu->fType & ~MF_POPUP;
if( menu->hbmpItem) lpmii->fType |= MFT_BITMAP;
- lpmii->hbmpItem = menu->hbmpItem;
+ lpmii->hbmpItem = menu->hbmpItem; /* not on Win9x/ME */
if( lpmii->fType & MFT_BITMAP) {
lpmii->dwTypeData = (LPWSTR) menu->hbmpItem;
lpmii->cch = 0;
} else if( lpmii->fType & (MFT_OWNERDRAW | MFT_SEPARATOR)) {
+ /* this does not happen on Win9x/ME */
lpmii->dwTypeData = 0;
lpmii->cch = 0;
}
@@ -4124,8 +4133,11 @@ static BOOL GetMenuItemInfo_common ( HME
lpmii->cch--;
else
lpmii->cch = len;
- else /* return length of string */
+ else {
+ /* return length of string */
+ /* not on Win9x/ME if fType & MFT_BITMAP */
lpmii->cch = len;
+ }
}
}
@@ -4143,8 +4155,11 @@ static BOOL GetMenuItemInfo_common ( HME
if (lpmii->fMask & MIIM_SUBMENU)
lpmii->hSubMenu = menu->hSubMenu;
- else
- lpmii->hSubMenu = 0; /* hSubMenu is always cleared */
+ else {
+ /* hSubMenu is always cleared
+ * (not on Win9x/ME ) */
+ lpmii->hSubMenu = 0;
+ }
if (lpmii->fMask & MIIM_CHECKMARKS) {
lpmii->hbmpChecked = menu->hCheckBit;
@@ -4230,10 +4245,12 @@ static BOOL SetMenuItemInfo_common(MENUI
{
if (!menu) return FALSE;
- debug_print_menuitem("MENU_SetItemInfo_common from: ", menu, "");
+ debug_print_menuitem("SetmenuItemInfo_common from: ", menu, "");
if (lpmii->fMask & MIIM_TYPE ) {
if( lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) {
+ WARN("invalid combination of fMask bits used\n");
+ /* this does not happen on Win9x/ME */
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
@@ -4241,7 +4258,7 @@ static BOOL SetMenuItemInfo_common(MENUI
menu->fType &= ~MENU_ITEM_TYPE(menu->fType);
menu->fType |= MENU_ITEM_TYPE(lpmii->fType);
- if (IS_STRING_ITEM(menu->fType)) {
+ if (IS_STRING_ITEM_ONLY(menu->fType)) {
HeapFree(GetProcessHeap(), 0, menu->text);
set_menu_item_text( menu, lpmii->dwTypeData, unicode );
} else if( (menu->fType) & MFT_BITMAP)
--- wine/dlls/user/tests/menu.c 2006-01-12 09:56:18.000000000 +0100
+++ mywine/dlls/user/tests/menu.c 2006-01-12 17:36:21.000000000 +0100
@@ -32,6 +32,7 @@
#include "wine/test.h"
+static int iswin9x;
static ATOM atomMenuCheckClass;
static LRESULT WINAPI menu_check_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
@@ -251,11 +252,27 @@ static void test_menu_ownerdraw(void)
DestroyWindow(hwnd);
}
+/* Is this a system with old style menu info options (win95, NT4 or older) ?
+ * old means here: does not support MIIM_STRING */
+static BOOL sysoldmenustyle( void)
+{
+ MENUITEMINFOA mi;
+ HMENU hmenu = CreateMenu();
+ BOOL ret;
+ mi.cbSize = sizeof( mi);
+ mi.fMask = MIIM_STRING;
+ mi.dwTypeData = "hi";
+ ret = InsertMenuItemA(hmenu, 0, TRUE, &mi );
+ DestroyMenu( hmenu );
+ return ret == FALSE;
+}
+
static void test_menu_add_string( void )
{
HMENU hmenu;
MENUITEMINFO info;
BOOL rc;
+ INT ret;
char string[0x80];
char string2[0x80];
@@ -265,6 +282,8 @@ static void test_menu_add_string( void )
static const WCHAR expectedString[] = {'D', 'u', 'm', 'm', 'y', ' ',
's', 't', 'r', 'i', 'n', 'g', 0};
+ if( sysoldmenustyle()) return; /* these tests are no use on such old systems */
+
hmenu = CreateMenu();
memset( &info, 0, sizeof info );
@@ -300,10 +319,12 @@ static void test_menu_add_string( void )
strcpy(string,"Garbage");
ok (GetMenuString( hmenu, 0, strback, 99, MF_BYPOSITION), "GetMenuString on ownerdraw entry failed\n");
ok (!strcmp( strback, "Dummy string" ), "Menu text from Ansi version incorrect\n");
-
- ok (GetMenuStringW( hmenu, 0, (WCHAR *)strbackW, 99, MF_BYPOSITION), "GetMenuStringW on ownerdraw entry failed\n");
- ok (!lstrcmpW( strbackW, expectedString ), "Menu text from Unicode version incorrect\n");
-
+ SetLastError( 0xdeadbeef);
+ ret = GetMenuStringW( hmenu, 0, (WCHAR *)strbackW, 99, MF_BYPOSITION);
+ if( GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
+ ok (ret, "GetMenuStringW on ownerdraw entry failed\n");
+ ok (!lstrcmpW( strbackW, expectedString ), "Menu text from Unicode version incorrect\n");
+ }
/* Just change ftype to string and see what text is stored */
memset(&info, 0x00, sizeof(info));
info.cbSize= sizeof(MENUITEMINFO);
@@ -324,7 +345,7 @@ static void test_menu_add_string( void )
info.fType= MFT_BITMAP;
info.dwTypeData= (char *)0xdeadbee2;
rc = SetMenuItemInfo( hmenu, 0, TRUE, &info );
- ok (!rc, "SetMenuItemInfo unexpectedly worked\n");
+ ok (!rc || iswin9x, "SetMenuItemInfo unexpectedly worked\n");
/* Just change ftype back and ensure data hasnt been freed */
info.fType= MFT_OWNERDRAW; /* Set as ownerdraw type */
@@ -379,7 +400,7 @@ static WCHAR *strcpyW( WCHAR *dst, cons
return dst;
}
-
+/* i is item info, e is expected item info */
#define DMIINFF( i, e, field)\
ok((int)((i)->field)==(int)((e)->field) || (int)((i)->field)==(0xffff & (int)((e)->field)), \
"%s got 0x%x expected 0x%x\n", #field, (int)((i)->field), (int)((e)->field));
@@ -387,16 +408,21 @@ static WCHAR *strcpyW( WCHAR *dst, cons
#define DUMPMIINF(s,i,e)\
{\
DMIINFF( i, e, fMask)\
- DMIINFF( i, e, fType)\
+ if( !iswin9x || !(((i)->fMask & MIIM_FTYPE) && ((e)->fType & MFT_BITMAP)))\
+ DMIINFF( i, e, fType)\
DMIINFF( i, e, fState)\
DMIINFF( i, e, wID)\
- DMIINFF( i, e, hSubMenu)\
+ if( ((e)->hSubMenu) || !iswin9x) DMIINFF( i, e, hSubMenu)\
DMIINFF( i, e, hbmpChecked)\
DMIINFF( i, e, hbmpUnchecked)\
DMIINFF( i, e, dwItemData)\
- DMIINFF( i, e, dwTypeData)\
- DMIINFF( i, e, cch)\
- if( s==sizeof(MENUITEMINFOA)) DMIINFF( i, e, hbmpItem)\
+ if( !iswin9x || !(((i)->fMask & MIIM_TYPE) && \
+ ((i)->fType & (MFT_SEPARATOR | MFT_OWNERDRAW))))\
+ DMIINFF( i, e, dwTypeData)\
+ if( !iswin9x || !((i)->fType & MFT_BITMAP) || (i)->cch)\
+ DMIINFF( i, e, cch)\
+ if( s==sizeof(MENUITEMINFOA)) \
+ if( !( iswin9x && ((i)->fMask & MIIM_TYPE))) DMIINFF( i, e, hbmpItem)\
}
/* insert menu item */
@@ -411,9 +437,12 @@ static WCHAR *strcpyW( WCHAR *dst, cons
else strcpyW( (WCHAR*)string, (WCHAR*)init);\
if( ansi) ret = InsertMenuItemA(hmenu, 0, TRUE, &info1 );\
else ret = InsertMenuItemW(hmenu, 0, TRUE, (MENUITEMINFOW*)&info1 );\
- if( !(eret1)) { ok( (eret1)==ret,"InsertMenuItem should have failed.\n");\
+ if( ansi || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {\
+ if( !(eret1)) {\
+ ok( (eret1)==ret || iswin9x,"InsertMenuItem should have failed.\n");\
stop = TRUE;\
- } else ok( (eret1)==ret,"InsertMenuItem failed, err %ld\n",GetLastError());\
+ } else ok( (eret1)==ret,"InsertMenuItem failed, err %ld\n",GetLastError());\
+ }
/* GetMenuItemInfo + GetMenuString */
@@ -429,7 +458,7 @@ static WCHAR *strcpyW( WCHAR *dst, cons
if( !stop) {\
ret = ansi ? GetMenuItemInfoA( hmenu, 0, TRUE, info2 ) :\
GetMenuItemInfoW( hmenu, 0, TRUE, info2W );\
- if( !(eret2)) ok( (eret2)==ret,"GetMenuItemInfo should have failed.\n");\
+ if( !(eret2)) ok( (eret2)==ret || iswin9x,"GetMenuItemInfo should have failed.\n");\
else { \
ok( (eret2)==ret,"GetMenuItemInfo failed, err %ld\n",GetLastError());\
ret = memcmp( info2, einfo, sizeof einfoA);\
@@ -455,7 +484,7 @@ static WCHAR *strcpyW( WCHAR *dst, cons
RemoveMenu(hmenu, 0, TRUE );\
DestroyMenu( hmenu );\
DestroyMenu( submenu );\
-submenu = CreateMenu();\
+ submenu = CreateMenu();\
}
/* modify menu */
#define TMII_MODM( flags, id, data, eret )\
@@ -482,11 +511,9 @@ if( !stop) {\
}
-
#define OK 1
#define ER 0
-
static void test_menu_iteminfo( )
{
int S=sizeof( MENUITEMINFOA);
@@ -501,14 +528,18 @@ static void test_menu_iteminfo( )
HBITMAP hbm = CreateBitmap(1,1,1,1,NULL);
char stringA[0x80];
HMENU submenu=CreateMenu();
-
- do {
+
+ if( !sysoldmenustyle()) do {
if( ansi) {txt=txtA;init=initA;empty=emptyA;string=stringA;}
else {txt=txtW;init=initW;empty=emptyW;string=stringA;}
trace( "%s string %p hbm %p txt %p\n", ansi ? "ANSI tests: " : "Unicode tests:", string, hbm, txt);
/* test all combinations of MFT_STRING, MFT_OWNERDRAW and MFT_BITMAP */
/* (since MFT_STRING is zero, there are four of them) */
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, 0, 0, 0, 0, 0, 0, txt, 0, 0, }, OK)
+ if( !ansi && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
+ trace( "Unicode calls not implemented on this platform, skipping ...\n");
+ continue;
+ }
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, 0, },
txt, OK, OK )
@@ -881,13 +912,14 @@ static void test_menu_iteminfo( )
txt, OK, OK )
TMII_DONE
- ansi = !ansi;
- } while( !ansi);
+ } while( !(ansi = !ansi) );
DeleteObject( hbm);
}
START_TEST(menu)
{
+ iswin9x = GetVersion() & 0x80000000;
+
register_menu_check_class();
test_menu_locked_by_window();
More information about the wine-patches
mailing list