From 4d8f84cbdd388057ac46d1e90b7cdd6ddd2758be Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Wed, 20 Jun 2007 19:12:53 +0900 Subject: [PATCH] user32: When inserting a menu item make sure that MDI system buttons stay on the right side. --- dlls/user32/mdi.c | 10 +-- dlls/user32/menu.c | 11 +++ dlls/user32/tests/menu.c | 150 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 4 deletions(-) diff --git a/dlls/user32/mdi.c b/dlls/user32/mdi.c index 58252209192..0b488d2287d 100644 --- a/dlls/user32/mdi.c +++ b/dlls/user32/mdi.c @@ -307,7 +307,7 @@ static LRESULT MDISetMenu( HWND hwnd, HMENU hmenuFrame, MDICLIENTINFO *ci; HWND hwndFrame = GetParent(hwnd); - TRACE("%p %p %p\n", hwnd, hmenuFrame, hmenuWindow); + TRACE("%p, frame menu %p, window menu %p\n", hwnd, hmenuFrame, hmenuWindow); if (hmenuFrame && !IsMenu(hmenuFrame)) { @@ -323,6 +323,8 @@ static LRESULT MDISetMenu( HWND hwnd, HMENU hmenuFrame, if (!(ci = get_client_info( hwnd ))) return 0; + TRACE("old frame menu %p, old window menu %p\n", ci->hFrameMenu, ci->hWindowMenu); + if (hmenuFrame) { if (hmenuFrame == ci->hFrameMenu) return (LRESULT)hmenuFrame; @@ -844,12 +846,12 @@ static BOOL MDI_AugmentFrameMenu( HWND frame, HWND hChild ) } AppendMenuW(menu, MF_HELP | MF_BITMAP, - SC_MINIMIZE, (LPCWSTR)HBMMENU_MBAR_MINIMIZE ) ; + SC_CLOSE, is_close_enabled(hChild, hSysPopup) ? + (LPCWSTR)HBMMENU_MBAR_CLOSE : (LPCWSTR)HBMMENU_MBAR_CLOSE_D ); AppendMenuW(menu, MF_HELP | MF_BITMAP, SC_RESTORE, (LPCWSTR)HBMMENU_MBAR_RESTORE ); AppendMenuW(menu, MF_HELP | MF_BITMAP, - SC_CLOSE, is_close_enabled(hChild, hSysPopup) ? - (LPCWSTR)HBMMENU_MBAR_CLOSE : (LPCWSTR)HBMMENU_MBAR_CLOSE_D ); + SC_MINIMIZE, (LPCWSTR)HBMMENU_MBAR_MINIMIZE ) ; /* The system menu is replaced by the child icon */ hIcon = (HICON)SendMessageW(hChild, WM_GETICON, ICON_SMALL, 0); diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 6706e166e73..1660c205846 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -2101,6 +2101,17 @@ static MENUITEM *MENU_InsertItem( HMENU hMenu, UINT pos, UINT flags ) } } + /* Make sure that MDI system buttons stay on the right side. + * Note: XP treats only bitmap handles 1 - 6 as "magic" ones + * regardless of their id. + */ + while (pos > 0 && (menu->items[pos - 1].fType & MFT_BITMAP) && + (INT_PTR)menu->items[pos - 1].hbmpItem >= (INT_PTR)HBMMENU_SYSTEM && + (INT_PTR)menu->items[pos - 1].hbmpItem <= (INT_PTR)HBMMENU_MBAR_CLOSE_D) + pos--; + + TRACE("inserting at %u by pos %u\n", pos, flags & MF_BYPOSITION); + /* Create new items array */ newItems = HeapAlloc( GetProcessHeap(), 0, sizeof(MENUITEM) * (menu->nItems+1) ); diff --git a/dlls/user32/tests/menu.c b/dlls/user32/tests/menu.c index 3037099d0bf..2138fec7300 100644 --- a/dlls/user32/tests/menu.c +++ b/dlls/user32/tests/menu.c @@ -2069,6 +2069,155 @@ static void test_menu_resource_layout(void) DestroyMenu(hmenu); } +struct menu_data +{ + UINT type, id; + const char *str; +}; + +static HMENU create_menu_from_data(const struct menu_data *item, INT item_count) +{ + HMENU hmenu; + INT i; + BOOL ret; + + hmenu = CreateMenu(); + assert(hmenu != 0); + + for (i = 0; i < item_count; i++) + { + SetLastError(0xdeadbeef); + ret = AppendMenu(hmenu, item[i].type, item[i].id, item[i].str); + ok(ret, "%d: AppendMenu(%04x, %04x, %p) error %u\n", + i, item[i].type, item[i].id, item[i].str, GetLastError()); + } + return hmenu; +} + +static void compare_menu_data(HMENU hmenu, const struct menu_data *item, INT item_count) +{ + INT count, i; + BOOL ret; + + count = GetMenuItemCount(hmenu); + ok(count == item_count, "expected %d, got %d menu items\n", count, item_count); + + for (i = 0; i < count; i++) + { + char buf[20]; + MENUITEMINFO mii; + + memset(&mii, 0, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.dwTypeData = buf; + mii.cch = sizeof(buf); + mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_BITMAP; + ret = GetMenuItemInfo(hmenu, i, TRUE, &mii); + ok(ret, "GetMenuItemInfo(%u) failed\n", i); +#if 0 + trace("item #%u: fType %04x, fState %04x, wID %04x, hbmp %p\n", + i, mii.fType, mii.fState, mii.wID, mii.hbmpItem); +#endif + ok(mii.fType == item[i].type, + "%u: expected fType %04x, got %04x\n", i, item[i].type, mii.fType); + ok(mii.wID == item[i].id, + "%u: expected wID %04x, got %04x\n", i, item[i].id, mii.wID); + if (item[i].type & (MF_BITMAP | MF_SEPARATOR)) + { + /* For some reason Windows sets high word to not 0 for + * not "magic" ids. + */ + ok(LOWORD(mii.hbmpItem) == LOWORD(item[i].str), + "%u: expected hbmpItem %p, got %p\n", i, item[i].str, mii.hbmpItem); + } + else + { + ok(mii.cch == strlen(item[i].str), + "%u: expected cch %u, got %u\n", i, (UINT)strlen(item[i].str), mii.cch); + ok(!strcmp((LPCSTR)mii.dwTypeData, item[i].str), + "%u: expected dwTypeData %s, got %s\n", i, item[i].str, (LPCSTR)mii.dwTypeData); + } + } +} + +static void test_InsertMenu(void) +{ + /* Note: XP treats only bitmap handles 1 - 6 as "magic" ones + * regardless of their id. + */ + static const struct menu_data in1[] = + { + { MF_STRING, 1, "File" }, + { MF_BITMAP|MF_HELP, SC_CLOSE, MAKEINTRESOURCE(1) }, + { MF_STRING|MF_HELP, 2, "Help" } + }; + static const struct menu_data out1[] = + { + { MF_STRING, 1, "File" }, + { MF_STRING|MF_HELP, 2, "Help" }, + { MF_BITMAP|MF_HELP, SC_CLOSE, MAKEINTRESOURCE(1) } + }; + static const struct menu_data in2[] = + { + { MF_STRING, 1, "File" }, + { MF_BITMAP|MF_HELP, SC_CLOSE, MAKEINTRESOURCE(100) }, + { MF_STRING|MF_HELP, 2, "Help" } + }; + static const struct menu_data out2[] = + { + { MF_STRING, 1, "File" }, + { MF_BITMAP|MF_HELP, SC_CLOSE, MAKEINTRESOURCE(100) }, + { MF_STRING|MF_HELP, 2, "Help" } + }; + static const struct menu_data in3[] = + { + { MF_STRING, 1, "File" }, + { MF_SEPARATOR|MF_HELP, SC_CLOSE, MAKEINTRESOURCE(1) }, + { MF_STRING|MF_HELP, 2, "Help" } + }; + static const struct menu_data out3[] = + { + { MF_STRING, 1, "File" }, + { MF_SEPARATOR|MF_HELP, SC_CLOSE, MAKEINTRESOURCE(0) }, + { MF_STRING|MF_HELP, 2, "Help" }, + }; + static const struct menu_data in4[] = + { + { MF_STRING, 1, "File" }, + { MF_BITMAP|MF_HELP, 1, MAKEINTRESOURCE(1) }, + { MF_STRING|MF_HELP, 2, "Help" } + }; + static const struct menu_data out4[] = + { + { MF_STRING, 1, "File" }, + { MF_STRING|MF_HELP, 2, "Help" }, + { MF_BITMAP|MF_HELP, 1, MAKEINTRESOURCE(1) } + }; + HMENU hmenu; + +#define create_menu(a) create_menu_from_data((a), sizeof(a)/sizeof((a)[0])) +#define compare_menu(h, a) compare_menu_data((h), (a), sizeof(a)/sizeof((a)[0])) + + hmenu = create_menu(in1); + compare_menu(hmenu, out1); + DestroyMenu(hmenu); + + hmenu = create_menu(in2); + compare_menu(hmenu, out2); + DestroyMenu(hmenu); + + hmenu = create_menu(in3); + compare_menu(hmenu, out3); + DestroyMenu(hmenu); + + hmenu = create_menu(in4); + compare_menu(hmenu, out4); + DestroyMenu(hmenu); + +#undef create_menu +#undef compare_menu +} + START_TEST(menu) { pSetMenuInfo = @@ -2089,4 +2238,5 @@ START_TEST(menu) test_menu_hilitemenuitem(); test_CheckMenuRadioItem(); test_menu_resource_layout(); + test_InsertMenu(); }