user32: Separate menu bitmaps and strings.

Store bitmaps and bitmaps always in separate fields in the internal
menu structure.  Get rid of a lot of assumptions in the code that the
menu can have strings only when it is not some other type and that
bitmaps come in two flavors.
Add a lot of conformance tests, including some submitted by Jason
Edmeades.
This commit is contained in:
Rein Klazes 2006-01-03 13:23:28 +01:00 committed by Alexandre Julliard
parent f824852b26
commit b34868dffa
2 changed files with 786 additions and 126 deletions

View File

@ -72,10 +72,10 @@ typedef struct {
HMENU hSubMenu; /* Pop-up menu. */
HBITMAP hCheckBit; /* Bitmap when checked. */
HBITMAP hUnCheckBit; /* Bitmap when unchecked. */
LPWSTR text; /* Item text or bitmap handle. */
LPWSTR text; /* Item text. */
ULONG_PTR dwItemData; /* Application defined. */
LPWSTR dwTypeData; /* depends on fMask */
HBITMAP hbmpItem; /* bitmap in win98 style menus */
HBITMAP hbmpItem; /* bitmap */
/* ----------- Wine stuff ----------- */
RECT rect; /* Item area (relative to menu window) */
UINT xTab; /* X position of text after Tab */
@ -148,8 +148,7 @@ typedef struct
((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR))
#define IS_STRING_ITEM(flags) (MENU_ITEM_TYPE ((flags)) == MF_STRING)
#define IS_BITMAP_ITEM(flags) (MENU_ITEM_TYPE ((flags)) == MF_BITMAP)
#define IS_MAGIC_ITEM(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
#define IS_SYSTEM_MENU(menu) \
(!((menu)->wFlags & MF_POPUP) && ((menu)->wFlags & MF_SYSMENU))
@ -612,8 +611,7 @@ UINT MENU_FindSubMenu( HMENU *hmenu, HMENU hSubTarget )
static void MENU_FreeItemData( MENUITEM* item )
{
/* delete text */
if (IS_STRING_ITEM(item->fType) && item->text)
HeapFree( GetProcessHeap(), 0, item->text );
HeapFree( GetProcessHeap(), 0, item->text );
}
/***********************************************************************
@ -671,7 +669,7 @@ static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu,
for (i = 0; i < menu->nItems; i++, item++)
{
if (IS_STRING_ITEM(item->fType) && item->text)
if( item->text)
{
WCHAR *p = item->text - 2;
do
@ -740,22 +738,22 @@ static void MENU_GetBitmapItemSize( HBITMAP bmp, DWORD data, SIZE *size )
* MENU_DrawBitmapItem
*
* Draw a bitmap item.
* drawhbmbitmap : True to draw the hbmbitmap(MIIM_BITMAP)/False to draw the MF_BITMAP
*/
static void MENU_DrawBitmapItem( HDC hdc, MENUITEM *lpitem, const RECT *rect, BOOL menuBar, BOOL drawhbmbitmap )
static void MENU_DrawBitmapItem( HDC hdc, MENUITEM *lpitem, const RECT *rect, BOOL menuBar)
{
BITMAP bm;
DWORD rop;
HDC hdcMem;
HBITMAP bmp = (HBITMAP)lpitem->text;
HBITMAP bmp;
int w = rect->right - rect->left;
int h = rect->bottom - rect->top;
int bmp_xoffset = 0;
int left, top;
HBITMAP hbmToDraw = (drawhbmbitmap)?lpitem->hbmpItem:(HBITMAP)lpitem->text;
HBITMAP hbmToDraw = lpitem->hbmpItem;
bmp = hbmToDraw;
/* Check if there is a magic menu item associated with this item */
if (IS_MAGIC_ITEM(hbmToDraw))
if (IS_MAGIC_BITMAP(hbmToDraw))
{
UINT flags = 0;
RECT r;
@ -820,8 +818,8 @@ static void MENU_DrawBitmapItem( HDC hdc, MENUITEM *lpitem, const RECT *rect, BO
/* handle fontsize > bitmap_height */
top = (h>bm.bmHeight) ? rect->top+(h-bm.bmHeight)/2 : rect->top;
left=rect->left;
rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_ITEM(hbmToDraw)) ? NOTSRCCOPY : SRCCOPY;
if ((lpitem->fState & MF_HILITE) && IS_BITMAP_ITEM(lpitem->fType))
rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmToDraw)) ? NOTSRCCOPY : SRCCOPY;
if ((lpitem->fState & MF_HILITE) && lpitem->hbmpItem)
SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
BitBlt( hdc, left, top, w, h, hdcMem, bmp_xoffset, 0, rop );
DeleteDC( hdcMem );
@ -892,7 +890,6 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
if (!menuBar)
{
/* New style MIIM_BITMAP */
if (lpitem->hbmpItem)
{
if (lpitem->hbmpItem == HBMMENU_CALLBACK)
@ -927,13 +924,11 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
lpitem->rect.right += 2 * check_bitmap_width;
if (lpitem->fType & MF_POPUP)
lpitem->rect.right += arrow_bitmap_width;
}
if (IS_BITMAP_ITEM(lpitem->fType))
} else if (lpitem->hbmpItem)
{
SIZE size;
MENU_GetBitmapItemSize( (HBITMAP) lpitem->text, lpitem->dwItemData, &size );
MENU_GetBitmapItemSize( (HBITMAP) lpitem->hbmpItem, lpitem->dwItemData, &size );
lpitem->rect.right += size.cx;
lpitem->rect.bottom += size.cy;
/* Leave space for the sunken border */
@ -941,9 +936,8 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
lpitem->rect.bottom += 2;
}
/* it must be a text item - unless it's the system menu */
if (!(lpitem->fType & MF_SYSMENU) && IS_STRING_ITEM( lpitem->fType ))
if (!(lpitem->fType & MF_SYSMENU) && lpitem->text)
{ SIZE size;
GetTextExtentPoint32W(hdc, lpitem->text, strlenW(lpitem->text), &size);
@ -1303,7 +1297,6 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
{
RECT rc;
rc = rect;
/* New style MIIM_BITMAP */
if (lpitem->hbmpItem)
{
POPUPMENU *menu = MENU_GetMenu(hmenu);
@ -1342,7 +1335,6 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
DeleteDC( hdcMem );
DeleteObject( bm );
}
/* New style MIIM_BITMAP */
if (lpitem->hbmpItem)
{
HBITMAP hbm = lpitem->hbmpItem;
@ -1371,7 +1363,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
} else {
MENU_DrawBitmapItem(hdc, lpitem, &rect, FALSE, TRUE);
MENU_DrawBitmapItem(hdc, lpitem, &rect, FALSE);
}
}
}
@ -1394,19 +1386,15 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
rect.left += check_bitmap_width;
rect.right -= arrow_bitmap_width;
}
else if( lpitem->hbmpItem && !(lpitem->fType & MF_OWNERDRAW))
{ /* Draw the bitmap */
MENU_DrawBitmapItem( hdc, lpitem, &rect, menuBar);
}
/* Done for owner-drawn */
if (lpitem->fType & MF_OWNERDRAW)
return;
/* Draw the item text or bitmap */
if (IS_BITMAP_ITEM(lpitem->fType))
{
MENU_DrawBitmapItem( hdc, lpitem, &rect, menuBar, FALSE);
return;
}
/* No bitmap - process text if present */
else if (IS_STRING_ITEM(lpitem->fType))
/* process text if present */
if (lpitem->text)
{
register int i;
HFONT hfontOld = 0;
@ -1745,13 +1733,12 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset )
static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT_PTR id,
LPCWSTR str )
{
LPWSTR prevText = IS_STRING_ITEM(item->fType) ? item->text : NULL;
debug_print_menuitem("MENU_SetItemData from: ", item, "");
TRACE("flags=%x str=%p\n", flags, str);
if (IS_STRING_ITEM(flags))
{
LPWSTR prevText = item->text;
if (!str)
{
flags |= MF_SEPARATOR;
@ -1771,10 +1758,15 @@ static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT_PTR id,
strcpyW( text, str );
item->text = text;
}
item->hbmpItem = NULL;
HeapFree( GetProcessHeap(), 0, prevText );
}
else if(( flags & MFT_BITMAP)) {
item->hbmpItem = HBITMAP_32(LOWORD(str));
/* setting bitmap clears text */
HeapFree( GetProcessHeap(), 0, item->text );
item->text = NULL;
}
else if (IS_BITMAP_ITEM(flags))
item->text = (LPWSTR)HBITMAP_32(LOWORD(str));
else item->text = NULL;
if (flags & MF_OWNERDRAW)
item->dwItemData = (DWORD_PTR)str;
@ -1808,12 +1800,8 @@ static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT_PTR id,
item->fState = (flags & STATE_MASK) &
~(MF_HILITE | MF_MOUSESELECT | MF_BYPOSITION);
/* Don't call SetRectEmpty here! */
HeapFree( GetProcessHeap(), 0, prevText );
debug_print_menuitem("MENU_SetItemData to : ", item, "");
return TRUE;
}
@ -3318,8 +3306,10 @@ INT WINAPI GetMenuStringA(
TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, wItemID, str, nMaxSiz, wFlags );
if (str && nMaxSiz) str[0] = '\0';
if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return 0;
if (!IS_STRING_ITEM(item->fType)) return 0;
if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) {
SetLastError( ERROR_MENU_ITEM_NOT_FOUND);
return 0;
}
if (!str || !nMaxSiz) return strlenW(item->text);
if (!WideCharToMultiByte( CP_ACP, 0, item->text, -1, str, nMaxSiz, NULL, NULL ))
str[nMaxSiz-1] = 0;
@ -3338,9 +3328,15 @@ INT WINAPI GetMenuStringW( HMENU hMenu, UINT wItemID,
TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, wItemID, str, nMaxSiz, wFlags );
if (str && nMaxSiz) str[0] = '\0';
if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return 0;
if (!IS_STRING_ITEM(item->fType)) return 0;
if (!str || !nMaxSiz) return strlenW(item->text);
if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) {
SetLastError( ERROR_MENU_ITEM_NOT_FOUND);
return 0;
}
if (!str || !nMaxSiz) return item->text ? strlenW(item->text) : 0;
if( !(item->text)) {
str[0] = 0;
return 0;
}
lstrcpynW( str, item->text, nMaxSiz );
return strlenW(str);
}
@ -4095,51 +4091,64 @@ static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
if (!menu)
return FALSE;
if (lpmii->fMask & MIIM_TYPE) {
lpmii->fType = menu->fType;
switch (MENU_ITEM_TYPE(menu->fType)) {
case MF_STRING:
break; /* will be done below */
case MF_OWNERDRAW:
case MF_BITMAP:
lpmii->dwTypeData = menu->text;
/* fall through */
default:
if( lpmii->fMask & MIIM_TYPE) {
if( lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) {
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
lpmii->fType = menu->fType & ~MF_POPUP;
if( menu->hbmpItem) lpmii->fType |= MFT_BITMAP;
lpmii->hbmpItem = menu->hbmpItem;
if( lpmii->fType & MFT_BITMAP) {
lpmii->dwTypeData = (LPWSTR) menu->hbmpItem;
lpmii->cch = 0;
}
} else if( lpmii->fType & (MFT_OWNERDRAW | MFT_SEPARATOR)) {
lpmii->dwTypeData = 0;
lpmii->cch = 0;
}
}
/* copy the text string */
if ((lpmii->fMask & (MIIM_TYPE|MIIM_STRING)) &&
(MENU_ITEM_TYPE(menu->fType) == MF_STRING) && menu->text)
{
int len;
if (unicode)
{
len = strlenW(menu->text);
if ((lpmii->fMask & (MIIM_TYPE|MIIM_STRING))) {
if( !menu->text ) {
if(lpmii->dwTypeData && lpmii->cch) {
lpmii->cch = 0;
if( unicode)
*((WCHAR *)lpmii->dwTypeData) = 0;
else
*((CHAR *)lpmii->dwTypeData) = 0;
}
} else {
int len;
if (unicode)
{
len = strlenW(menu->text);
if(lpmii->dwTypeData && lpmii->cch)
lstrcpynW(lpmii->dwTypeData, menu->text, lpmii->cch);
}
else
{
len = WideCharToMultiByte( CP_ACP, 0, menu->text, -1, NULL,
0, NULL, NULL ) - 1;
if(lpmii->dwTypeData && lpmii->cch)
if (!WideCharToMultiByte( CP_ACP, 0, menu->text, -1,
(LPSTR)lpmii->dwTypeData, lpmii->cch, NULL, NULL ))
((LPSTR)lpmii->dwTypeData)[lpmii->cch - 1] = 0;
}
/* if we've copied a substring we return its length */
if(lpmii->dwTypeData && lpmii->cch)
lstrcpynW(lpmii->dwTypeData, menu->text, lpmii->cch);
if (lpmii->cch <= len + 1)
lpmii->cch--;
else
lpmii->cch = len;
else /* return length of string */
lpmii->cch = len;
}
else
{
len = WideCharToMultiByte( CP_ACP, 0, menu->text, -1, NULL, 0, NULL, NULL );
if(lpmii->dwTypeData && lpmii->cch)
if (!WideCharToMultiByte( CP_ACP, 0, menu->text, -1,
(LPSTR)lpmii->dwTypeData, lpmii->cch, NULL, NULL ))
((LPSTR)lpmii->dwTypeData)[lpmii->cch-1] = 0;
}
/* if we've copied a substring we return its length */
if(lpmii->dwTypeData && lpmii->cch)
{
if (lpmii->cch <= len) lpmii->cch--;
}
else /* return length of string */
lpmii->cch = len;
}
if (lpmii->fMask & MIIM_FTYPE)
lpmii->fType = menu->fType;
lpmii->fType = menu->fType & ~MF_POPUP;
if (lpmii->fMask & MIIM_BITMAP)
lpmii->hbmpItem = menu->hbmpItem;
@ -4152,6 +4161,8 @@ static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
if (lpmii->fMask & MIIM_SUBMENU)
lpmii->hSubMenu = menu->hSubMenu;
else
lpmii->hSubMenu = 0; /* hSubMenu is always cleared */
if (lpmii->fMask & MIIM_CHECKMARKS) {
lpmii->hbmpChecked = menu->hCheckBit;
@ -4169,8 +4180,20 @@ static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
BOOL WINAPI GetMenuItemInfoA( HMENU hmenu, UINT item, BOOL bypos,
LPMENUITEMINFOA lpmii)
{
return GetMenuItemInfo_common (hmenu, item, bypos,
(LPMENUITEMINFOW)lpmii, FALSE);
BOOL ret;
MENUITEMINFOA mii;
if( lpmii->cbSize != sizeof( mii) &&
lpmii->cbSize != sizeof( mii) - sizeof ( mii.hbmpItem)) {
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
memcpy( &mii, lpmii, lpmii->cbSize);
mii.cbSize = sizeof( mii);
ret = GetMenuItemInfo_common (hmenu, item, bypos,
(LPMENUITEMINFOW)&mii, FALSE);
mii.cbSize = lpmii->cbSize;
memcpy( lpmii, &mii, mii.cbSize);
return ret;
}
/**********************************************************************
@ -4179,8 +4202,19 @@ BOOL WINAPI GetMenuItemInfoA( HMENU hmenu, UINT item, BOOL bypos,
BOOL WINAPI GetMenuItemInfoW( HMENU hmenu, UINT item, BOOL bypos,
LPMENUITEMINFOW lpmii)
{
return GetMenuItemInfo_common (hmenu, item, bypos,
lpmii, TRUE);
BOOL ret;
MENUITEMINFOW mii;
if( lpmii->cbSize != sizeof( mii) &&
lpmii->cbSize != sizeof( mii) - sizeof ( mii.hbmpItem)) {
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
memcpy( &mii, lpmii, lpmii->cbSize);
mii.cbSize = sizeof( mii);
ret = GetMenuItemInfo_common (hmenu, item, bypos, &mii, TRUE);
mii.cbSize = lpmii->cbSize;
memcpy( lpmii, &mii, mii.cbSize);
return ret;
}
@ -4188,10 +4222,7 @@ BOOL WINAPI GetMenuItemInfoW( HMENU hmenu, UINT item, BOOL bypos,
inline static void set_menu_item_text( MENUITEM *menu, LPCWSTR text, BOOL unicode )
{
if (!text)
{
menu->text = NULL;
menu->fType |= MF_SEPARATOR;
}
else if (unicode)
{
if ((menu->text = HeapAlloc( GetProcessHeap(), 0, (strlenW(text)+1) * sizeof(WCHAR) )))
@ -4220,43 +4251,33 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu,
debug_print_menuitem("MENU_SetItemInfo_common from: ", menu, "");
if (lpmii->fMask & MIIM_TYPE ) {
/* Get rid of old string. */
if (IS_STRING_ITEM(menu->fType) && menu->text) {
HeapFree(GetProcessHeap(), 0, menu->text);
menu->text = NULL;
}
if( lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) {
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);
if (IS_STRING_ITEM(menu->fType))
if (IS_STRING_ITEM(menu->fType)) {
HeapFree(GetProcessHeap(), 0, menu->text);
set_menu_item_text( menu, lpmii->dwTypeData, unicode );
else
menu->text = lpmii->dwTypeData;
} else if( (menu->fType) & MFT_BITMAP)
menu->hbmpItem = (HBITMAP)lpmii->dwTypeData;
}
if (lpmii->fMask & MIIM_FTYPE ) {
/* free the string when the type is changing */
if ( (!IS_STRING_ITEM(lpmii->fType)) && IS_STRING_ITEM(menu->fType) && menu->text) {
HeapFree(GetProcessHeap(), 0, menu->text);
menu->text = NULL;
}
if(( lpmii->fType & MFT_BITMAP)) {
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
menu->fType &= ~MENU_ITEM_TYPE(menu->fType);
menu->fType |= MENU_ITEM_TYPE(lpmii->fType);
if (IS_STRING_ITEM(menu->fType))
set_menu_item_text( menu, lpmii->dwTypeData, unicode );
else
menu->text = lpmii->dwTypeData;
}
if (lpmii->fMask & MIIM_STRING ) {
if (IS_STRING_ITEM(menu->fType)) {
/* free the string when used */
HeapFree(GetProcessHeap(), 0, menu->text);
set_menu_item_text( menu, lpmii->dwTypeData, unicode );
}
/* free the string when used */
HeapFree(GetProcessHeap(), 0, menu->text);
set_menu_item_text( menu, lpmii->dwTypeData, unicode );
}
if (lpmii->fMask & MIIM_STATE)
@ -4276,9 +4297,10 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu,
subMenu->wFlags |= MF_POPUP;
menu->fType |= MF_POPUP;
}
else
/* FIXME: Return an error ? */
menu->fType &= ~MF_POPUP;
else {
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
}
else
menu->fType &= ~MF_POPUP;
@ -4298,6 +4320,9 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu,
if (lpmii->fMask & MIIM_BITMAP)
menu->hbmpItem = lpmii->hbmpItem;
if( !menu->text && !(menu->fType & MFT_OWNERDRAW) && !menu->hbmpItem)
menu->fType |= MFT_SEPARATOR;
debug_print_menuitem("SetMenuItemInfo_common to : ", menu, "");
return TRUE;
}
@ -4308,8 +4333,19 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu,
BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos,
const MENUITEMINFOA *lpmii)
{
MENUITEMINFOA mii;
if( lpmii->cbSize != sizeof( mii) &&
lpmii->cbSize != sizeof( mii) - sizeof ( mii.hbmpItem)) {
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
memcpy( &mii, lpmii, lpmii->cbSize);
if( lpmii->cbSize != sizeof( mii)) {
mii.cbSize = sizeof( mii);
mii.hbmpItem = NULL;
}
return SetMenuItemInfo_common(MENU_FindItem(&hmenu, &item, bypos? MF_BYPOSITION : 0),
(const MENUITEMINFOW *)lpmii, FALSE);
(const MENUITEMINFOW *)&mii, FALSE);
}
/**********************************************************************
@ -4318,8 +4354,19 @@ BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos,
BOOL WINAPI SetMenuItemInfoW(HMENU hmenu, UINT item, BOOL bypos,
const MENUITEMINFOW *lpmii)
{
return SetMenuItemInfo_common(MENU_FindItem(&hmenu, &item, bypos? MF_BYPOSITION : 0),
lpmii, TRUE);
MENUITEMINFOW mii;
if( lpmii->cbSize != sizeof( mii) &&
lpmii->cbSize != sizeof( mii) - sizeof ( mii.hbmpItem)) {
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
memcpy( &mii, lpmii, lpmii->cbSize);
if( lpmii->cbSize != sizeof( mii)) {
mii.cbSize = sizeof( mii);
mii.hbmpItem = NULL;
}
return SetMenuItemInfo_common(MENU_FindItem(&hmenu,
&item, bypos? MF_BYPOSITION : 0), &mii, TRUE);
}
/**********************************************************************
@ -4420,7 +4467,18 @@ BOOL WINAPI InsertMenuItemA(HMENU hMenu, UINT uItem, BOOL bypos,
const MENUITEMINFOA *lpmii)
{
MENUITEM *item = MENU_InsertItem(hMenu, uItem, bypos ? MF_BYPOSITION : 0 );
return SetMenuItemInfo_common(item, (const MENUITEMINFOW *)lpmii, FALSE);
MENUITEMINFOA mii;
if( lpmii->cbSize != sizeof( mii) &&
lpmii->cbSize != sizeof( mii) - sizeof ( mii.hbmpItem)) {
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
memcpy( &mii, lpmii, lpmii->cbSize);
if( lpmii->cbSize != sizeof( mii)) {
mii.cbSize = sizeof( mii);
mii.hbmpItem = NULL;
}
return SetMenuItemInfo_common(item, (const MENUITEMINFOW *)&mii, FALSE);
}
@ -4431,7 +4489,18 @@ BOOL WINAPI InsertMenuItemW(HMENU hMenu, UINT uItem, BOOL bypos,
const MENUITEMINFOW *lpmii)
{
MENUITEM *item = MENU_InsertItem(hMenu, uItem, bypos ? MF_BYPOSITION : 0 );
return SetMenuItemInfo_common(item, lpmii, TRUE);
MENUITEMINFOW mii;
if( lpmii->cbSize != sizeof( mii) &&
lpmii->cbSize != sizeof( mii) - sizeof ( mii.hbmpItem)) {
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
memcpy( &mii, lpmii, lpmii->cbSize);
if( lpmii->cbSize != sizeof( mii)) {
mii.cbSize = sizeof( mii);
mii.hbmpItem = NULL;
}
return SetMenuItemInfo_common(item, &mii, TRUE);
}
/**********************************************************************

View File

@ -253,9 +253,17 @@ static void test_menu_ownerdraw(void)
static void test_menu_add_string( void )
{
MENUITEMINFO info;
char string[0x80];
HMENU hmenu;
MENUITEMINFO info;
BOOL rc;
char string[0x80];
char string2[0x80];
char strback[0x80];
WCHAR strbackW[0x80];
static const WCHAR expectedString[] = {'D', 'u', 'm', 'm', 'y', ' ',
's', 't', 'r', 'i', 'n', 'g', 0};
hmenu = CreateMenu();
@ -279,9 +287,591 @@ static void test_menu_add_string( void )
ok( !strcmp( string, "blah" ), "menu item name differed\n");
/* Test combination of ownerdraw and strings with GetMenuItemString(A/W) */
strcpy(string, "Dummy string");
memset(&info, 0x00, sizeof(info));
info.cbSize= sizeof(MENUITEMINFO);
info.fMask= MIIM_FTYPE | MIIM_STRING; /* Set OwnerDraw + typeData */
info.fType= MFT_OWNERDRAW;
info.dwTypeData= string;
rc = InsertMenuItem( hmenu, 0, TRUE, &info );
ok (rc, "InsertMenuItem failed\n");
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");
/* Just change ftype to string and see what text is stored */
memset(&info, 0x00, sizeof(info));
info.cbSize= sizeof(MENUITEMINFO);
info.fMask= MIIM_FTYPE; /* Set string type */
info.fType= MFT_STRING;
info.dwTypeData= (char *)0xdeadbeef;
rc = SetMenuItemInfo( hmenu, 0, TRUE, &info );
ok (rc, "SetMenuItemInfo failed\n");
/* Did we keep the old dwTypeData? */
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");
/* Ensure change to bitmap type fails */
memset(&info, 0x00, sizeof(info));
info.cbSize= sizeof(MENUITEMINFO);
info.fMask= MIIM_FTYPE; /* Set as bitmap type */
info.fType= MFT_BITMAP;
info.dwTypeData= (char *)0xdeadbee2;
rc = SetMenuItemInfo( hmenu, 0, TRUE, &info );
ok (!rc, "SetMenuItemInfo unexpectedly worked\n");
/* Just change ftype back and ensure data hasnt been freed */
info.fType= MFT_OWNERDRAW; /* Set as ownerdraw type */
info.dwTypeData= (char *)0xdeadbee3;
rc = SetMenuItemInfo( hmenu, 0, TRUE, &info );
ok (rc, "SetMenuItemInfo failed\n");
/* Did we keep the old dwTypeData? */
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");
/* Just change string value (not type) */
memset(&info, 0x00, sizeof(info));
info.cbSize= sizeof(MENUITEMINFO);
info.fMask= MIIM_STRING; /* Set typeData */
strcpy(string2, "string2");
info.dwTypeData= string2;
rc = SetMenuItemInfo( hmenu, 0, TRUE, &info );
ok (rc, "SetMenuItemInfo failed\n");
ok (GetMenuString( hmenu, 0, strback, 99, MF_BYPOSITION), "GetMenuString on ownerdraw entry failed\n");
ok (!strcmp( strback, "string2" ), "Menu text from Ansi version incorrect\n");
DestroyMenu( hmenu );
}
/* define building blocks for the menu item info tests */
static int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
{
if (n <= 0) return 0;
while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
return *str1 - *str2;
}
static WCHAR *strcpyW( WCHAR *dst, const WCHAR *src )
{
WCHAR *p = dst;
while ((*p++ = *src++));
return dst;
}
#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));
#define DUMPMIINF(s,i,e)\
{\
DMIINFF( i, e, fMask)\
DMIINFF( i, e, fType)\
DMIINFF( i, e, fState)\
DMIINFF( i, e, wID)\
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)\
}
/* insert menu item */
#define TMII_INSMI( a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,\
eret1)\
{\
MENUITEMINFOA info1=a1 b1,c1,d1,e1,f1,(void*)g1,(void*)h1,(void*)i1,j1,(void*)k1,l1,(void*)m1 n1;\
HMENU hmenu = CreateMenu();\
BOOL ret, stop = FALSE;\
SetLastError( 0xdeadbeef);\
if(ansi)strcpy( string, init);\
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");\
stop = TRUE;\
} else ok( (eret1)==ret,"InsertMenuItem failed, err %ld\n",GetLastError());\
/* GetMenuItemInfo + GetMenuString */
#define TMII_GMII( a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,\
a3,b3,c3,d3,e3,f3,g3,h3,i3,j3,k3,l3,m3,n3,\
expname, eret2, eret3)\
{\
MENUITEMINFOA info2A=a2 b2,c2,d2,e2,f2,(void*)g2,(void*)h2,(void*)i2,j2,(void*)k2,l2,(void*)m2 n2;\
MENUITEMINFOA einfoA=a3 b3,c3,d3,e3,f3,(void*)g3,(void*)h3,(void*)i3,j3,(void*)k3,l3,(void*)m3 n3;\
MENUITEMINFOA *info2 = &info2A;\
MENUITEMINFOA *einfo = &einfoA;\
MENUITEMINFOW *info2W = (MENUITEMINFOW *)&info2A;\
if( !stop) {\
ret = ansi ? GetMenuItemInfoA( hmenu, 0, TRUE, info2 ) :\
GetMenuItemInfoW( hmenu, 0, TRUE, info2W );\
if( !(eret2)) ok( (eret2)==ret,"GetMenuItemInfo should have failed.\n");\
else { \
ok( (eret2)==ret,"GetMenuItemInfo failed, err %ld\n",GetLastError());\
ret = memcmp( info2, einfo, sizeof einfoA);\
/* ok( ret==0, "Got wrong menu item info data\n");*/\
if( ret) DUMPMIINF(info2A.cbSize, &info2A, &einfoA)\
if( einfo->dwTypeData == string) {\
if(ansi) ok( !strncmp( expname, info2->dwTypeData, einfo->cch ), "menu item name differed \"%s\"\n",\
einfo->dwTypeData ? einfo->dwTypeData: "");\
else ok( !strncmpW( (WCHAR*)expname, (WCHAR*)info2->dwTypeData, einfo->cch ), "menu item name differed \"%s\"\n",\
einfo->dwTypeData ? einfo->dwTypeData: "");\
ret = ansi ? GetMenuStringA( hmenu, 0, string, 80, MF_BYPOSITION) :\
GetMenuStringW( hmenu, 0, string, 80, MF_BYPOSITION);\
if( (eret3)){\
ok( ret, "GetMenuString failed, err %ld\n",GetLastError());\
}else\
ok( !ret, "GetMenuString should have failed\n");\
}\
}\
}\
}
#define TMII_DONE \
RemoveMenu(hmenu, 0, TRUE );\
DestroyMenu( hmenu );\
DestroyMenu( submenu );\
submenu = CreateMenu();\
}
/* modify menu */
#define TMII_MODM( flags, id, data, eret )\
if( !stop) {\
if(ansi)ret = ModifyMenuA( hmenu, 0, flags, (UINT_PTR)id, (char*)data);\
else ret = ModifyMenuW( hmenu, 0, flags, (UINT_PTR)id, (WCHAR*)data);\
if( !(eret)) ok( (eret)==ret,"ModifyMenuA should have failed.\n");\
else ok( (eret)==ret,"ModifyMenuA failed, err %ld\n",GetLastError());\
}
/* SetMenuItemInfo */
#define TMII_SMII( a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,\
eret1)\
if( !stop) {\
MENUITEMINFOA info1=a1 b1,c1,d1,e1,f1,(void*)g1,(void*)h1,(void*)i1,j1,(void*)k1,l1,(void*)m1 n1;\
SetLastError( 0xdeadbeef);\
if(ansi)strcpy( string, init);\
else strcpyW( (WCHAR*)string, (WCHAR*)init);\
if( ansi) ret = SetMenuItemInfoA(hmenu, 0, TRUE, &info1 );\
else ret = SetMenuItemInfoW(hmenu, 0, TRUE, (MENUITEMINFOW*)&info1 );\
if( !(eret1)) { ok( (eret1)==ret,"InsertMenuItem should have failed.\n");\
stop = TRUE;\
} else ok( (eret1)==ret,"InsertMenuItem failed, err %ld\n",GetLastError());\
}
#define OK 1
#define ER 0
static void test_menu_iteminfo( )
{
int S=sizeof( MENUITEMINFOA);
int ansi = TRUE;
char txtA[]="wine";
char initA[]="XYZ";
char emptyA[]="";
WCHAR txtW[]={'W','i','n','e',0};
WCHAR initW[]={'X','Y','Z',0};
WCHAR emptyW[]={0};
void *txt, *init, *empty, *string;
HBITMAP hbm = CreateBitmap(1,1,1,1,NULL);
char stringA[0x80];
HMENU submenu=CreateMenu();
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)
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 )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, 0, 0, 0, },
empty, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_BITMAP, -1, -1, -1, -1, -1, -1, hbm, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_BITMAP, -9, -9, 0, -9, -9, -9, hbm, 0, hbm, },
empty, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_BITMAP|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, hbm, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_BITMAP|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, hbm, 0, hbm, },
empty, OK, ER )
TMII_DONE
/* not enough space for name*/
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, NULL, 0, -9, },
{, S, MIIM_TYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, NULL, 4, 0, },
empty, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 5, -9, },
{, S, MIIM_TYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, 0, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 4, -9, },
{, S, MIIM_TYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 3, 0, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING, MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, NULL, 0, -9, },
{, S, MIIM_TYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 0, 0, },
empty, OK, ER )
TMII_DONE
/* can not combine MIIM_TYPE with some other flags */
TMII_INSMI( {, S, MIIM_TYPE|MIIM_STRING, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, ER)
TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
{, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
empty, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE|MIIM_STRING, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
empty, ER, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE|MIIM_FTYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, ER)
TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
{, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
empty, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
empty, ER, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE|MIIM_BITMAP, MFT_BITMAP, -1, -1, -1, -1, -1, -1, hbm, 6, hbm, }, ER)
TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
{, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
empty, OK, OK )
TMII_DONE
/* but succeeds with some others */
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE|MIIM_SUBMENU, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE|MIIM_SUBMENU, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, 0, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE|MIIM_STATE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE|MIIM_STATE, MFT_STRING, 0, -9, 0, -9, -9, -9, string, 4, 0, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE|MIIM_ID, MFT_STRING, -1, 888, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE|MIIM_ID, MFT_STRING, -9, 888, 0, -9, -9, -9, string, 4, 0, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE|MIIM_DATA, MFT_STRING, -1, -1, -1, -1, -1, 999, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE|MIIM_DATA, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE|MIIM_DATA, MFT_STRING, -9, -9, 0, -9, -9, 999, string, 4, 0, },
txt, OK, OK )
TMII_DONE
/* to be continued */
/* set text with MIIM_TYPE and retrieve with MIIM_STRING */
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, -9, },
txt, OK, OK )
TMII_DONE
/* set text with MIIM_TYPE and retrieve with MIIM_STRING; MFT_OWNERDRAW causes an empty string */
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 0, -9, },
empty, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_STRING|MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 0, -9, },
empty, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 80, -9, },
init, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK)
TMII_GMII ( {, S, 0, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, 0, -9, -9, -9, 0, -9, -9, -9, string, 80, -9, },
init, OK, OK )
TMII_DONE
/* contrary to MIIM_TYPE,you can set the text for an owner draw menu */
TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_STRING|MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 4, -9, },
txt, OK, OK )
TMII_DONE
/* same but retrieve with MIIM_TYPE */
TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_STRING|MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 0, -9, },
empty, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_STRING|MIIM_FTYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, string, 0, -9, },
empty, OK, ER )
TMII_DONE
/* How is that with bitmaps? */
TMII_INSMI( {, S, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_BITMAP, -9, -9, 0, -9, -9, -9, hbm, 0, hbm, },
empty, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK)
TMII_GMII ( {, S, MIIM_BITMAP|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_BITMAP|MIIM_FTYPE, 0, -9, -9, 0, -9, -9, -9, string, 80, hbm, },
init, OK, ER )
TMII_DONE
/* MIIM_BITMAP does not like MFT_BITMAP */
TMII_INSMI( {, S, MIIM_BITMAP|MIIM_FTYPE, MFT_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, ER)
TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
{, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
init, OK, OK )
TMII_DONE
/* no problem with OWNERDRAWN */
TMII_INSMI( {, S, MIIM_BITMAP|MIIM_FTYPE, MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK)
TMII_GMII ( {, S, MIIM_BITMAP|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_BITMAP|MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 80, hbm, },
init, OK, ER )
TMII_DONE
/* setting MFT_BITMAP with MFT_FTYPE fails anyway */
TMII_INSMI( {, S, MIIM_FTYPE, MFT_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, ER)
TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
{, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
empty, OK, OK )
TMII_DONE
/* menu with submenu */
TMII_INSMI( {, S, MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, submenu, -1, -1, -1, txt, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_SUBMENU, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_SUBMENU, -9, -9, -9, submenu, -9, -9, -9, string, 80, -9, },
init, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, submenu, -1, -1, -1, empty, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_SUBMENU, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_SUBMENU, -9, -9, -9, submenu, -9, -9, -9, string, 80, -9, },
init, OK, ER )
TMII_DONE
/* menu with submenu, without MIIM_SUBMENU the submenufield is cleared */
TMII_INSMI( {, S, MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, submenu, -1, -1, -1, txt, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, string, 0, -9, },
empty, OK, ER )
TMII_GMII ( {, S, MIIM_SUBMENU|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_SUBMENU|MIIM_FTYPE, MFT_SEPARATOR, -9, -9, submenu, -9, -9, -9, string, 80, -9, },
empty, OK, ER )
TMII_DONE
/* menu with invalid submenu */
TMII_INSMI( {, S, MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, 999, -1, -1, -1, txt, 0, -1, }, ER)
TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
{, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
init, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, txt, 0, 0, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, 0, 0, 0, },
empty, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_BITMAP|MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, hbm, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_BITMAP|MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, hbm, 0, hbm, },
empty, OK, ER )
TMII_DONE
/* SEPARATOR and STRING go well together */
/* BITMAP and STRING go well together */
TMII_INSMI( {, S, MIIM_STRING|MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, hbm, },
txt, OK, OK )
TMII_DONE
/* BITMAP, SEPARATOR and STRING go well together */
TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, string, 4, hbm, },
txt, OK, OK )
TMII_DONE
/* last two tests, but use MIIM_TYPE to retrieve info */
TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING, MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_STRING|MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_BITMAP, -9, -9, 0, -9, -9, -9, hbm, 4, hbm, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_SEPARATOR|MFT_BITMAP, -9, -9, 0, -9, -9, -9, hbm, 4, hbm, },
txt, OK, OK )
TMII_DONE
/* same three with MFT_OWNERDRAW */
TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING, MFT_SEPARATOR|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_SEPARATOR|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_BITMAP|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, hbm, 4, hbm, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_SEPARATOR|MFT_BITMAP|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, hbm, 4, hbm, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE|MIIM_ID, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, },
txt, OK, OK )
TMII_DONE
/* test with modifymenu: string is preserved after seting OWNERDRAW */
TMII_INSMI( {, S, MIIM_STRING, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK)
TMII_MODM( MFT_OWNERDRAW, -1, 787, OK)
TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_DATA, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE|MIIM_STRING|MIIM_DATA, MFT_OWNERDRAW, -9, -9, 0, -9, -9, 787, string, 4, -9, },
txt, OK, OK )
TMII_DONE
/* same with bitmap: now the text is cleared */
TMII_INSMI( {, S, MIIM_STRING, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK)
TMII_MODM( MFT_BITMAP, 545, hbm, OK)
TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, MFT_BITMAP, -9, 545, 0, -9, -9, -9, string, 0, hbm, },
empty, OK, ER )
TMII_DONE
/* start with bitmap: now setting text clears it (though he flag is raised) */
TMII_INSMI( {, S, MIIM_BITMAP, MFT_STRING, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK)
TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, MFT_STRING, -9, 0, 0, -9, -9, -9, string, 0, hbm, },
empty, OK, ER )
TMII_MODM( MFT_STRING, 545, txt, OK)
TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, MFT_STRING, -9, 545, 0, -9, -9, -9, string, 4, 0, },
txt, OK, OK )
TMII_DONE
/*repeat with text NULL */
TMII_INSMI( {, S, MIIM_BITMAP, MFT_STRING, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK)
TMII_MODM( MFT_STRING, 545, NULL, OK)
TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, MFT_SEPARATOR, -9, 545, 0, -9, -9, -9, string, 0, 0, },
empty, OK, ER )
TMII_DONE
/* repeat with text "" */
TMII_INSMI( {, S, MIIM_BITMAP, -1 , -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK)
TMII_MODM( MFT_STRING, 545, empty, OK)
TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, MFT_STRING, -9, 545, 0, -9, -9, -9, string, 0, 0, },
empty, OK, ER )
TMII_DONE
/* start with bitmap: set ownerdraw */
TMII_INSMI( {, S, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK)
TMII_MODM( MFT_OWNERDRAW, -1, 232, OK)
TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_DATA, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_DATA, MFT_OWNERDRAW, -9, -9, 0, -9, -9, 232, string, 0, hbm, },
empty, OK, ER )
TMII_DONE
/* ask nothing */
TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
TMII_GMII ( {, S, 0, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, 0, -9, -9, -9, 0, -9, -9, -9, string, 80, -9, },
init, OK, OK )
TMII_DONE
/* some tests with small cbSize: the hbmpItem is to be ignored */
TMII_INSMI( {, S - 4, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, NULL, 0, NULL, },
empty, OK, ER )
TMII_DONE
TMII_INSMI( {, S - 4, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK)
TMII_GMII ( {, S, MIIM_BITMAP|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_BITMAP|MIIM_FTYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, string, 80, NULL, },
init, OK, ER )
TMII_DONE
TMII_INSMI( {, S - 4, MIIM_STRING|MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
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, NULL, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S - 4, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S - 4, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, },
txt, OK, OK )
TMII_DONE
TMII_INSMI( {, S - 4, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_SEPARATOR|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, },
txt, OK, OK )
TMII_DONE
/* MIIM_TYPE by itself does not get/set the dwItemData for OwnerDrawn menus */
TMII_INSMI( {, S, MIIM_TYPE|MIIM_DATA, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, 343, txt, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE|MIIM_DATA, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE|MIIM_DATA, MFT_STRING|MFT_OWNERDRAW, -9, -9, 0, -9, -9, 343, 0, 0, 0, },
empty, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE|MIIM_DATA, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, 343, txt, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, 0, 0, 0, },
empty, OK, ER )
TMII_DONE
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, 343, txt, 0, -1, }, OK)
TMII_GMII ( {, S, MIIM_TYPE|MIIM_DATA, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_TYPE|MIIM_DATA, MFT_STRING|MFT_OWNERDRAW, -9, -9, 0, -9, -9, 0, 0, 0, 0, },
empty, OK, ER )
TMII_DONE
/* set a string menu to ownerdraw with MIIM_TYPE */
TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -2, -2, -2, -2, -2, -2, txt, -2, -2, }, OK)
TMII_SMII( {, S, MIIM_TYPE, MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, OK)
TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_STRING|MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 4, -9, },
txt, OK, OK )
TMII_DONE
/* test with modifymenu add submenu */
TMII_INSMI( {, S, MIIM_STRING, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK)
TMII_MODM( MF_POPUP, submenu, txt, OK)
TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_SUBMENU, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, },
{, S, MIIM_FTYPE|MIIM_STRING|MIIM_SUBMENU, MFT_STRING, -9, -9, submenu, -9, -9, -9, string, 4, -9, },
txt, OK, OK )
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 )
TMII_DONE
ansi = !ansi;
} while( !ansi);
DeleteObject( hbm);
}
START_TEST(menu)
{
@ -290,4 +880,5 @@ START_TEST(menu)
test_menu_locked_by_window();
test_menu_ownerdraw();
test_menu_add_string();
test_menu_iteminfo();
}