Dmitry Timoshkov : user32: When inserting a menu item make sure that MDI system buttons stay on the right side .

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jun 20 09:13:44 CDT 2007


Module: wine
Branch: master
Commit: 4d8f84cbdd388057ac46d1e90b7cdd6ddd2758be
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4d8f84cbdd388057ac46d1e90b7cdd6ddd2758be

Author: Dmitry Timoshkov <dmitry at codeweavers.com>
Date:   Wed Jun 20 19:12:53 2007 +0900

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 5825220..0b488d2 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 6706e16..1660c20 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 3037099..2138fec 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();
 }




More information about the wine-cvs mailing list