user32: Add a test for CheckMenuRadioItem and make it pass under Wine.
This commit is contained in:
parent
e61eddd6a5
commit
7f189eccb9
|
@ -4817,34 +4817,49 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu,
|
|||
UINT first, UINT last, UINT check,
|
||||
UINT bypos)
|
||||
{
|
||||
MENUITEM *mifirst, *milast, *micheck;
|
||||
HMENU mfirst = hMenu, mlast = hMenu, mcheck = hMenu;
|
||||
BOOL done = FALSE;
|
||||
UINT i;
|
||||
MENUITEM *mi_first = NULL, *mi_check;
|
||||
HMENU m_first, m_check;
|
||||
|
||||
TRACE("%p: %d-%d, check %d, bypos=%d\n", hMenu, first, last, check, bypos);
|
||||
TRACE("%p: %u-%u, check %u, flags %04x\n", hMenu, first, last, check, bypos);
|
||||
|
||||
mifirst = MENU_FindItem (&mfirst, &first, bypos);
|
||||
milast = MENU_FindItem (&mlast, &last, bypos);
|
||||
micheck = MENU_FindItem (&mcheck, &check, bypos);
|
||||
for (i = first; i <= last; i++)
|
||||
{
|
||||
UINT pos = i;
|
||||
|
||||
if (mifirst == NULL || milast == NULL || micheck == NULL ||
|
||||
mifirst > milast || mfirst != mlast || mfirst != mcheck ||
|
||||
micheck > milast || micheck < mifirst)
|
||||
return FALSE;
|
||||
if (!mi_first)
|
||||
{
|
||||
m_first = hMenu;
|
||||
mi_first = MENU_FindItem(&m_first, &pos, bypos);
|
||||
if (!mi_first) continue;
|
||||
mi_check = mi_first;
|
||||
m_check = m_first;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_check = hMenu;
|
||||
mi_check = MENU_FindItem(&m_check, &pos, bypos);
|
||||
if (!mi_check) continue;
|
||||
}
|
||||
|
||||
while (mifirst <= milast)
|
||||
{
|
||||
if (mifirst == micheck)
|
||||
{
|
||||
mifirst->fType |= MFT_RADIOCHECK;
|
||||
mifirst->fState |= MFS_CHECKED;
|
||||
} else {
|
||||
mifirst->fType &= ~MFT_RADIOCHECK;
|
||||
mifirst->fState &= ~MFS_CHECKED;
|
||||
}
|
||||
mifirst++;
|
||||
}
|
||||
if (m_first != m_check) continue;
|
||||
if (mi_check->fType == MFT_SEPARATOR) continue;
|
||||
|
||||
return TRUE;
|
||||
if (i == check)
|
||||
{
|
||||
mi_check->fType |= MFT_RADIOCHECK;
|
||||
mi_check->fState |= MFS_CHECKED;
|
||||
done = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MSDN is wrong, Windows does not remove MFT_RADIOCHECK */
|
||||
mi_check->fState &= ~MFS_CHECKED;
|
||||
}
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Unit tests for menus
|
||||
*
|
||||
* Copyright 2005 Robert Shearman
|
||||
* Copyright 2007 Dmitry Timoshkov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -18,7 +19,8 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#define _WIN32_WINNT 0x0501
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -1872,6 +1874,120 @@ static void test_menu_hilitemenuitem( void )
|
|||
DestroyMenu(hMenu);
|
||||
}
|
||||
|
||||
static void check_menu_items(HMENU hmenu, UINT checked_cmd, UINT checked_type,
|
||||
UINT checked_state)
|
||||
{
|
||||
UINT i, count;
|
||||
|
||||
count = GetMenuItemCount(hmenu);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
BOOL ret;
|
||||
MENUITEMINFO mii;
|
||||
|
||||
memset(&mii, 0, sizeof(mii));
|
||||
mii.cbSize = sizeof(mii);
|
||||
mii.fMask = MIIM_FTYPE | MIIM_STATE | MIIM_ID | MIIM_SUBMENU;
|
||||
ret = GetMenuItemInfo(hmenu, i, TRUE, &mii);
|
||||
ok(ret, "GetMenuItemInfo(%u) failed\n", i);
|
||||
#if 0
|
||||
trace("item #%u: fType %04x, fState %04x, wID %u, hSubMenu %p\n",
|
||||
i, mii.fType, mii.fState, mii.wID, mii.hSubMenu);
|
||||
#endif
|
||||
if (mii.hSubMenu)
|
||||
{
|
||||
ok((HMENU)mii.wID == mii.hSubMenu, "id %u: wID should be equal to hSubMenu\n", checked_cmd);
|
||||
check_menu_items(mii.hSubMenu, checked_cmd, checked_type, checked_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mii.wID == checked_cmd)
|
||||
{
|
||||
ok(mii.fType == checked_type, "id %u: expected fType %04x, got %04x\n", checked_cmd, checked_type, mii.fType);
|
||||
ok(mii.fState == checked_state, "id %u: expected fState %04x, got %04x\n", checked_cmd, checked_state, mii.fState);
|
||||
ok(mii.wID != 0, "id %u: not expected wID 0\n", checked_cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(mii.fType != MFT_RADIOCHECK, "id %u: not expected fType MFT_RADIOCHECK on cmd %u\n", checked_cmd, mii.wID);
|
||||
|
||||
if (mii.fType == MFT_SEPARATOR)
|
||||
{
|
||||
todo_wine {
|
||||
ok(mii.fState == MFS_GRAYED, "id %u: expected fState MFS_GRAYED, got %04x\n", checked_cmd, mii.fState);
|
||||
}
|
||||
ok(mii.wID == 0, "id %u: expected wID 0, got %u\n", checked_cmd, mii.wID);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(mii.fState == 0, "id %u: expected fState 0, got %04x\n", checked_cmd, mii.fState);
|
||||
ok(mii.wID != 0, "id %u: not expected wID 0\n", checked_cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_ftype_and_state(HMENU hmenu, UINT id, UINT flags)
|
||||
{
|
||||
BOOL ret;
|
||||
MENUITEMINFO mii;
|
||||
|
||||
memset(&mii, 0, sizeof(mii));
|
||||
mii.cbSize = sizeof(mii);
|
||||
mii.fMask = MIIM_FTYPE | MIIM_STATE;
|
||||
ret = SetMenuItemInfo(hmenu, id, (flags & MF_BYPOSITION) != 0, &mii);
|
||||
ok(ret, "SetMenuItemInfo(%u) failed\n", id);
|
||||
}
|
||||
|
||||
static void test_CheckMenuRadioItem(void)
|
||||
{
|
||||
BOOL ret;
|
||||
HMENU hmenu;
|
||||
|
||||
hmenu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(1));
|
||||
assert(hmenu != 0);
|
||||
|
||||
check_menu_items(hmenu, -1, 0, 0);
|
||||
|
||||
ret = CheckMenuRadioItem(hmenu, 100, 100, 100, MF_BYCOMMAND);
|
||||
ok(ret, "CheckMenuRadioItem failed\n");
|
||||
check_menu_items(hmenu, 100, MFT_RADIOCHECK, MFS_CHECKED);
|
||||
|
||||
/* MSDN is wrong, Windows does not remove MFT_RADIOCHECK */
|
||||
ret = CheckMenuRadioItem(hmenu, 100, 100, -1, MF_BYCOMMAND);
|
||||
ok(!ret, "CheckMenuRadioItem should return FALSE\n");
|
||||
check_menu_items(hmenu, 100, MFT_RADIOCHECK, 0);
|
||||
|
||||
/* clear check */
|
||||
clear_ftype_and_state(hmenu, 100, MF_BYCOMMAND);
|
||||
check_menu_items(hmenu, -1, 0, 0);
|
||||
|
||||
/* first and checked items are on different menus */
|
||||
ret = CheckMenuRadioItem(hmenu, 0, 300, 202, MF_BYCOMMAND);
|
||||
ok(!ret, "CheckMenuRadioItem should return FALSE\n");
|
||||
check_menu_items(hmenu, -1, 0, 0);
|
||||
|
||||
ret = CheckMenuRadioItem(hmenu, 200, 300, 202, MF_BYCOMMAND);
|
||||
ok(ret, "CheckMenuRadioItem failed\n");
|
||||
check_menu_items(hmenu, 202, MFT_RADIOCHECK, MFS_CHECKED);
|
||||
|
||||
/* MSDN is wrong, Windows does not remove MFT_RADIOCHECK */
|
||||
ret = CheckMenuRadioItem(hmenu, 202, 202, -1, MF_BYCOMMAND);
|
||||
ok(!ret, "CheckMenuRadioItem should return FALSE\n");
|
||||
check_menu_items(hmenu, 202, MFT_RADIOCHECK, 0);
|
||||
|
||||
/* clear check */
|
||||
clear_ftype_and_state(hmenu, 202, MF_BYCOMMAND);
|
||||
check_menu_items(hmenu, -1, 0, 0);
|
||||
|
||||
/* just for fun, try to check separator */
|
||||
ret = CheckMenuRadioItem(hmenu, 0, 300, 0, MF_BYCOMMAND);
|
||||
ok(!ret, "CheckMenuRadioItem should return FALSE\n");
|
||||
check_menu_items(hmenu, -1, 0, 0);
|
||||
}
|
||||
|
||||
START_TEST(menu)
|
||||
{
|
||||
pSetMenuInfo =
|
||||
|
@ -1890,4 +2006,5 @@ START_TEST(menu)
|
|||
test_menu_input();
|
||||
test_menu_flags();
|
||||
test_menu_hilitemenuitem();
|
||||
test_CheckMenuRadioItem();
|
||||
}
|
||||
|
|
|
@ -106,3 +106,24 @@ END
|
|||
'00 00 00 00 00 00 00 00 00 00 FF FF FF 00 40 00'
|
||||
'00 00'
|
||||
} */
|
||||
|
||||
1 MENU
|
||||
{
|
||||
POPUP "&File"
|
||||
{
|
||||
MENUITEM "&New", 100
|
||||
MENUITEM "&Open", 101
|
||||
MENUITEM "&Save", 102
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&xit", 103
|
||||
}
|
||||
POPUP "Edit"
|
||||
{
|
||||
MENUITEM "&Undo", 200
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Cu&t", 201
|
||||
MENUITEM "&Copy", 202
|
||||
MENUITEM "&Paste", 203
|
||||
MENUITEM "&Delete", 204
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue