- Patch by Victor Martinez Calvo : Several menu.c fixes. See CORE-7967.
- Sync port from wine with modifications

svn path=/trunk/; revision=62528
This commit is contained in:
James Tabor 2014-03-18 04:11:30 +00:00
parent 13bd05110c
commit 6e6984882a

View file

@ -36,6 +36,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(menu);
#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)
@ -1303,7 +1306,7 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd
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
@ -1551,6 +1554,7 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
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);
@ -1592,6 +1596,11 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
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;
@ -1619,7 +1628,7 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
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);
@ -1697,9 +1706,9 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
}
if (sendMenuSelect)
{
WPARAM wParam = MAKELONG( ItemInfo.fType & MF_POPUP ? wIndex : ItemInfo.wID,
ItemInfo.fType | ItemInfo.fState |
(hmenu->Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) );
WPARAM wParam = MAKEWPARAM( ItemInfo.fType & MF_POPUP ? wIndex : ItemInfo.wID,
ItemInfo.fType | ItemInfo.fState |
(hmenu->Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) );
SendMessageW(hwndOwner, WM_MENUSELECT, wParam, (LPARAM) hmenu->Self);
}
@ -1714,8 +1723,8 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
if (MenuGetRosMenuInfo(&TopMenuInfo, topmenu)
&& MenuGetRosMenuItemInfo(topmenu, pos, &ItemInfo))
{
WPARAM wParam = MAKELONG( Pos, ItemInfo.fType | ItemInfo.fState |
(TopMenuInfo.Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) );
WPARAM wParam = MAKEWPARAM( Pos, ItemInfo.fType | ItemInfo.fState |
(TopMenuInfo.Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) );
SendMessageW(hwndOwner, WM_MENUSELECT, wParam, (LPARAM) topmenu);
}
@ -1999,11 +2008,11 @@ PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
*
* 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
@ -2020,46 +2029,19 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
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;
@ -2075,10 +2057,10 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
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);
@ -2119,13 +2101,12 @@ static LPCSTR MENUEX_ParseResource(LPCSTR res, HMENU hMenu)
}
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;
}
@ -2332,7 +2313,7 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl
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))
@ -2377,38 +2358,47 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl
{
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);
Rect.bottom = GetSystemMetrics(SM_CYSIZE);
}
else
{
{
GetWindowRect(MenuInfo->Wnd, &Rect);
if (0 != (MenuInfo->Flags & MNF_POPUP))
{
Rect.left += ItemInfo.Rect.right - GetSystemMetrics(SM_CXBORDER);
Rect.top += ItemInfo.Rect.top - 3;
{
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 - 3 - 2
- GetSystemMetrics(SM_CYBORDER);
}
Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom - MENU_TOP_MARGIN - MENU_BOTTOM_MARGIN/*2*/
- GetSystemMetrics(SM_CYBORDER);
}
else
{
Rect.left += ItemInfo.Rect.left;
{
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;
}
}
}
}
/* 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))
{
{
MenuMoveSelection(WndOwner, &SubMenuInfo, ITEM_NEXT);
}
}
Ret = ItemInfo.hSubMenu;
MenuCleanupRosMenuItemInfo(&ItemInfo);
@ -2985,20 +2975,20 @@ MenuSuspendPopup(MTRACKER* Mt, UINT uMsg)
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;
@ -3622,6 +3612,7 @@ VOID MenuTrackMouseMenuBar( HWND hWnd, ULONG ht, POINT pt)
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 */
@ -3723,6 +3714,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
/* ReactOS Check */
if (!ValidateHwnd(Wnd))
{
/* invalid window see wine menu.c test_menu_trackpopupmenu line 3146 */
return FALSE;
}
@ -4823,7 +4815,7 @@ LoadMenuIndirectW(CONST MENUTEMPLATE *lpMenuTemplate)
offset = GET_WORD(p);
p += sizeof(WORD) + offset;
if (!(hMenu = CreateMenu())) return 0;
if (!MENU_ParseResource(p, hMenu, TRUE))
if (!MENU_ParseResource(p, hMenu))
{
DestroyMenu(hMenu);
return 0;