Author: jimtabor
Date: Tue Mar 18 04:11:30 2014
New Revision: 62528
URL:
http://svn.reactos.org/svn/reactos?rev=62528&view=rev
Log:
[User32]
- Patch by Victor Martinez Calvo : Several menu.c fixes. See CORE-7967.
- Sync port from wine with modifications
Modified:
trunk/reactos/win32ss/user/user32/windows/menu.c
Modified: trunk/reactos/win32ss/user/user32/windows/menu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/window…
==============================================================================
--- trunk/reactos/win32ss/user/user32/windows/menu.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/windows/menu.c [iso-8859-1] Tue Mar 18 04:11:30
2014
@@ -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)
@@ -1303,7 +1306,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
@@ -1551,6 +1554,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);
@@ -1592,6 +1596,11 @@
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 @@
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 @@
}
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 @@
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 @@
*
* 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 @@
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 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 @@
}
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 @@
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 @@
{
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 @@
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 @@
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 @@
/* ReactOS Check */
if (!ValidateHwnd(Wnd))
{
+ /* invalid window see wine menu.c test_menu_trackpopupmenu line 3146 */
return FALSE;
}
@@ -4823,7 +4815,7 @@
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;