Index: win32ss/user/user32/windows/menu.c =================================================================== --- win32ss/user/user32/windows/menu.c (revision 62032) +++ win32ss/user/user32/windows/menu.c (working copy) @@ -36,6 +36,9 @@ #define TPM_BUTTONDOWN 0x40000000 /* menu was clicked before tracking */ #define TPM_POPUPMENU 0x20000000 /* menu is a popup menu */ +/* top and bottom margins for popup menus */ +#define MENU_TOP_MARGIN 3 +#define MENU_BOTTOM_MARGIN 2 #define MENU_TYPE_MASK (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR) @@ -1299,7 +1302,7 @@ HBITMAP bm; INT y = rect.top + rect.bottom; RECT rc = rect; - int checked = FALSE; + BOOL checked = FALSE; UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK ); UINT check_bitmap_height = GetSystemMetrics( SM_CYMENUCHECK ); /* Draw the check mark @@ -1547,6 +1550,7 @@ POINT pt; HMONITOR monitor; MONITORINFO info; + DWORD ex_style = 0; TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n", hwndOwner, hmenu, id, x, y, xanchor, yanchor); @@ -1587,7 +1591,12 @@ monitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST ); info.cbSize = sizeof(info); GetMonitorInfoW( monitor, &info ); - + + if (flags & TPM_LAYOUTRTL) + { + ex_style = WS_EX_LAYOUTRTL; + flags ^= TPM_RIGHTALIGN; + } if( flags & TPM_RIGHTALIGN ) x -= width; if( flags & TPM_CENTERALIGN ) x -= width / 2; @@ -1615,7 +1624,7 @@ if( y < info.rcMonitor.top ) y = info.rcMonitor.top; /* NOTE: In Windows, top menu popup is not owned. */ - MenuInfo.Wnd = CreateWindowExW( 0, WC_MENU, NULL, + MenuInfo.Wnd = CreateWindowExW( ex_style, WC_MENU, NULL, WS_POPUP, x, y, width, height, hwndOwner, 0, (HINSTANCE) GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE), (LPVOID) MenuInfo.Self); @@ -1694,7 +1703,7 @@ if (sendMenuSelect) { SendMessageW(hwndOwner, WM_MENUSELECT, - MAKELONG(ItemInfo.fType & MF_POPUP ? wIndex : ItemInfo.wID, + MAKEWPARAM(ItemInfo.fType & MF_POPUP ? wIndex : ItemInfo.wID, ItemInfo.fType | ItemInfo.fState | MF_MOUSESELECT | (hmenu->Flags & MF_SYSMENU)), (LPARAM) hmenu->Self); } @@ -1710,7 +1719,7 @@ && MenuGetRosMenuItemInfo(topmenu, pos, &ItemInfo)) { SendMessageW(hwndOwner, WM_MENUSELECT, - MAKELONG(Pos, ItemInfo.fType | ItemInfo.fState + MAKEWPARAM(Pos, ItemInfo.fType | ItemInfo.fState | MF_MOUSESELECT | (TopMenuInfo.Flags & MF_SYSMENU)), (LPARAM) topmenu); @@ -1995,11 +2004,11 @@ * * NOTE: flags is equivalent to the mtOption field */ -static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode ) +static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu) { WORD flags, id = 0; HMENU hSubMenu; - LPCSTR str; + LPCWSTR str; BOOL end = FALSE; do @@ -2016,46 +2025,19 @@ id = GET_WORD(res); res += sizeof(WORD); } - str = res; - if(!unicode) - res += strlen(str) + 1; - else - res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR); + str = (LPCWSTR)res; + res += (strlenW(str) + 1) * sizeof(WCHAR); + if (flags & MF_POPUP) { hSubMenu = CreatePopupMenu(); if(!hSubMenu) return NULL; - if(!(res = MENU_ParseResource(res, hSubMenu, unicode))) - return NULL; - if(!unicode) - AppendMenuA(hMenu, flags, (UINT)hSubMenu, str); - else - AppendMenuW(hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str); + if(!(res = MENU_ParseResource(res, hSubMenu))) return NULL; + AppendMenuW(hMenu, flags, (UINT_PTR)hSubMenu, (LPCWSTR)str); } else /* Not a popup */ { - if(!unicode) - { - if (*str == 0) - flags = MF_SEPARATOR; - } - else - { - if (*(LPCWSTR)str == 0) - flags = MF_SEPARATOR; - } - - if (flags & MF_SEPARATOR) - { - if (!(flags & (MF_GRAYED | MF_DISABLED))) - flags |= MF_GRAYED | MF_DISABLED; - } - - if(!unicode) - AppendMenuA(hMenu, flags, id, *str ? str : NULL); - else - AppendMenuW(hMenu, flags, id, - *(LPCWSTR)str ? (LPCWSTR)str : NULL); + AppendMenuW(hMenu, flags, id, *(LPCWSTR)str ? (LPCWSTR)str : NULL); } } while(!end); return res; @@ -2071,10 +2053,10 @@ static LPCSTR MENUEX_ParseResource(LPCSTR res, HMENU hMenu) { WORD resinfo; - MENUITEMINFOW mii; - do { + MENUITEMINFOW mii; + mii.cbSize = sizeof(mii); mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE; mii.fType = GET_DWORD(res); @@ -2115,13 +2097,12 @@ } mii.fMask |= MIIM_SUBMENU; mii.fType |= MF_POPUP; - mii.wID = (UINT)mii.hSubMenu; } - else if (!mii.dwTypeData[0]) + else if (!mii.dwTypeData[0] && !(mii.fType & MF_SEPARATOR)) + { mii.fType |= MF_SEPARATOR; - - if (!InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii)) - ERR("InsertMenuItemW failed\n"); + } + InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii); } while (!(resinfo & MF_END)); return res; } @@ -2328,7 +2309,7 @@ if (0 == (Flags & TPM_NONOTIFY)) { SendMessageW(WndOwner, WM_INITMENUPOPUP, (WPARAM) ItemInfo.hSubMenu, - MAKELONG(MenuInfo->FocusedItem, IS_SYSTEM_MENU(MenuInfo))); + MAKELPARAM(MenuInfo->FocusedItem, IS_SYSTEM_MENU(MenuInfo))); } if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo)) @@ -2373,7 +2354,7 @@ { MenuInitSysMenuPopup(ItemInfo.hSubMenu, GetWindowLongPtrW(MenuInfo->Wnd, GWL_STYLE), GetClassLongPtrW(MenuInfo->Wnd, GCL_STYLE), HTSYSMENU); - + if (Flags & TPM_LAYOUTRTL) Rect.left; NcGetSysPopupPos(MenuInfo->Wnd, &Rect); Rect.top = Rect.bottom; Rect.right = GetSystemMetrics(SM_CXSIZE); @@ -2381,35 +2362,44 @@ } else { - GetWindowRect(MenuInfo->Wnd, &Rect); - if (0 != (MenuInfo->Flags & MF_POPUP)) - { - Rect.left += ItemInfo.Rect.right - GetSystemMetrics(SM_CXBORDER); - Rect.top += ItemInfo.Rect.top - 3; - Rect.right = ItemInfo.Rect.left - ItemInfo.Rect.right + GetSystemMetrics(SM_CXBORDER); - Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom - 3 - 2 + GetWindowRect(MenuInfo->Wnd, &Rect); + if (0 != (MenuInfo->Flags & MF_POPUP)) + { + if(Flags & TPM_LAYOUTRTL) + Rect.left += GetSystemMetrics(SM_CXBORDER); + else + Rect.left += ItemInfo.Rect.right- GetSystemMetrics(SM_CXBORDER); + Rect.top += ItemInfo.Rect.top - MENU_TOP_MARGIN;//3; + Rect.right = ItemInfo.Rect.left - ItemInfo.Rect.right + GetSystemMetrics(SM_CXBORDER); + Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom - MENU_TOP_MARGIN - MENU_BOTTOM_MARGIN/*2*/ - GetSystemMetrics(SM_CYBORDER); } - else + else { - Rect.left += ItemInfo.Rect.left; - Rect.top += ItemInfo.Rect.bottom; - Rect.right = ItemInfo.Rect.right - ItemInfo.Rect.left; - Rect.bottom = ItemInfo.Rect.bottom - ItemInfo.Rect.top; + if(Flags & TPM_LAYOUTRTL) + Rect.left += Rect.right - ItemInfo.Rect.left; + else + Rect.left += ItemInfo.Rect.left; + Rect.top += ItemInfo.Rect.bottom; + Rect.right = ItemInfo.Rect.right - ItemInfo.Rect.left; + Rect.bottom = ItemInfo.Rect.bottom - ItemInfo.Rect.top; } } - MenuShowPopup(WndOwner, ItemInfo.hSubMenu, MenuInfo->FocusedItem, Flags, + /* use default alignment for submenus */ + Flags &= ~(TPM_CENTERALIGN | TPM_RIGHTALIGN | TPM_VCENTERALIGN | TPM_BOTTOMALIGN); + + MenuShowPopup(WndOwner, ItemInfo.hSubMenu, MenuInfo->FocusedItem, Flags, Rect.left, Rect.top, Rect.right, Rect.bottom ); - if (SelectFirst && MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu)) + if (SelectFirst && MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu)) { - MenuMoveSelection(WndOwner, &SubMenuInfo, ITEM_NEXT); + MenuMoveSelection(WndOwner, &SubMenuInfo, ITEM_NEXT); } - - Ret = ItemInfo.hSubMenu; - MenuCleanupRosMenuItemInfo(&ItemInfo); - - return Ret; + + Ret = ItemInfo.hSubMenu; + MenuCleanupRosMenuItemInfo(&ItemInfo); + + return Ret; } /********************************************************************** @@ -2978,20 +2968,20 @@ switch( uMsg ) { - case WM_KEYDOWN: - PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE); - if( msg.message == WM_KEYUP || msg.message == WM_PAINT ) - { - PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE); - PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE); - if( msg.message == WM_KEYDOWN && - (msg.wParam == VK_LEFT || msg.wParam == VK_RIGHT)) - { - Mt->TrackFlags |= TF_SUSPENDPOPUP; - return TRUE; - } - } - break; + case WM_KEYDOWN: + PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE); + if( msg.message == WM_KEYUP || msg.message == WM_PAINT ) + { + PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE); + PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE); + if( msg.message == WM_KEYDOWN && + (msg.wParam == VK_LEFT || msg.wParam == VK_RIGHT)) + { + Mt->TrackFlags |= TF_SUSPENDPOPUP; + return TRUE; + } + } + break; } /* failures go through this */ Mt->TrackFlags &= ~TF_SUSPENDPOPUP; @@ -3616,6 +3606,7 @@ TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", hWnd, ht, pt.x, pt.y); + if (GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) wFlags |= TPM_LAYOUTRTL; if (IsMenu(hMenu)) { /* map point to parent client coordinates */ @@ -3717,6 +3708,7 @@ /* ReactOS Check */ if (!ValidateHwnd(Wnd)) { + SetLastError( ERROR_POPUP_ALREADY_ACTIVE ); return FALSE; }