LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
BOOL WINAPI GdiValidateHandle(HGDIOBJ hobj);
+LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
+void FASTCALL NcGetSysPopupPos(HWND Wnd, RECT *Rect);
WINE_DEFAULT_DEBUG_CHANNEL(menu);
#define TPM_BUTTONDOWN 0x40000000 /* menu was clicked before tracking */
#define TPM_POPUPMENU 0x20000000 /* menu is a popup menu */
+ /* Space between 2 columns */
+#define MENU_COL_SPACE 4
+
/* top and bottom margins for popup menus */
#define MENU_TOP_MARGIN 3
#define MENU_BOTTOM_MARGIN 2
*
* Validate the given menu handle and returns the menu structure pointer.
*/
-PMENU FORCEINLINE MENU_GetMenu(HMENU hMenu)
+FORCEINLINE PMENU MENU_GetMenu(HMENU hMenu)
+{
+ return ValidateHandleNoErr(hMenu, TYPE_MENU);
+}
+
+/***********************************************************************
+ * get_win_sys_menu
+ *
+ * Get the system menu of a window
+ */
+static HMENU get_win_sys_menu( HWND hwnd )
{
- return ValidateHandle(hMenu, TYPE_MENU);
+ HMENU ret = 0;
+ WND *win = ValidateHwnd( hwnd );
+ if (win)
+ {
+ ret = win->SystemMenu;
+ }
+ return ret;
}
/***********************************************************************
{
if (*nPos >= menu->cItems) return NULL;
pItem = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL;
- //pItem = &menu->rgItems[*nPos];
- i = 0;
- while(pItem) // Do this for now.
- {
- if (i < (INT)menu->cItems)
- {
- if ( *nPos == i ) return pItem;
- }
- pItem = pItem->Next ? DesktopPtrToUser(pItem->Next) : NULL;
- i++;
- }
+ if (pItem) pItem = &pItem[*nPos];
+ return pItem;
}
else
{
PITEM item = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL;
- for (i = 0; item ,i < menu->cItems; i++, item = item->Next ? DesktopPtrToUser(item->Next) : NULL)//, item++)
+ for (i = 0; item, i < menu->cItems; i++, item++)
{
if (item->spSubMenu)
{
UINT FASTCALL
IntGetMenuDefaultItem(PMENU Menu, BOOL fByPos, UINT gmdiFlags, DWORD *gismc)
{
- UINT x = 0;
- UINT res = -1;
- UINT sres;
+ UINT i = 0;
PITEM Item = Menu->rgItems ? DesktopPtrToUser(Menu->rgItems) : NULL;
- while(Item)
- {
- if (Item->fState & MFS_DEFAULT)
- {
- if (!(gmdiFlags & GMDI_USEDISABLED) &&
- (Item->fState & MFS_DISABLED) )
- break;
+ /* empty menu */
+ if (!Item) return -1;
- res = fByPos ? x : Item->wID;
+ while ( !( Item->fState & MFS_DEFAULT ) )
+ {
+ i++; Item++;
+ if (i >= Menu->cItems ) return -1;
+ }
- if ((*gismc < MAX_GOINTOSUBMENU) &&
- (gmdiFlags & GMDI_GOINTOPOPUPS) &&
- Item->spSubMenu)
- {
- if (DesktopPtrToUser(Item->spSubMenu) == Menu)
- break;
+ /* default: don't return disabled items */
+ if ( (!(GMDI_USEDISABLED & gmdiFlags)) && (Item->fState & MFS_DISABLED )) return -1;
- (*gismc)++;
- sres = IntGetMenuDefaultItem( DesktopPtrToUser(Item->spSubMenu), fByPos, gmdiFlags, gismc);
- (*gismc)--;
+ /* search rekursiv when needed */
+ if ( (Item->fType & MF_POPUP) && (gmdiFlags & GMDI_GOINTOPOPUPS) && Item->spSubMenu)
+ {
+ UINT ret;
+ (*gismc)++;
+ ret = IntGetMenuDefaultItem( DesktopPtrToUser(Item->spSubMenu), fByPos, gmdiFlags, gismc );
+ (*gismc)--;
+ if ( -1 != ret ) return ret;
- if(sres > (UINT)-1)
- res = sres;
- }
- break;
- }
- Item = Item->Next ? DesktopPtrToUser(Item->Next) : NULL;
- x++;
+ /* when item not found in submenu, return the popup item */
}
- return res;
+ return ( fByPos ) ? i : Item->wID;
}
static BOOL GetMenuItemInfo_common ( HMENU hmenu,
if (!pItem)
{
SetLastError( ERROR_MENU_ITEM_NOT_FOUND);
- //SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
lpmii->hbmpItem = pItem->hbmp;
if (lpmii->fMask & MIIM_STATE)
- lpmii->fState = pItem->fState & MII_STATE_MASK; //MENUITEMINFO_STATE_MASK;
+ lpmii->fState = pItem->fState & MENUITEMINFO_STATE_MASK;
if (lpmii->fMask & MIIM_ID)
lpmii->wID = pItem->wID;
MenuGetRosMenuInfo(PROSMENUINFO MenuInfo, HMENU Menu)
{
PMENU pMenu;
- if (!(pMenu = ValidateHandle(Menu, TYPE_MENU))) return FALSE;
+ if (!(pMenu = ValidateHandleNoErr(Menu, TYPE_MENU))) return FALSE;
MenuInfo->hbrBack = pMenu->hbrBack;
MenuInfo->dwContextHelpID = pMenu->dwContextHelpId;
ItemInfo->Rect.right = pItem->cxItem; // Do this for now......
ItemInfo->Rect.bottom = pItem->cyItem;
ItemInfo->dxTab = pItem->dxTab;
- ItemInfo->lpstr = pItem->lpstr.Buffer;
+ ItemInfo->lpstr = pItem->lpstr.Buffer ? DesktopPtrToUser(pItem->lpstr.Buffer) : NULL;
ItemInfo->maxBmpSize.cx = pItem->cxBmp;
ItemInfo->maxBmpSize.cy = pItem->cyBmp;
{
ItemInfo->cch = strlenW(ItemInfo->dwTypeData);
}
+ if (ItemInfo->hSubMenu)
+ {
+ if (!IsMenu(ItemInfo->hSubMenu)) ItemInfo->hSubMenu = NULL;
+ }
Ret = NtUserThunkedMenuItemInfo(Menu, Index, TRUE, FALSE, (LPMENUITEMINFOW)ItemInfo, NULL);
return Ret;
}
}
}
-DWORD FASTCALL
-IntBuildMenuItemList(PMENU MenuObject, PVOID Buffer, ULONG nMax)
-{
- DWORD res = 0;
- ROSMENUITEMINFO mii;
- PVOID Buf;
- PITEM CurItem = MenuObject->rgItems ? DesktopPtrToUser(MenuObject->rgItems) : NULL;
- PWCHAR StrOut;
- WCHAR NulByte;
-
- if (0 != nMax)
- {
- if (nMax < MenuObject->cItems * sizeof(ROSMENUITEMINFO))
- {
- return 0;
- }
- StrOut = (PWCHAR)((char *) Buffer + MenuObject->cItems * sizeof(ROSMENUITEMINFO));
- nMax -= MenuObject->cItems * sizeof(ROSMENUITEMINFO);
- Buf = Buffer;
- mii.cbSize = sizeof(ROSMENUITEMINFO);
- mii.fMask = 0;
- NulByte = L'\0';
-
- while (NULL != CurItem)
- {
- mii.cch = CurItem->lpstr.Length / sizeof(WCHAR);
- mii.dwItemData = CurItem->dwItemData;
- if (0 != CurItem->lpstr.Length)
- {
- mii.dwTypeData = StrOut;
- }
- else
- {
- mii.dwTypeData = NULL;
- }
- mii.fState = CurItem->fState;
- mii.fType = CurItem->fType;
- mii.wID = CurItem->wID;
- mii.hbmpChecked = CurItem->hbmpChecked;
- mii.hbmpItem = CurItem->hbmp;
- mii.hbmpUnchecked = CurItem->hbmpUnchecked;
- if (CurItem->spSubMenu)
- {
- PMENU pSubMenu = DesktopPtrToUser(CurItem->spSubMenu);
- HMENU hSubMenu = UserHMGetHandle(pSubMenu);
- mii.hSubMenu = hSubMenu;
- }
- else
- mii.hSubMenu = NULL;
- mii.Rect.left = CurItem->xItem;
- mii.Rect.top = CurItem->yItem;
- mii.Rect.right = CurItem->cxItem; // Do this for now......
- mii.Rect.bottom = CurItem->cyItem;
- mii.dxTab = CurItem->dxTab;
- mii.lpstr = CurItem->lpstr.Buffer; // Can be read from user side!
- //mii.maxBmpSize.cx = CurItem->cxBmp;
- //mii.maxBmpSize.cy = CurItem->cyBmp;
-
- RtlCopyMemory(Buf, &mii, sizeof(ROSMENUITEMINFO));
- Buf = (PVOID)((ULONG_PTR)Buf + sizeof(ROSMENUITEMINFO));
-
- if (0 != CurItem->lpstr.Length && (nMax >= CurItem->lpstr.Length + sizeof(WCHAR)))
- {
- LPWSTR lpstr = CurItem->lpstr.Buffer ? DesktopPtrToUser(CurItem->lpstr.Buffer) : NULL;
- if (lpstr)
- {
- /* Copy string */
- RtlCopyMemory(StrOut, lpstr, CurItem->lpstr.Length);
-
- StrOut += CurItem->lpstr.Length / sizeof(WCHAR);
- RtlCopyMemory(StrOut, &NulByte, sizeof(WCHAR));
- StrOut++;
- nMax -= CurItem->lpstr.Length + sizeof(WCHAR);
- }
- }
- else if (0 != CurItem->lpstr.Length)
- {
- break;
- }
-
- CurItem = CurItem->Next ? DesktopPtrToUser(CurItem->Next) : NULL;
- res++;
- }
- }
- else
- {
- while (NULL != CurItem)
- {
- res += sizeof(ROSMENUITEMINFO) + CurItem->lpstr.Length + sizeof(WCHAR);
- CurItem = CurItem->Next ? DesktopPtrToUser(CurItem->Next) : NULL;
- }
- }
- return res;
-}
-
-/***********************************************************************
- * MenuGetAllRosMenuItemInfo
- *
- * Get full information about all menu items
- */
-static INT FASTCALL
-MenuGetAllRosMenuItemInfo(HMENU Menu, PROSMENUITEMINFO *ItemInfo)
-{
- DWORD BufSize;
- PMENU pMenu;
-
- if (!(pMenu = ValidateHandle(Menu, TYPE_MENU))) return -1;
-
- BufSize = IntBuildMenuItemList(pMenu, (PVOID)1, 0);
- if (BufSize == (DWORD) -1 || BufSize == 0)
- {
- return -1;
- }
- *ItemInfo = HeapAlloc(GetProcessHeap(), 0, BufSize);
- if (NULL == *ItemInfo)
- {
- return -1;
- }
-
- return IntBuildMenuItemList(pMenu, (PVOID)*ItemInfo, BufSize);
-}
-
-/***********************************************************************
- * MenuCleanupAllRosMenuItemInfo
- *
- * Cleanup after use of MenuGetAllRosMenuItemInfo
- */
-static VOID FASTCALL
-MenuCleanupAllRosMenuItemInfo(PROSMENUITEMINFO ItemInfo)
-{
- HeapFree(GetProcessHeap(), 0, ItemInfo);
-}
-
/***********************************************************************
* MenuInitSysMenuPopup
*
* PROSMENUINFO MenuInfo)
*
*****************************************************************************/
-static UINT MenuGetStartOfNextColumn(
- PROSMENUINFO MenuInfo)
+
+static UINT MENU_GetStartOfNextColumn(
+ HMENU hMenu )
{
- PROSMENUITEMINFO MenuItems;
+ MENU *menu = MENU_GetMenu(hMenu);
+ PITEM pItem;
UINT i;
- i = MenuInfo->iItem;
- if ( i == NO_SELECTED_ITEM )
- return i;
+ if(!menu)
+ return NO_SELECTED_ITEM;
- if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &MenuItems) <= 0)
- return NO_SELECTED_ITEM;
+ i = menu->iItem + 1;
+ if( i == NO_SELECTED_ITEM )
+ return i;
- for (i++ ; i < MenuInfo->cItems; i++)
- if (0 != (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK)))
- return i;
+ pItem = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL;
+ if (!pItem) return NO_SELECTED_ITEM;
+ for( ; i < menu->cItems; ++i ) {
+ if (pItem[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK))
+ return i;
+ }
return NO_SELECTED_ITEM;
}
* PROSMENUINFO MenuInfo)
*
*****************************************************************************/
-
-static UINT FASTCALL MenuGetStartOfPrevColumn(
- PROSMENUINFO MenuInfo)
+static UINT MENU_GetStartOfPrevColumn(
+ HMENU hMenu )
{
- PROSMENUITEMINFO MenuItems;
- UINT i;
+ MENU *menu = MENU_GetMenu(hMenu);
+ UINT i;
+ PITEM pItem;
- if (!MenuInfo->iItem || MenuInfo->iItem == NO_SELECTED_ITEM)
- return NO_SELECTED_ITEM;
+ if( !menu )
+ return NO_SELECTED_ITEM;
- if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &MenuItems) <= 0)
- return NO_SELECTED_ITEM;
+ if( menu->iItem == 0 || menu->iItem == NO_SELECTED_ITEM )
+ return NO_SELECTED_ITEM;
+
+ pItem = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL;
+ if (!pItem) return NO_SELECTED_ITEM;
/* Find the start of the column */
- for (i = MenuInfo->iItem;
- 0 != i && 0 == (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK));
- --i)
- {
- ; /* empty */
- }
- if (i == 0)
- {
- MenuCleanupAllRosMenuItemInfo(MenuItems);
- return NO_SELECTED_ITEM;
- }
+ for(i = menu->iItem; i != 0 &&
+ !(pItem[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK));
+ --i); /* empty */
- for (--i; 0 != i; --i)
- if (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK))
- break;
+ if(i == 0)
+ return NO_SELECTED_ITEM;
+
+ for(--i; i != 0; --i) {
+ if (pItem[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK))
+ break;
+ }
- MenuCleanupAllRosMenuItemInfo(MenuItems);
TRACE("ret %d.\n", i );
return i;
return NO_SELECTED_ITEM;
item = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL;
- for (i = 0; i < menu->cItems; i++, item = item->Next ? DesktopPtrToUser(item->Next) : NULL)//item++)
+ for (i = 0; i < menu->cItems; i++, item++)
{
if (!item->spSubMenu)
continue;
* Find the menu item selected by a key press.
* Return item id, -1 if none, -2 if we should close the menu.
*/
-static UINT FASTCALL MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo,
+static UINT FASTCALL MENU_FindItemByKey(HWND WndOwner, HMENU hmenu,
WCHAR Key, BOOL ForceMenuChar)
{
- ROSMENUINFO SysMenuInfo;
- PROSMENUITEMINFO Items, ItemInfo;
LRESULT MenuChar;
- UINT i;
WORD Flags = 0;
- TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char) Key, Key, MenuInfo);
+ TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char)Key, Key, hmenu );
- if (NULL == MenuInfo || ! IsMenu(MenuInfo->Self))
+ if (!IsMenu( hmenu )) hmenu = GetSubMenu( get_win_sys_menu(WndOwner), 0);
+ if (hmenu)
{
- if (MenuGetRosMenuInfo(&SysMenuInfo, GetSystemMenu(WndOwner, FALSE)))
- {
- MenuInfo = &SysMenuInfo;
- }
- else
- {
- MenuInfo = NULL;
- }
- }
+ MENU *menu = MENU_GetMenu( hmenu );
+ ITEM *item = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL;
- if (NULL != MenuInfo)
- {
- if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &Items) <= 0)
- {
- return -1;
- }
- if ( !ForceMenuChar )
- {
- ItemInfo = Items;
- for (i = 0; i < MenuInfo->cItems; i++, ItemInfo++)
- {
- if ((ItemInfo->lpstr) && NULL != ItemInfo->dwTypeData)
+ if ( !ForceMenuChar )
+ {
+ UINT i;
+ BOOL cjk = GetSystemMetrics( SM_DBCSENABLED );
+
+ for (i = 0; i < menu->cItems; i++, item++)
+ {
+ LPWSTR text = item->Xlpstr ? DesktopPtrToUser(item->Xlpstr) : NULL;
+ if( text)
+ {
+ const WCHAR *p = text - 2;
+ do
{
- WCHAR *p = (WCHAR *) ItemInfo->dwTypeData - 2;
- do
- {
- p = strchrW (p + 2, '&');
- }
- while (p != NULL && p [1] == '&');
- if (p && (toupperW(p[1]) == toupperW(Key))) return i;
+ const WCHAR *q = p + 2;
+ p = strchrW (q, '&');
+ if (!p && cjk) p = strchrW (q, '\036'); /* Japanese Win16 */
}
- }
- }
+ while (p != NULL && p [1] == '&');
+ if (p && (toupperW(p[1]) == toupperW(Key))) return i;
+ }
+ }
+ }
- Flags |= MenuInfo->fFlags & MNF_POPUP ? MF_POPUP : 0;
- Flags |= MenuInfo->fFlags & MNF_SYSDESKMN ? MF_SYSMENU : 0;
+ Flags |= menu->fFlags & MNF_POPUP ? MF_POPUP : 0;
+ Flags |= menu->fFlags & MNF_SYSDESKMN ? MF_SYSMENU : 0;
- MenuChar = SendMessageW(WndOwner, WM_MENUCHAR,
- MAKEWPARAM(Key, Flags), (LPARAM) MenuInfo->Self);
- if (HIWORD(MenuChar) == MNC_EXECUTE) return LOWORD(MenuChar);
- if (HIWORD(MenuChar) == MNC_CLOSE) return (UINT)(-2);
- }
+ MenuChar = SendMessageW( WndOwner, WM_MENUCHAR,
+ MAKEWPARAM(Key, Flags), (LPARAM) hmenu);
+ if (HIWORD(MenuChar) == MNC_EXECUTE) return LOWORD(MenuChar);
+ if (HIWORD(MenuChar) == MNC_CLOSE) return (UINT)(-2);
+ }
return (UINT)(-1);
}
hfontOld = SelectObject( hdc, hMenuFontBold );
}
if (menuBar) {
- txtheight = DrawTextW( hdc, lpitem->dwTypeData, -1, &rc,
+ txtheight = DrawTextW( hdc, lpitem->lpstr, -1, &rc,
DT_SINGLELINE|DT_CALCRECT);
lpitem->Rect.right += rc.right - rc.left;
itemheight = max( max( itemheight, txtheight),
GetSystemMetrics( SM_CYMENU) - 1);
lpitem->Rect.right += 2 * MenuCharSize.cx;
} else {
- if ((p = strchrW( lpitem->dwTypeData, '\t' )) != NULL) {
+ if ((p = strchrW( lpitem->lpstr, '\t' )) != NULL) {
RECT tmprc = rc;
LONG tmpheight;
- int n = (int)( p - lpitem->dwTypeData);
+ int n = (int)( p - lpitem->lpstr);
/* Item contains a tab (only meaningful in popup menus) */
/* get text size before the tab */
- txtheight = DrawTextW( hdc, lpitem->dwTypeData, n, &rc,
+ txtheight = DrawTextW( hdc, lpitem->lpstr, n, &rc,
DT_SINGLELINE|DT_CALCRECT);
txtwidth = rc.right - rc.left;
p += 1; /* advance past the Tab */
txtwidth += MenuCharSize.cx + /* space for the tab */
tmprc.right - tmprc.left; /* space for the short cut */
} else {
- txtheight = DrawTextW( hdc, lpitem->dwTypeData, -1, &rc,
+ txtheight = DrawTextW( hdc, lpitem->lpstr, -1, &rc,
DT_SINGLELINE|DT_CALCRECT);
txtwidth = rc.right - rc.left;
lpitem->dxTab += txtwidth;
MenuInfo->cxTextAlign = 0;
MenuInitRosMenuItemInfo(&lpitem);
+ //MenuGetRosMenuItemInfo(MenuInfo->Self, start, &lpitem);
while (start < MenuInfo->cItems)
{
+ //lpitem = &lppop->items[start];
orgX = maxX;
- orgY = 2;
+ //if( lpitem.fType & (MF_MENUBREAK | MF_MENUBARBREAK))
+ // orgX += MENU_COL_SPACE;
+ orgY = 2;//MENU_TOP_MARGIN;
maxTab = maxTabWidth = 0;
-
/* Parse items until column break or end of menu */
- for (i = start; i < MenuInfo->cItems; i++)
+ for (i = start; i < MenuInfo->cItems; i++)//, lpitem++)
{
if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i, &lpitem))
{
if (i != start &&
(lpitem.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
- if( lpitem.lpstr && lpitem.hbmpItem) textandbmp = TRUE;
MenuCalcItemSize(hdc, &lpitem, MenuInfo, WndOwner, orgX, orgY, FALSE, textandbmp);
if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &lpitem))
MenuSetRosMenuInfo(MenuInfo);
return;
}
-// Not sure here,, The patch from wine removes this.
-// if ((lpitem.fType & MF_MENUBARBREAK) != 0)
-// {
-// OrgX++;
-// }
+
maxX = max(maxX, lpitem.Rect.right);
orgY = lpitem.Rect.bottom;
- if ((lpitem.lpstr) && lpitem.dxTab )
+ if (IS_STRING_ITEM(lpitem.fType) && lpitem.dxTab )
{
maxTab = max( maxTab, lpitem.dxTab );
maxTabWidth = max(maxTabWidth, lpitem.Rect.right - lpitem.dxTab);
}
- }
+ if( lpitem.lpstr && lpitem.hbmpItem) textandbmp = TRUE;
+ }
/* Finish the column (set all items to the largest width found) */
- maxX = max( maxX, maxTab + maxTabWidth );
- while (start < i)
- {
- if (MenuGetRosMenuItemInfo(MenuInfo->Self, start, &lpitem))
- {
- lpitem.Rect.right = maxX;
- if ((lpitem.lpstr) && 0 != lpitem.dxTab)
- {
- lpitem.dxTab = maxTab;
- }
- MenuSetRosMenuItemInfo(MenuInfo->Self, start, &lpitem);
- }
- start++;
- }
- MenuInfo->cyMenu = max(MenuInfo->cyMenu, orgY);
+ maxX = max( maxX, maxTab + maxTabWidth );
+ while (start < i)
+ {
+ if (MenuGetRosMenuItemInfo(MenuInfo->Self, start, &lpitem))
+ {
+ lpitem.Rect.right = maxX;
+ if (IS_STRING_ITEM(lpitem.fType) && lpitem.dxTab)
+ {
+ lpitem.dxTab = maxTab;
+ }
+ MenuSetRosMenuItemInfo(MenuInfo->Self, start, &lpitem);
+ }
+ start++;
+ }
+ MenuInfo->cyMenu = max(MenuInfo->cyMenu, orgY);
}
MenuInfo->cxMenu = maxX;
if ((lprect == NULL) || (MenuInfo == NULL)) return;
if (MenuInfo->cItems == 0) return;
- TRACE("left=%ld top=%ld right=%ld bottom=%ld\n", lprect->left, lprect->top, lprect->right, lprect->bottom);
+ TRACE("lprect %p %s\n", lprect, wine_dbgstr_rect( lprect));
MenuInfo->cxMenu = lprect->right - lprect->left;
MenuInfo->cyMenu = 0;
maxY = lprect->top + 1;
}
/* FIXME: Is this really needed? */ /*NO! it is not needed, why make the
-HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */
+ HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */
#if 0
/* Finish the line (set all items to the largest height found) */
while (start < i)
orgY = ItemInfo.Rect.top;
orgX = lprect->right;
for (i = MenuInfo->cItems - 1; helpPos <= i; i--)
- {
- if (i < helpPos)
- {
- break; /* done */
- }
- if (ItemInfo.Rect.top != orgY)
- {
- break; /* Other line */
- }
- if (orgX <= ItemInfo.Rect.right)
- {
- break; /* Too far right already */
- }
+ {
+ if (i < helpPos) break; /* done */
+ if (ItemInfo.Rect.top != orgY) break; /* Other line */
+ if (orgX <= ItemInfo.Rect.right) break; /* Too far right already */
ItemInfo.Rect.left += orgX - ItemInfo.Rect.right;
ItemInfo.Rect.right = orgX;
orgX = ItemInfo.Rect.left;
MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo);
if (helpPos + 1 <= i &&
! MenuGetRosMenuItemInfo(MenuInfo->Self, i - 1, &ItemInfo))
- {
+ {
MenuCleanupRosMenuItemInfo(&ItemInfo);
return;
- }
- }
+ }
+ }
}
MenuCleanupRosMenuItemInfo(&ItemInfo);
arrow_bitmap_width = bmp.bmWidth;
arrow_bitmap_height = bmp.bmHeight;
-
if (lppop->iTop)
hOrigBitmap = SelectObject(hdcMem, get_up_arrow_bitmap());
else
DeleteDC(hdcMem);
}
+/***********************************************************************
+ * draw_popup_arrow
+ *
+ * Draws the popup-menu arrow.
+ */
+static void draw_popup_arrow( HDC hdc, RECT rect, UINT arrow_bitmap_width,
+ UINT arrow_bitmap_height)
+{
+ HDC hdcMem = CreateCompatibleDC( hdc );
+ HBITMAP hOrigBitmap;
+
+ hOrigBitmap = SelectObject( hdcMem, get_arrow_bitmap() );
+ BitBlt( hdc, rect.right - arrow_bitmap_width - 1,
+ (rect.top + rect.bottom - arrow_bitmap_height) / 2,
+ arrow_bitmap_width, arrow_bitmap_height,
+ hdcMem, 0, 0, SRCCOPY );
+ SelectObject( hdcMem, hOrigBitmap );
+ DeleteDC( hdcMem );
+}
/***********************************************************************
* MenuDrawMenuItem
PWCHAR Text;
BOOL flat_menu = FALSE;
int bkgnd;
- PWND Wnd = ValidateHwnd(hWnd);
+ UINT arrow_bitmap_width = 0, arrow_bitmap_height = 0;
+ PWND Wnd = ValidateHwndNoErr(hWnd);
if (!Wnd)
return;
+ if (!menuBar) {
+ BITMAP bmp;
+ GetObjectW( get_arrow_bitmap(), sizeof(bmp), &bmp );
+ arrow_bitmap_width = bmp.bmWidth;
+ arrow_bitmap_height = bmp.bmHeight;
+ }
+
if (lpitem->fType & MF_SYSMENU)
{
if ( (Wnd->style & WS_MINIMIZE))
SetBkColor( hdc, GetSysColor( bkgnd ) );
}
+ TRACE("rect=%s\n", wine_dbgstr_rect( &lpitem->Rect));
rect = lpitem->Rect;
MENU_AdjustMenuItemRect(MenuInfo, &rect);
/* Draw the popup-menu arrow */
if (lpitem->hSubMenu)
{
- RECT rectTemp;
+ /* RECT rectTemp;
CopyRect(&rectTemp, &rect);
rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK);
DrawFrameControl(hdc, &rectTemp, DFC_MENU, DFCS_MENUARROW);
+ */
+ draw_popup_arrow( hdc, rect, arrow_bitmap_width, arrow_bitmap_height);
}
return;
}
HPEN oldPen;
RECT rc = rect;
- rc.left -= 3;
+ rc.left -= 3;//MENU_COL_SPACE / 2 + 1;
rc.top = 3;
rc.bottom = Height - 3;
if (flat_menu)
else if (lpitem->fState & MF_CHECKED) /* standard bitmaps */
{
RECT r;
+ //HBITMAP bm = CreateBitmap( check_bitmap_width, check_bitmap_height, 1, 1, NULL );
+ //HDC hdcMem = CreateCompatibleDC( hdc );
+ //SelectObject( hdcMem, bm );
+ //SetRect( &r, 0, 0, check_bitmap_width, check_bitmap_height);
CopyRect(&r, &rect);
r.right = r.left + GetSystemMetrics(SM_CXMENUCHECK);
DrawFrameControl( hdc, &r, DFC_MENU,
(lpitem->fType & MFT_RADIOCHECK) ?
DFCS_MENUBULLET : DFCS_MENUCHECK);
+ //BitBlt( hdc, rc.left, (y - r.bottom) / 2, r.right, r.bottom, hdcMem, 0, 0, SRCCOPY );
+ //DeleteDC( hdcMem );
+ //DeleteObject( bm );
checked = TRUE;
}
}
- if ( lpitem->hbmpItem )
+ if ( lpitem->hbmpItem )//&& !( checked && (MenuInfo->dwStyle & MNS_CHECKORBMP)))
{
RECT bmpRect;
CopyRect(&bmpRect, &rect);
bmpRect.left += check_bitmap_width + 2;
if (!(checked && (MenuInfo->dwStyle & MNS_CHECKORBMP)))
{
+ //POINT origorg;
bmpRect.right = bmpRect.left + lpitem->maxBmpSize.cx;
+ /* some applications make this assumption on the DC's origin */
+ //SetViewportOrgEx( hdc, rect.left, rect.top, &origorg);
MenuDrawBitmapItem(hdc, lpitem, &bmpRect, MenuInfo, WndOwner, odaction, menuBar);
+ //SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
}
}
/* Draw the popup-menu arrow */
if (lpitem->hSubMenu)
{
- RECT rectTemp;
+ /* RECT rectTemp;
CopyRect(&rectTemp, &rect);
rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK);
DrawFrameControl(hdc, &rectTemp, DFC_MENU, DFCS_MENUARROW);
+ */
+ draw_popup_arrow( hdc, rect, arrow_bitmap_width, arrow_bitmap_height);
}
rect.left += 4;
if( !(MenuInfo->dwStyle & MNS_NOCHECK))
rect.left += check_bitmap_width;
- rect.right -= check_bitmap_width;
+ rect.right -= arrow_bitmap_width;//check_bitmap_width;
}
else if( lpitem->hbmpItem)
{ /* Draw the bitmap */
+ //POINT origorg;
+
+ //SetViewportOrgEx( hdc, rect.left, rect.top, &origorg);
MenuDrawBitmapItem(hdc, lpitem, &rect, MenuInfo, WndOwner, odaction, menuBar);
+ //SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
}
/* process text if present */
{
register int i = 0;
HFONT hfontOld = 0;
-
UINT uFormat = menuBar ?
DT_CENTER | DT_VCENTER | DT_SINGLELINE :
DT_LEFT | DT_VCENTER | DT_SINGLELINE;
if((MenuInfo->dwStyle & MNS_CHECKORBMP))
- rect.left += max(0, MenuInfo->cxTextAlign - GetSystemMetrics(SM_CXMENUCHECK));
+ rect.left += max(0, (int)(MenuInfo->cxTextAlign - GetSystemMetrics(SM_CXMENUCHECK)));
else
rect.left += MenuInfo->cxTextAlign;
rect.right -= MENU_BAR_ITEMS_SPACE / 2;
}
- Text = (PWCHAR) lpitem->dwTypeData;
+ Text = lpitem->lpstr;
if(Text)
{
for (i = 0; L'\0' != Text[i]; i++)
else
DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT);
+ //TRACE("hmenu %p Style %08x\n", hmenu, menu->dwStyle);
/* draw menu items */
if (MenuGetRosMenuInfo(&MenuInfo, hmenu) && MenuInfo.cItems)
{
{
HWND WndOwner = MenuInfo.spwndNotify ? MenuInfo.spwndNotify->head.h : NULL;
MenuDrawMenuItem(hwnd, &MenuInfo, WndOwner, hdc, &ItemInfo,
- MenuInfo.cyMenu, FALSE, ODA_DRAWENTIRE);
+ MenuInfo.cyMenu, FALSE, ODA_DRAWENTIRE);
}
}
-
/* draw scroll arrows */
if (MenuInfo.dwArrowsOn)
MENU_DrawScrollArrows(&MenuInfo, hdc);
return DrawMenuBarTemp(hwnd, hDC, lprect, hMenu, NULL);
}
+/***********************************************************************
+ * MENU_InitPopup
+ *
+ * Popup menu initialization before WM_ENTERMENULOOP.
+ */
+static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags )
+{
+ MENU *menu;
+ DWORD ex_style = 0;
+ ROSMENUINFO MenuInfo;
+
+ TRACE("owner=%p hmenu=%p\n", hwndOwner, hmenu);
+
+ if (!(menu = MENU_GetMenu( hmenu ))) return FALSE;
+
+ /* store the owner for DrawItem */
+ if (!IsWindow( hwndOwner ))
+ {
+ SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+ return FALSE;
+ }
+ MenuGetRosMenuInfo(&MenuInfo, menu->head.h);
+ //menu->hwndOwner = hwndOwner;
+ MenuInfo.spwndNotify = ValidateHwndNoErr( hwndOwner );
+
+ if (flags & TPM_LAYOUTRTL)
+ ex_style = WS_EX_LAYOUTRTL;
+
+ /* NOTE: In Windows, top menu popup is not owned. */
+ //menu->hWnd = CreateWindowExW( ex_style, WC_MENU, NULL,
+ MenuInfo.Wnd = CreateWindowExW( ex_style, WC_MENU, NULL,
+ WS_POPUP, 0, 0, 0, 0,
+ hwndOwner, 0, (HINSTANCE)GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
+ (LPVOID)hmenu );
+ MenuSetRosMenuInfo(&MenuInfo);
+ if( !menu->hWnd ) return FALSE;
+ return TRUE;
+}
/***********************************************************************
* MenuShowPopup
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);
MenuInfo.iItem = NO_SELECTED_ITEM;
}
- /* store the owner for DrawItem */
- if (!IsWindow(hwndOwner))
- {
- SetLastError( ERROR_INVALID_WINDOW_HANDLE );
- return FALSE;
- }
- MenuInfo.spwndNotify = ValidateHwndNoErr(hwndOwner);
+ //menu->dwArrowsOn = 0;
+ MenuInfo.dwArrowsOn = 0;
MenuSetRosMenuInfo(&MenuInfo);
-
MenuPopupMenuCalcSize(&MenuInfo, hwndOwner);
/* adjust popup menu pos so that it fits within the desktop */
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;
}
if( y < info.rcMonitor.top ) y = info.rcMonitor.top;
- /* NOTE: In Windows, top menu popup is not owned. */
- MenuInfo.Wnd = CreateWindowExW( ex_style, WC_MENU, NULL,
- WS_POPUP, x, y, width, height,
- hwndOwner, 0, (HINSTANCE) GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
- (LPVOID) MenuInfo.Self);
- if ( !MenuInfo.Wnd || ! MenuSetRosMenuInfo(&MenuInfo)) return FALSE;
if (!top_popup) {
top_popup = MenuInfo.Wnd;
top_popup_hmenu = hmenu;
}
-
- IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
-
/* Display the window */
- SetWindowPos( MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0,
- SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+ SetWindowPos( MenuInfo.Wnd, HWND_TOPMOST, x, y, width, height,
+ SWP_SHOWWINDOW | SWP_NOACTIVATE);
UpdateWindow( MenuInfo.Wnd );
+
+ IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
+
return TRUE;
}
ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
MenuSetRosMenuItemInfo(hmenu->Self, hmenu->iItem, &ItemInfo);
}
- //MENU_EnsureMenuItemVisible(hmenu, &ItemInfo, hdc);
MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc, &ItemInfo,
hmenu->cyMenu, !(hmenu->fFlags & MNF_POPUP),
ODA_SELECT);
ItemInfo.fMask |= MIIM_STATE;
ItemInfo.fState |= MF_HILITE;
MenuSetRosMenuItemInfo(hmenu->Self, hmenu->iItem, &ItemInfo);
+ MENU_EnsureMenuItemVisible(hmenu, &ItemInfo, hdc);
MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc,
- &ItemInfo, hmenu->cyMenu, !(hmenu->fFlags & MNF_POPUP),
- ODA_SELECT);
+ &ItemInfo, hmenu->cyMenu, !(hmenu->fFlags & MNF_POPUP), ODA_SELECT);
}
if (sendMenuSelect)
{
PWND pWnd;
PPOPUPMENU pPopupMenu;
- pWnd = ValidateHwnd(Wnd);
+ pWnd = ValidateHwndNoErr(Wnd);
if (pWnd)
{
if (!pWnd->fnid)
}
break;
+#ifdef __REACTOS__
+ case WM_NCDESTROY:
+ NtUserSetWindowFNID(Wnd, FNID_DESTROY);
+ break;
+#endif
+
case WM_SHOWWINDOW:
if (0 != wParam)
{
return res;
}
-
/**********************************************************************
* MENUEX_ParseResource
*
TRACE("Menu item: [%08x,%08x,%04x,%04x,%S]\n",
mii.fType, mii.fState, mii.wID, resinfo, mii.dwTypeData);
- if (resinfo & 1) /* Pop-up? */
- {
+ if (resinfo & 1) /* Pop-up? */
+ {
/* DWORD helpid = GET_DWORD(res); FIXME: use this. */
res += sizeof(DWORD);
mii.hSubMenu = CreatePopupMenu();
}
else if (!mii.dwTypeData[0] && !(mii.fType & MF_SEPARATOR))
{
+ WARN("Converting NULL menu item %04x, type %04x to SEPARATOR\n",
+ mii.wID, mii.fType);
mii.fType |= MF_SEPARATOR;
}
InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
return res;
}
-NTSTATUS WINAPI
-User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength)
+
+/***********************************************************************
+ * DrawMenuBarTemp (USER32.@)
+ *
+ * UNDOCUMENTED !!
+ *
+ * called by W98SE desk.cpl Control Panel Applet
+ *
+ * Not 100% sure about the param names, but close.
+ *
+ * @implemented
+ */
+DWORD WINAPI
+DrawMenuBarTemp(HWND Wnd, HDC DC, LPRECT Rect, HMENU Menu, HFONT Font)
{
- HMENU hmenu = LoadMenuW(User32Instance, L"SYSMENU");
- LRESULT Result = (LRESULT)hmenu;
- MENUINFO menuinfo = {0};
- MENUITEMINFOW info = {0};
-
- // removing space for checkboxes from menu
- menuinfo.cbSize = sizeof(menuinfo);
- menuinfo.fMask = MIM_STYLE;
- GetMenuInfo(hmenu, &menuinfo);
- menuinfo.dwStyle |= MNS_CHECKORBMP; // test_menu_bmp_and_string MNS_CHECKORBMP
- SetMenuInfo(hmenu, &menuinfo);
-
- // adding bitmaps to menu items
- info.cbSize = sizeof(info);
- info.fMask |= MIIM_BITMAP;
- info.hbmpItem = HBMMENU_POPUP_MINIMIZE;
- SetMenuItemInfoW(hmenu, SC_MINIMIZE, FALSE, &info);
- info.hbmpItem = HBMMENU_POPUP_RESTORE;
- SetMenuItemInfoW(hmenu, SC_RESTORE, FALSE, &info);
- info.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
- SetMenuItemInfoW(hmenu, SC_MAXIMIZE, FALSE, &info);
- info.hbmpItem = HBMMENU_POPUP_CLOSE;
- SetMenuItemInfoW(hmenu, SC_CLOSE, FALSE, &info);
+ ROSMENUINFO MenuInfo;
+ ROSMENUITEMINFO ItemInfo;
+ UINT i;
+ HFONT FontOld = NULL;
+ BOOL flat_menu = FALSE;
- return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
-}
+ SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
-
-BOOL
-MenuInit(VOID)
-{
- NONCLIENTMETRICSW ncm;
-
- /* get the menu font */
- if(!hMenuFont || !hMenuFontBold)
- {
- ncm.cbSize = sizeof(ncm);
- if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0))
- {
- ERR("MenuInit(): SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed!\n");
- return FALSE;
- }
-
- hMenuFont = CreateFontIndirectW(&ncm.lfMenuFont);
- if(hMenuFont == NULL)
- {
- ERR("MenuInit(): CreateFontIndirectW(hMenuFont) failed!\n");
- return FALSE;
- }
-
- ncm.lfMenuFont.lfWeight = max(ncm.lfMenuFont.lfWeight + 300, 1000);
- hMenuFontBold = CreateFontIndirectW(&ncm.lfMenuFont);
- if(hMenuFontBold == NULL)
- {
- ERR("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n");
- DeleteObject(hMenuFont);
- hMenuFont = NULL;
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-VOID
-MenuCleanup(VOID)
-{
- if (hMenuFont)
- {
- DeleteObject(hMenuFont);
- hMenuFont = NULL;
- }
-
- if (hMenuFontBold)
- {
- DeleteObject(hMenuFontBold);
- hMenuFontBold = NULL;
- }
-}
-
-/***********************************************************************
- * DrawMenuBarTemp (USER32.@)
- *
- * UNDOCUMENTED !!
- *
- * called by W98SE desk.cpl Control Panel Applet
- *
- * Not 100% sure about the param names, but close.
- *
- * @implemented
- */
-DWORD WINAPI
-DrawMenuBarTemp(HWND Wnd, HDC DC, LPRECT Rect, HMENU Menu, HFONT Font)
-{
- ROSMENUINFO MenuInfo;
- ROSMENUITEMINFO ItemInfo;
- UINT i;
- HFONT FontOld = NULL;
- BOOL flat_menu = FALSE;
-
- SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
-
- if (NULL == Menu)
- {
- Menu = GetMenu(Wnd);
- }
+ if (NULL == Menu)
+ {
+ Menu = GetMenu(Wnd);
+ }
if (NULL == Font)
{
return MenuInfo.cyMenu;
}
-#if 0
-static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags )
-{
- POPUPMENU *menu;
- DWORD ex_style = 0;
-
- TRACE("owner=%p hmenu=%p\n", hwndOwner, hmenu);
-
- if (!(menu = MENU_GetMenu( hmenu ))) return FALSE;
-
- /* store the owner for DrawItem */
- if (!IsWindow( hwndOwner ))
- {
- SetLastError( ERROR_INVALID_WINDOW_HANDLE );
- return FALSE;
- }
- menu->hwndOwner = hwndOwner;
- if (flags & TPM_LAYOUTRTL)
- ex_style = WS_EX_LAYOUTRTL;
- /* NOTE: In Windows, top menu popup is not owned. */
- menu->hWnd = CreateWindowExW( ex_style, (LPCWSTR)POPUPMENU_CLASS_ATOM, NULL,
- WS_POPUP, 0, 0, 0, 0,
- hwndOwner, 0, (HINSTANCE)GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
- (LPVOID)hmenu );
- if( !menu->hWnd ) return FALSE;
- return TRUE;
-}
-#endif
/***********************************************************************
* MenuShowSubPopup
*
static HMENU FASTCALL
MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Flags)
{
- extern void FASTCALL NcGetSysPopupPos(HWND Wnd, RECT *Rect);
RECT Rect;
ROSMENUITEMINFO ItemInfo;
ROSMENUINFO SubMenuInfo;
TRACE("owner=%x menu=%p 0x%04x\n", WndOwner, MenuInfo, SelectFirst);
- if (NO_SELECTED_ITEM == MenuInfo->iItem)
- {
- return MenuInfo->Self;
- }
+ if (MenuInfo->iItem == NO_SELECTED_ITEM) return MenuInfo->Self;
MenuInitRosMenuItemInfo(&ItemInfo);
if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo))
- {
+ {
MenuCleanupRosMenuItemInfo(&ItemInfo);
return MenuInfo->Self;
- }
- if (0 == (ItemInfo.hSubMenu) || 0 != (ItemInfo.fState & (MF_GRAYED | MF_DISABLED)))
- {
+ }
+
+ //item = &menu->rgItems[menu->iItem];
+ if (!(ItemInfo.hSubMenu) || (ItemInfo.fState & (MF_GRAYED | MF_DISABLED)))
+ {
MenuCleanupRosMenuItemInfo(&ItemInfo);
return MenuInfo->Self;
- }
+ }
/* message must be sent before using item,
because nearly everything may be changed by the application ! */
/* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
- if (0 == (Flags & TPM_NONOTIFY))
- {
+ if (!(Flags & TPM_NONOTIFY))
+ {
SendMessageW(WndOwner, WM_INITMENUPOPUP, (WPARAM) ItemInfo.hSubMenu,
MAKELPARAM(MenuInfo->iItem, IS_SYSTEM_MENU(MenuInfo)));
- }
+ }
if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo))
- {
+ {
MenuCleanupRosMenuItemInfo(&ItemInfo);
return MenuInfo->Self;
- }
+ }
+
+ //item = &menu->rgItems[menu->iItem];
Rect = ItemInfo.Rect;
/* correct item if modified as a reaction to WM_INITMENUPOPUP message */
- if (0 == (ItemInfo.fState & MF_HILITE))
- {
- if (0 != (MenuInfo->fFlags & MNF_POPUP))
- {
- Dc = GetDC(MenuInfo->Wnd);
- }
- else
- {
- Dc = GetDCEx(MenuInfo->Wnd, 0, DCX_CACHE | DCX_WINDOW);
- }
+ if (!(ItemInfo.fState & MF_HILITE))
+ {
+ if (MenuInfo->fFlags & MNF_POPUP) Dc = GetDC(MenuInfo->Wnd);
+ else Dc = GetDCEx(MenuInfo->Wnd, 0, DCX_CACHE | DCX_WINDOW);
SelectObject(Dc, hMenuFont);
ItemInfo.fMask |= MIIM_STATE;
MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo, MenuInfo->cyMenu,
!(MenuInfo->fFlags & MNF_POPUP), ODA_DRAWENTIRE);
ReleaseDC(MenuInfo->Wnd, Dc);
- }
+ }
- if (0 == ItemInfo.Rect.top && 0 == ItemInfo.Rect.left
- && 0 == ItemInfo.Rect.bottom && 0 == ItemInfo.Rect.right)
- {
+ if (!ItemInfo.Rect.top && !ItemInfo.Rect.left && !ItemInfo.Rect.bottom && !ItemInfo.Rect.right)
ItemInfo.Rect = Rect;
- }
ItemInfo.fMask |= MIIM_STATE;
ItemInfo.fState |= MF_MOUSESELECT;
if (IS_SYSTEM_MENU(MenuInfo))
{
- ERR("Right click on window bar and Draw system menu!\n");
- MenuInitSysMenuPopup(ItemInfo.hSubMenu, GetWindowLongPtrW(MenuInfo->Wnd, GWL_STYLE),
+ MenuInitSysMenuPopup(ItemInfo.hSubMenu,
+ GetWindowLongPtrW(MenuInfo->Wnd, GWL_STYLE),
GetClassLongPtrW(MenuInfo->Wnd, GCL_STYLE), HTSYSMENU);
- if (Flags & TPM_LAYOUTRTL) Rect.left;
+
NcGetSysPopupPos(MenuInfo->Wnd, &Rect);
+ if (Flags & TPM_LAYOUTRTL) Rect.left = Rect.right;
Rect.top = Rect.bottom;
Rect.right = GetSystemMetrics(SM_CXSIZE);
Rect.bottom = GetSystemMetrics(SM_CYSIZE);
else
{
GetWindowRect(MenuInfo->Wnd, &Rect);
- if (0 != (MenuInfo->fFlags & MNF_POPUP))
+ if (MenuInfo->fFlags & MNF_POPUP)
{
RECT rc = ItemInfo.Rect;
MENU_AdjustMenuItemRect(MenuInfo, &rc);
+ /* The first item in the popup menu has to be at the
+ same y position as the focused menu item */
if(Flags & TPM_LAYOUTRTL)
Rect.left += GetSystemMetrics(SM_CXBORDER);
else
- Rect.left += ItemInfo.Rect.right- GetSystemMetrics(SM_CXBORDER);
+ Rect.left += rc.right /*ItemInfo.Rect.right*/ - GetSystemMetrics(SM_CXBORDER);
Rect.top += rc.top - MENU_TOP_MARGIN;//3;
Rect.right = rc.left - rc.right + GetSystemMetrics(SM_CXBORDER);
Rect.bottom = rc.top - rc.bottom - MENU_TOP_MARGIN - MENU_BOTTOM_MARGIN/*2*/
/* use default alignment for submenus */
Flags &= ~(TPM_CENTERALIGN | TPM_RIGHTALIGN | TPM_VCENTERALIGN | TPM_BOTTOMALIGN);
- //MENU_InitPopup( WndOwner, ItemInfo.hSubMenu, Flags );
+ MENU_InitPopup( WndOwner, ItemInfo.hSubMenu, Flags );
MenuShowPopup(WndOwner, ItemInfo.hSubMenu, MenuInfo->iItem, Flags,
Rect.left, Rect.top, Rect.right, Rect.bottom );
*/
void MENU_EndMenu( HWND hwnd )
{
- ROSMENUINFO MenuInfo;
- BOOL Ret = FALSE;
- if (top_popup_hmenu)
- Ret = MenuGetRosMenuInfo(&MenuInfo, top_popup_hmenu);
- if (Ret && hwnd == (MenuInfo.spwndNotify ? MenuInfo.spwndNotify->head.h : NULL)) EndMenu();
+ MENU *menu;
+ menu = top_popup_hmenu ? MENU_GetMenu( top_popup_hmenu ) : NULL;
+ if (menu && ( hwnd == menu->hWnd || hwnd == (menu->spwndNotify ? menu->spwndNotify->head.h : NULL)) )
+ EndMenu();
}
/***********************************************************************
TRACE("owner=%x menu=%x 0x%04x\n", WndOwner, MenuInfo, SendMenuSelect);
- if (NULL != MenuInfo && NULL != top_popup && NO_SELECTED_ITEM != MenuInfo->iItem)
+ if (MenuInfo && top_popup && NO_SELECTED_ITEM != MenuInfo->iItem)
{
+ //item = &menu->rgItems[menu->iItem];
MenuInitRosMenuItemInfo(&ItemInfo);
ItemInfo.fMask |= MIIM_FTYPE | MIIM_STATE;
if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo)
- || 0 == (ItemInfo.hSubMenu)
- || 0 == (ItemInfo.fState & MF_MOUSESELECT))
+ || !(ItemInfo.hSubMenu)
+ || !(ItemInfo.fState & MF_MOUSESELECT))
{
MenuCleanupRosMenuItemInfo(&ItemInfo);
return;
{
MenuHideSubPopups(WndOwner, &SubMenuInfo, FALSE, wFlags);
MenuSelectItem(WndOwner, &SubMenuInfo, NO_SELECTED_ITEM, SendMenuSelect, NULL);
- DestroyWindow(SubMenuInfo.Wnd);
- SubMenuInfo.Wnd = NULL;
- MenuSetRosMenuInfo(&SubMenuInfo);
+ DestroyWindow(SubMenuInfo.Wnd);
+ /* Native returns handle to destroyed window */
if (!(wFlags & TPM_NONOTIFY))
SendMessageW( WndOwner, WM_UNINITMENUPOPUP, (WPARAM)ItemInfo.hSubMenu,
MAKELPARAM(0, IS_SYSTEM_MENU(&SubMenuInfo)) );
+ ////
+ // Call WM_UNINITMENUPOPUP FIRST before destroy!!
+ // Fixes todo_wine User32 test menu.c line 2233 GetMenuBarInfo callback....
+ //
+ SubMenuInfo.Wnd = NULL;
+ MenuSetRosMenuInfo(&SubMenuInfo);
+ ////
}
}
}
TRACE("%x menu=%x 0x%04x\n", Mt, PtMenuInfo->Self, Index);
- if (MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu) &&
- Mt->TopMenu != PtMenuInfo->Self &&
- 0 == ((PtMenuInfo->fFlags | TopMenuInfo.fFlags) & MNF_POPUP))
- {
+ if ( MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu) &&
+ Mt->TopMenu != PtMenuInfo->Self &&
+ !((PtMenuInfo->fFlags | TopMenuInfo.fFlags) & MNF_POPUP) )
+ {
/* both are top level menus (system and menu-bar) */
MenuHideSubPopups(Mt->OwnerWnd, &TopMenuInfo, FALSE, wFlags);
MenuSelectItem(Mt->OwnerWnd, &TopMenuInfo, NO_SELECTED_ITEM, FALSE, NULL);
Mt->TopMenu = PtMenuInfo->Self;
- }
+ }
else
- {
+ {
MenuHideSubPopups(Mt->OwnerWnd, PtMenuInfo, FALSE, wFlags);
- }
+ }
MenuSelectItem(Mt->OwnerWnd, PtMenuInfo, Index, TRUE, NULL);
}
TRACE("%p menu=%p\n", Mt, MenuInfo);
if (0 == MenuInfo->cItems || NO_SELECTED_ITEM == MenuInfo->iItem)
- {
+ {
return -1;
- }
+ }
MenuInitRosMenuItemInfo(&ItemInfo);
if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo))
- {
+ {
MenuCleanupRosMenuItemInfo(&ItemInfo);
return -1;
- }
+ }
TRACE("%p %08x %p\n", MenuInfo, ItemInfo.wID, ItemInfo.hSubMenu);
if (0 == (ItemInfo.hSubMenu))
- {
+ {
if (0 == (ItemInfo.fState & (MF_GRAYED | MF_DISABLED))
&& 0 == (ItemInfo.fType & MF_SEPARATOR))
- {
+ {
/* If TPM_RETURNCMD is set you return the id, but
do not send a message to the owner */
if (0 == (Flags & TPM_RETURNCMD))
- {
+ {
if (0 != (MenuInfo->fFlags & MNF_SYSDESKMN))
- {
+ {
PostMessageW(Mt->OwnerWnd, WM_SYSCOMMAND, ItemInfo.wID,
MAKELPARAM((SHORT) Mt->Pt.x, (SHORT) Mt->Pt.y));
- }
+ }
else
- {
+ {
ROSMENUINFO topmenuI;
BOOL ret = MenuGetRosMenuInfo(&topmenuI, Mt->TopMenu);
DWORD dwStyle = MenuInfo->dwStyle | (ret ? topmenuI.dwStyle : 0);
PostMessageW(Mt->OwnerWnd, WM_MENUCOMMAND, MenuInfo->iItem, (LPARAM)MenuInfo->Self);
else
PostMessageW(Mt->OwnerWnd, WM_COMMAND, ItemInfo.wID, 0);
- }
- }
+ }
+ }
wID = ItemInfo.wID;
MenuCleanupRosMenuItemInfo(&ItemInfo);
return wID;
- }
- }
+ }
+ }
else
- {
+ {
Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, MenuInfo, TRUE, Flags);
return -2;
- }
+ }
return -1;
}
* Return TRUE if we can go on with menu tracking.
*/
static BOOL FASTCALL
-MenuButtonDown(MTRACKER* Mt, HMENU PtMenu, UINT Flags)
+MENU_ButtonDown(MTRACKER* Mt, HMENU PtMenu, UINT Flags)
{
int Index;
ROSMENUINFO MenuInfo;
TRACE("%x PtMenu=%p\n", Mt, PtMenu);
if (NULL != PtMenu)
- {
+ {
if (! MenuGetRosMenuInfo(&MenuInfo, PtMenu))
- {
+ {
return FALSE;
- }
+ }
if (IS_SYSTEM_MENU(&MenuInfo))
- {
+ {
Index = 0;
- }
+ }
else
- {
+ {
Index = NtUserMenuItemFromPoint(Mt->OwnerWnd, PtMenu, Mt->Pt.x, Mt->Pt.y);
- }
+ }
MenuInitRosMenuItemInfo(&Item);
if (NO_SELECTED_ITEM == Index || ! MenuGetRosMenuItemInfo(PtMenu, Index, &Item))
- {
+ {
MenuCleanupRosMenuItemInfo(&Item);
return FALSE;
- }
+ }
if (!(Item.fType & MF_SEPARATOR) &&
!(Item.fState & (MFS_DISABLED | MFS_GRAYED)) )
- {
+ {
if (MenuInfo.iItem != Index)
- {
+ {
MenuSwitchTracking(Mt, &MenuInfo, Index, Flags);
- }
+ }
/* If the popup menu is not already "popped" */
if (0 == (Item.fState & MF_MOUSESELECT))
- {
+ {
Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
- }
- }
+ }
+ }
MenuCleanupRosMenuItemInfo(&Item);
*
*/
static INT FASTCALL
-MenuButtonUp(MTRACKER *Mt, HMENU PtMenu, UINT Flags)
+MENU_ButtonUp(MTRACKER *Mt, HMENU PtMenu, UINT Flags)
{
INT Id;
ROSMENUINFO MenuInfo;
TRACE("%p hmenu=%x\n", Mt, PtMenu);
if (NULL != PtMenu)
- {
+ {
Id = 0;
if (! MenuGetRosMenuInfo(&MenuInfo, PtMenu))
- {
+ {
return -1;
- }
+ }
if (! IS_SYSTEM_MENU(&MenuInfo))
- {
+ {
Id = NtUserMenuItemFromPoint(Mt->OwnerWnd, MenuInfo.Self, Mt->Pt.x, Mt->Pt.y);
- }
+ }
MenuInitRosMenuItemInfo(&ItemInfo);
if (0 <= Id && MenuGetRosMenuItemInfo(MenuInfo.Self, Id, &ItemInfo) &&
MenuInfo.iItem == Id)
- {
+ {
if (0 == (ItemInfo.hSubMenu))
- {
+ {
INT ExecutedMenuId = MenuExecFocusedItem(Mt, &MenuInfo, Flags);
MenuCleanupRosMenuItemInfo(&ItemInfo);
return (ExecutedMenuId < 0) ? -1 : ExecutedMenuId;
- }
+ }
MenuCleanupRosMenuItemInfo(&ItemInfo);
/* If we are dealing with the top-level menu */
/* and this is a click on an already "popped" item: */
/* Stop the menu tracking and close the opened submenus */
if (Mt->TopMenu == MenuInfo.Self && MenuInfo.TimeToHide)
- {
+ {
MenuCleanupRosMenuItemInfo(&ItemInfo);
return 0;
- }
- }
+ }
+ }
MenuCleanupRosMenuItemInfo(&ItemInfo);
MenuInfo.TimeToHide = TRUE;
MenuSetRosMenuInfo(&MenuInfo);
- }
+ }
return -1;
}
* Walks menu chain trying to find a menu pt maps to.
*/
static HMENU FASTCALL
-MenuPtMenu(HMENU Menu, POINT Pt)
+MENU_PtMenu(HMENU hMenu, POINT pt)
{
- extern LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
- ROSMENUINFO MenuInfo;
- ROSMENUITEMINFO ItemInfo;
- HMENU Ret = NULL;
- INT Ht;
+ MENU *menu;
+ PITEM pItem;
+ HMENU ret = NULL;
- if (! MenuGetRosMenuInfo(&MenuInfo, Menu))
- {
- return NULL;
- }
+ menu = MENU_GetMenu( hMenu );
+ if (!menu) return NULL;
/* try subpopup first (if any) */
- if (NO_SELECTED_ITEM != MenuInfo.iItem)
- {
- MenuInitRosMenuItemInfo(&ItemInfo);
- if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.iItem, &ItemInfo) &&
- 0 != (ItemInfo.hSubMenu) &&
- 0 != (ItemInfo.fState & MF_MOUSESELECT))
- {
- Ret = MenuPtMenu(ItemInfo.hSubMenu, Pt);
- if (NULL != Ret)
- {
- MenuCleanupRosMenuItemInfo(&ItemInfo);
- return Ret;
- }
- }
- MenuCleanupRosMenuItemInfo(&ItemInfo);
- }
+ if (menu->iItem != NO_SELECTED_ITEM)
+ {
+ pItem = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL;
+ if ( pItem ) pItem = &pItem[menu->iItem];
+ if ( pItem && pItem->spSubMenu && pItem->fState & MF_MOUSESELECT)
+ {
+ PMENU pSubMenu = DesktopPtrToUser(pItem->spSubMenu);
+ ret = MENU_PtMenu( UserHMGetHandle(pSubMenu), pt);
+ }
+ }
/* check the current window (avoiding WM_HITTEST) */
- Ht = DefWndNCHitTest(MenuInfo.Wnd, Pt);
- if (0 != (MenuInfo.fFlags & MNF_POPUP))
- {
- if (HTNOWHERE != Ht && HTERROR != Ht)
- {
- Ret = Menu;
- }
- }
- else if (HTSYSMENU == Ht)
- {
- Ret = NtUserGetSystemMenu(MenuInfo.Wnd, FALSE);
- }
- else if (HTMENU == Ht)
- {
- Ret = GetMenu(MenuInfo.Wnd);
- }
-
- return Ret;
+ if (!ret)
+ {
+ INT ht = DefWndNCHitTest(menu->hWnd, pt);
+ if ( menu->fFlags & MNF_POPUP )
+ {
+ if (ht != HTNOWHERE && ht != HTERROR) ret = hMenu;
+ }
+ else if (ht == HTSYSMENU)
+ ret = NtUserGetSystemMenu(menu->hWnd, FALSE);
+ else if (ht == HTMENU)
+ ret = GetMenu( menu->hWnd );
+ }
+ return ret;
}
/***********************************************************************
ROSMENUITEMINFO ItemInfo;
if (NULL != PtMenu)
- {
+ {
if (! MenuGetRosMenuInfo(&MenuInfo, PtMenu))
- {
+ {
return TRUE;
- }
+ }
if (IS_SYSTEM_MENU(&MenuInfo))
- {
+ {
Index = 0;
- }
+ }
else
- {
+ {
Index = NtUserMenuItemFromPoint(Mt->OwnerWnd, PtMenu, Mt->Pt.x, Mt->Pt.y);
- }
- }
+ }
+ }
else
- {
+ {
Index = NO_SELECTED_ITEM;
- }
+ }
if (NO_SELECTED_ITEM == Index)
- {
+ {
if (Mt->CurrentMenu == MenuInfo.Self ||
MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
- {
+ {
MenuSelectItem(Mt->OwnerWnd, &MenuInfo, NO_SELECTED_ITEM,
TRUE, Mt->TopMenu);
- }
- }
+ }
+ }
else if (MenuInfo.iItem != Index)
- {
+ {
MenuInitRosMenuItemInfo(&ItemInfo);
if (MenuGetRosMenuItemInfo(MenuInfo.Self, Index, &ItemInfo) &&
- !(ItemInfo.fType & MF_SEPARATOR))
+ !(ItemInfo.fType & MF_SEPARATOR))
{
MenuSwitchTracking(Mt, &MenuInfo, Index, Flags);
- if (!(ItemInfo.fState & (MFS_DISABLED | MFS_GRAYED)))
+ if (!(ItemInfo.fState & (MFS_DISABLED | MFS_GRAYED)))
Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
}
MenuCleanupRosMenuItemInfo(&ItemInfo);
- }
+ }
return TRUE;
}
*
* Return the handle of the selected sub-popup menu (if any).
*/
-static HMENU FASTCALL
-MenuGetSubPopup(HMENU Menu)
+static
+HMENU MENU_GetSubPopup( HMENU hmenu )
{
- ROSMENUINFO MenuInfo;
- ROSMENUITEMINFO ItemInfo;
+ MENU *menu;
+ ITEM *item;
- if (! MenuGetRosMenuInfo(&MenuInfo, Menu)
- || NO_SELECTED_ITEM == MenuInfo.iItem)
- {
- return NULL;
- }
+ menu = MENU_GetMenu( hmenu );
- MenuInitRosMenuItemInfo(&ItemInfo);
- if (! MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.iItem, &ItemInfo))
- {
- MenuCleanupRosMenuItemInfo(&ItemInfo);
- return NULL;
- }
- if (0 != (ItemInfo.hSubMenu) && 0 != (ItemInfo.fState & MF_MOUSESELECT))
+ if ((!menu) || (menu->iItem == NO_SELECTED_ITEM)) return 0;
+
+ //item = &menu->rgItems[menu->iItem];
+ item = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL;
+ if (item) item = &item[menu->iItem];
+ if (item && (item->spSubMenu) && (item->fState & MF_MOUSESELECT))
{
- MenuCleanupRosMenuItemInfo(&ItemInfo);
- return ItemInfo.hSubMenu;
+ PMENU pSubMenu = DesktopPtrToUser(item->spSubMenu);
+ return UserHMGetHandle(pSubMenu);
}
-
- MenuCleanupRosMenuItemInfo(&ItemInfo);
- return NULL;
+ return 0;
}
/***********************************************************************
ROSMENUINFO MenuInfo;
if (! MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
- {
+ {
return (LRESULT) FALSE;
- }
+ }
if ((VK_LEFT == Vk && 0 == TopMenuInfo.iItem)
|| (VK_RIGHT == Vk && TopMenuInfo.iItem == TopMenuInfo.cItems - 1))
- {
+ {
MDINEXTMENU NextMenu;
HMENU NewMenu;
HWND NewWnd;
Mt->CurrentMenu, Mt->OwnerWnd, NextMenu.hmenuNext, NextMenu.hwndNext );
if (NULL == NextMenu.hmenuNext || NULL == NextMenu.hwndNext)
- {
+ {
DWORD Style = GetWindowLongPtrW(Mt->OwnerWnd, GWL_STYLE);
NewWnd = Mt->OwnerWnd;
if (IS_SYSTEM_MENU(&TopMenuInfo))
- {
+ {
/* switch to the menu bar */
if (0 != (Style & WS_CHILD)
|| NULL == (NewMenu = GetMenu(NewWnd)))
- {
+ {
return FALSE;
- }
+ }
if (VK_LEFT == Vk)
- {
+ {
if (! MenuGetRosMenuInfo(&MenuInfo, NewMenu))
- {
+ {
return FALSE;
- }
+ }
Id = MenuInfo.cItems - 1;
- }
- }
+ }
+ }
else if (0 != (Style & WS_SYSMENU))
- {
+ {
/* switch to the system menu */
NewMenu = NtUserGetSystemMenu(NewWnd, FALSE);
- }
+ }
else
- {
+ {
return FALSE;
- }
- }
+ }
+ }
else /* application returned a new menu to switch to */
- {
+ {
NewMenu = NextMenu.hmenuNext;
NewWnd = NextMenu.hwndNext;
if (IsMenu(NewMenu) && IsWindow(NewWnd))
- {
+ {
DWORD Style = GetWindowLongPtrW(NewWnd, GWL_STYLE);
if (0 != (Style & WS_SYSMENU)
&& GetSystemMenu(NewWnd, FALSE) == NewMenu)
- {
+ {
/* get the real system menu */
NewMenu = NtUserGetSystemMenu(NewWnd, FALSE);
- }
+ }
else if (0 != (Style & WS_CHILD) || GetMenu(NewWnd) != NewMenu)
- {
+ {
/* FIXME: Not sure what to do here;
* perhaps try to track NewMenu as a popup? */
WARN(" -- got confused.\n");
return FALSE;
- }
- }
+ }
+ }
else
- {
+ {
return FALSE;
- }
- }
+ }
+ }
if (NewMenu != Mt->TopMenu)
- {
+ {
MenuSelectItem(Mt->OwnerWnd, &TopMenuInfo, NO_SELECTED_ITEM,
FALSE, 0 );
if (Mt->CurrentMenu != Mt->TopMenu)
- {
+ {
MenuHideSubPopups(Mt->OwnerWnd, &TopMenuInfo, FALSE, wFlags);
- }
- }
+ }
+ }
if (NewWnd != Mt->OwnerWnd)
- {
+ {
Mt->OwnerWnd = NewWnd;
NtUserxSetGUIThreadHandle(MSQ_STATE_MENUOWNER, Mt->OwnerWnd); // 1
SetCapture(Mt->OwnerWnd); // 2
- }
+ }
Mt->TopMenu = Mt->CurrentMenu = NewMenu; /* all subpopups are hidden */
if (MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
- {
+ {
MenuSelectItem(Mt->OwnerWnd, &TopMenuInfo, Id, TRUE, 0);
- }
+ }
return TRUE;
- }
+ }
return FALSE;
}
msg.hwnd = Mt->OwnerWnd;
PeekMessageW( &msg, 0, uMsg, uMsg, PM_NOYIELD | PM_REMOVE); // ported incorrectly since 8317 GvG
-// Mt->TrackFlags |= TF_SKIPREMOVE; // This sends TrackMenu into a loop with arrow keys!!!!
+ //Mt->TrackFlags |= TF_SKIPREMOVE; // This sends TrackMenu into a loop with arrow keys!!!!
switch( uMsg )
{
HMENU MenuTmp, MenuPrev;
if (Mt->CurrentMenu != Mt->TopMenu)
- {
+ {
if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu)
&& 0 != (MenuInfo.fFlags & MNF_POPUP))
- {
+ {
MenuPrev = MenuTmp = Mt->TopMenu;
/* close topmost popup */
while (MenuTmp != Mt->CurrentMenu)
- {
+ {
MenuPrev = MenuTmp;
- MenuTmp = MenuGetSubPopup(MenuPrev);
- }
+ MenuTmp = MENU_GetSubPopup(MenuPrev);
+ }
if (MenuGetRosMenuInfo(&MenuInfo, MenuPrev))
- {
+ {
MenuHideSubPopups(Mt->OwnerWnd, &MenuInfo, TRUE, Flags);
- }
+ }
Mt->CurrentMenu = MenuPrev;
EndMenu = FALSE;
- }
- }
+ }
+ }
return EndMenu;
}
MenuPrev = MenuTmp = Mt->TopMenu;
- if (! MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
- {
- return;
- }
-
/* Try to move 1 column left (if possible) */
- if ( (PrevCol = MenuGetStartOfPrevColumn(&MenuInfo)) != NO_SELECTED_ITEM)
+ if ( (PrevCol = MENU_GetStartOfPrevColumn(Mt->CurrentMenu)) != NO_SELECTED_ITEM)
{
if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
{
/* close topmost popup */
while (MenuTmp != Mt->CurrentMenu)
- {
+ {
MenuPrev = MenuTmp;
- MenuTmp = MenuGetSubPopup(MenuPrev);
- }
+ MenuTmp = MENU_GetSubPopup(MenuPrev);
+ }
if (! MenuGetRosMenuInfo(&PrevMenuInfo, MenuPrev))
- {
+ {
return;
- }
+ }
MenuHideSubPopups(Mt->OwnerWnd, &PrevMenuInfo, TRUE, Flags);
Mt->CurrentMenu = MenuPrev;
if (! MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
- {
+ {
return;
- }
+ }
if ((MenuPrev == Mt->TopMenu) && !(TopMenuInfo.fFlags & MNF_POPUP))
- {
+ {
/* move menu bar selection if no more popups are left */
if (!MenuDoNextMenu(Mt, VK_LEFT, Flags))
- {
+ {
MenuMoveSelection(Mt->OwnerWnd, &TopMenuInfo, ITEM_PREV);
- }
+ }
if (MenuPrev != MenuTmp || Mt->TrackFlags & TF_SUSPENDPOPUP)
- {
+ {
/* A sublevel menu was displayed - display the next one
* unless there is another displacement coming up */
if (! MenuSuspendPopup(Mt, WM_KEYDOWN)
&& MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
- {
+ {
Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &TopMenuInfo,
TRUE, Flags);
- }
- }
- }
+ }
+ }
+ }
}
/***********************************************************************
if (hmenutmp != Mt->CurrentMenu) return;
}
- if (! MenuGetRosMenuInfo(&CurrentMenuInfo, Mt->CurrentMenu))
- {
- return;
- }
-
/* Check to see if there's another column */
- if ( (NextCol = MenuGetStartOfNextColumn(&CurrentMenuInfo)) != NO_SELECTED_ITEM)
+ if ( (NextCol = MENU_GetStartOfNextColumn(Mt->CurrentMenu)) != NO_SELECTED_ITEM)
{
TRACE("Going to %d.\n", NextCol);
if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
if (!(MenuInfo.fFlags & MNF_POPUP)) /* menu bar tracking */
{
if (Mt->CurrentMenu != Mt->TopMenu)
- {
+ {
MenuHideSubPopups(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
hmenutmp = Mt->CurrentMenu = Mt->TopMenu;
- }
+ }
else
- {
+ {
hmenutmp = NULL;
- }
+ }
/* try to move to the next item */
if ( !MenuDoNextMenu(Mt, VK_RIGHT, Flags))
MenuMoveSelection(Mt->OwnerWnd, &MenuInfo, ITEM_NEXT);
if ( hmenutmp || Mt->TrackFlags & TF_SUSPENDPOPUP )
- {
+ {
if (! MenuSuspendPopup(Mt, WM_KEYDOWN)
&& MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu))
- {
+ {
Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo,
TRUE, Flags);
- }
- }
+ }
+ }
}
}
MSG msg;
ROSMENUINFO MenuInfo;
ROSMENUITEMINFO ItemInfo;
+ PMENU menu;
BOOL fRemove;
INT executedMenuId = -1;
MTRACKER mt;
if (!IsMenu(hmenu))
{
- WARN("Invalid menu handle %p\n", hmenu);
- SetLastError( ERROR_INVALID_MENU_HANDLE );
+ WARN("Invalid menu handle %p\n", hmenu); // Error already set in IsMenu.
return FALSE;
}
- fEndMenu = FALSE;
if (! MenuGetRosMenuInfo(&MenuInfo, hmenu))
{
return FALSE;
if (wFlags & TPM_BUTTONDOWN)
{
/* Get the result in order to start the tracking or not */
- fRemove = MenuButtonDown( &mt, hmenu, wFlags );
+ fRemove = MENU_ButtonDown( &mt, hmenu, wFlags );
fEndMenu = !fRemove;
}
NtUserxSetGUIThreadHandle(MSQ_STATE_MENUOWNER, capture_win); // 1
SetCapture(capture_win); // 2
- while (! fEndMenu)
+ while (!fEndMenu)
{
BOOL ErrorExit = FALSE;
- PMENU menu = ValidateHandle(mt.CurrentMenu, TYPE_MENU);
+ menu = MENU_GetMenu( mt.CurrentMenu );
if (!menu) /* sometimes happens if I do a window manager close */
break;
else
{
/* ReactOS Check */
- if (!ValidateHwnd(mt.OwnerWnd) || !ValidateHwnd(MenuInfo.Wnd))
+ if (!ValidateHwndNoErr(mt.OwnerWnd) || !ValidateHwndNoErr(MenuInfo.Wnd))
{
ErrorExit = TRUE; // Do not wait on dead windows, now test_capture_4 works.
break;
mt.Pt.y = (short)HIWORD(msg.lParam);
/* Find a menu for this mouse event */
- hmenu = MenuPtMenu(mt.TopMenu, mt.Pt);
+ hmenu = MENU_PtMenu(mt.TopMenu, mt.Pt);
switch(msg.message)
{
/* no WM_NC... messages in captured state */
case WM_RBUTTONDBLCLK:
- ERR("WM_RBUTTONDBLCLK\n");
case WM_RBUTTONDOWN:
if (!(wFlags & TPM_RIGHTBUTTON)) break;
/* fall through */
case WM_LBUTTONDOWN:
/* If the message belongs to the menu, removes it from the queue */
/* Else, end menu tracking */
- fRemove = MenuButtonDown(&mt, hmenu, wFlags);
+ fRemove = MENU_ButtonDown(&mt, hmenu, wFlags);
fEndMenu = !fRemove;
break;
/* Check if a menu was selected by the mouse */
if (hmenu)
{
- executedMenuId = MenuButtonUp( &mt, hmenu, wFlags);
+ executedMenuId = MENU_ButtonUp( &mt, hmenu, wFlags);
TRACE("executedMenuId %d\n", executedMenuId);
/* End the loop if executedMenuId is an item ID */
case VK_END:
if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
{
- MenuSelectItem(mt.OwnerWnd, &MenuInfo,
- NO_SELECTED_ITEM, FALSE, 0 );
- MenuMoveSelection(mt.OwnerWnd, &MenuInfo,
- VK_HOME == msg.wParam ? ITEM_NEXT : ITEM_PREV);
+ MenuSelectItem(mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM, FALSE, 0 );
+ MenuMoveSelection(mt.OwnerWnd, &MenuInfo, VK_HOME == msg.wParam ? ITEM_NEXT : ITEM_PREV);
}
break;
mt.CurrentMenu = MenuShowSubPopup(mt.OwnerWnd, &MenuInfo, TRUE, wFlags);
}
else /* otherwise try to move selection */
- MenuMoveSelection(mt.OwnerWnd, &MenuInfo,
- (msg.wParam == VK_UP)? ITEM_PREV : ITEM_NEXT );
+ MenuMoveSelection(mt.OwnerWnd, &MenuInfo, (msg.wParam == VK_UP)? ITEM_PREV : ITEM_NEXT );
}
break;
/* We will find a better way real soon... */
if (msg.wParam < 32) break;
- pos = MenuFindItemByKey(mt.OwnerWnd, &MenuInfo,
- LOWORD(msg.wParam), FALSE);
+ pos = MENU_FindItemByKey(mt.OwnerWnd, mt.CurrentMenu, LOWORD(msg.wParam), FALSE);
if (pos == (UINT)-2) fEndMenu = TRUE;
else if (pos == (UINT)-1) MessageBeep(0);
else
{
- MenuSelectItem(mt.OwnerWnd, &MenuInfo, pos,
- TRUE, 0);
+ MenuSelectItem(mt.OwnerWnd, &MenuInfo, pos, TRUE, 0);
executedMenuId = MenuExecFocusedItem(&mt, &MenuInfo, wFlags);
fEndMenu = (executedMenuId != -2);
}
IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
DestroyWindow(MenuInfo.Wnd);
MenuInfo.Wnd = NULL;
+ MenuSetRosMenuInfo(&MenuInfo);
if (!(wFlags & TPM_NONOTIFY))
SendMessageW( mt.OwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.TopMenu,
* It also enables menus to be displayed in more than one window,
* but there are some bugs left that need to be fixed in this case.
*/
- if (MenuGetRosMenuInfo(&MenuInfo, hMenu))
+ if (!bPopup && (MenuGetRosMenuInfo(&MenuInfo, hMenu)))
{
MenuInfo.Wnd = hWnd;
MenuSetRosMenuInfo(&MenuInfo);
}
+ //if (!bPopup) menu->hWnd = hWnd;
+ if (!top_popup)
+ {
+ top_popup = MenuInfo.Wnd;//menu->hWnd;
+ top_popup_hmenu = hMenu;
+ }
+
+ fEndMenu = FALSE;
/* Send WM_ENTERMENULOOP and WM_INITMENU message only if TPM_NONOTIFY flag is not specified */
if (!(wFlags & TPM_NONOTIFY))
CHILDID_SELF, 0);
return TRUE;
}
+
/***********************************************************************
* MenuExitTracking
*/
}
}
-
/***********************************************************************
* MenuTrackKbdMenuBar
*
MenuInitTracking( hwnd, hTrackMenu, FALSE, wFlags );
+ /* fetch the window menu again, it may have changed */
+ hTrackMenu = (wParam & HTSYSMENU) ? get_win_sys_menu( hwnd ) : GetMenu( hwnd );
+
if (! MenuGetRosMenuInfo(&MenuInfo, hTrackMenu))
{
goto track_menu;
if( wChar && wChar != ' ' )
{
- uItem = MenuFindItemByKey( hwnd, &MenuInfo, wChar, (wParam & HTSYSMENU) );
+ uItem = MENU_FindItemByKey( hwnd, hTrackMenu, wChar, (wParam & HTSYSMENU) );
if ( uItem >= (UINT)(-2) )
{
if( uItem == (UINT)(-1) ) MessageBeep(0);
/**********************************************************************
* TrackPopupMenuEx (USER32.@)
*/
-BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
- HWND Wnd, LPTPMPARAMS Tpm)
+BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, int x, int y,
+ HWND hWnd, LPTPMPARAMS lpTpm)
{
BOOL ret = FALSE;
- ROSMENUINFO MenuInfo;
-
- if (!IsMenu(Menu))
- {
- SetLastError( ERROR_INVALID_MENU_HANDLE );
- return FALSE;
- }
-
- /* ReactOS Check */
- if (!ValidateHwnd(Wnd))
- {
- /* invalid window see wine menu.c test_menu_trackpopupmenu line 3146 */
- return FALSE;
- }
-
- MenuGetRosMenuInfo(&MenuInfo, Menu);
- if (IsWindow(MenuInfo.Wnd))
- {
- SetLastError( ERROR_POPUP_ALREADY_ACTIVE );
- return FALSE;
- }
-
- MenuInitTracking(Wnd, Menu, TRUE, Flags);
-
- /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
- if (!(Flags & TPM_NONOTIFY))
- SendMessageW(Wnd, WM_INITMENUPOPUP, (WPARAM) Menu, 0);
-
- if (MenuShowPopup(Wnd, Menu, 0, Flags, x, y, 0, 0 ))
- ret = MenuTrackMenu(Menu, Flags | TPM_POPUPMENU, 0, 0, Wnd,
- Tpm ? &Tpm->rcExclude : NULL);
- MenuExitTracking(Wnd, TRUE);
- return ret;
-}
-
-/**********************************************************************
- * TrackPopupMenu (USER32.@)
- */
-BOOL WINAPI TrackPopupMenu( HMENU Menu, UINT Flags, int x, int y,
- int Reserved, HWND Wnd, CONST RECT *Rect)
-{
- return TrackPopupMenuEx( Menu, Flags, x, y, Wnd, NULL);
-}
-
-/*
- * From MSDN:
- * The MFT_BITMAP, MFT_SEPARATOR, and MFT_STRING values cannot be combined
- * with one another. Also MFT_OWNERDRAW. Set fMask to MIIM_TYPE to use fType.
- *
- * Windows 2K/XP: fType is used only if fMask has a value of MIIM_FTYPE.
- *
- * MIIM_TYPE: Retrieves or sets the fType and dwTypeData members. Windows
- * 2K/XP: MIIM_TYPE is replaced by MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING.
- * MFT_STRING is replaced by MIIM_STRING.
- * (So, I guess we should use MIIM_STRING only for strings?)
- *
- * MIIM_FTYPE: Windows 2K/Windows XP: Retrieves or sets the fType member.
- *
- * Based on wine, SetMenuItemInfo_common:
- * 1) set MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP any one with MIIM_TYPE,
- * it will result in a error.
- * 2) set menu mask to MIIM_FTYPE and MFT_BITMAP ftype it will result in a error.
- * These conditions are addressed in Win32k IntSetMenuItemInfo.
- *
- */
-static
-BOOL
-FASTCALL
-MenuSetItemData(
- LPMENUITEMINFOW mii,
- UINT Flags,
- UINT_PTR IDNewItem,
- LPCWSTR NewItem,
- BOOL Unicode)
-{
-/*
- * Let us assume MIIM_FTYPE is set and building a new menu item structure.
- */
- if(Flags & MF_BITMAP)
- {
- mii->fMask |= MIIM_BITMAP; /* Use the new way of seting hbmpItem.*/
- mii->hbmpItem = (HBITMAP) NewItem;
-
- if (Flags & MF_HELP)
- {
- /* increase ident */
- mii->fType |= MF_HELP;
- }
- }
- else if(Flags & MF_OWNERDRAW)
- {
- mii->fType |= MFT_OWNERDRAW;
- mii->fMask |= MIIM_DATA;
- mii->dwItemData = (DWORD_PTR) NewItem;
- }
- else if (Flags & MF_SEPARATOR)
- {
- mii->fType |= MFT_SEPARATOR;
- if (!(Flags & (MF_GRAYED|MF_DISABLED)))
- Flags |= MF_GRAYED|MF_DISABLED;
- }
- else /* Default action MF_STRING. */
- {
- /* Item beginning with a backspace is a help item */
- if (NewItem != NULL)
- {
- if (Unicode)
- {
- if (*NewItem == '\b')
- {
- mii->fType |= MF_HELP;
- NewItem++;
- }
- }
- else
- {
- LPCSTR NewItemA = (LPCSTR) NewItem;
- if (*NewItemA == '\b')
- {
- mii->fType |= MF_HELP;
- NewItemA++;
- NewItem = (LPCWSTR) NewItemA;
- }
- }
+ MENU *menu;
- if (Flags & MF_HELP)
- mii->fType |= MF_HELP;
- mii->fMask |= MIIM_STRING;
- mii->fType |= MFT_STRING; /* Zero */
- mii->dwTypeData = (LPWSTR)NewItem;
- if (Unicode)
- mii->cch = (NULL == NewItem ? 0 : strlenW(NewItem));
- else
- mii->cch = (NULL == NewItem ? 0 : strlen((LPCSTR)NewItem));
- }
- else
+ TRACE("hmenu %p flags %04x (%d,%d) hwnd %p lpTpm %p rect %s\n",
+ hMenu, wFlags, x, y, hWnd, lpTpm,
+ lpTpm ? wine_dbgstr_rect( &lpTpm->rcExclude) : "-" );
+
+ /* Parameter check */
+ /* FIXME: this check is performed several times, here and in the called
+ functions. That could be optimized */
+ if (!(menu = MENU_GetMenu( hMenu )))
{
- mii->fType |= MFT_SEPARATOR;
- if (!(Flags & (MF_GRAYED|MF_DISABLED)))
- Flags |= MF_GRAYED|MF_DISABLED;
+ SetLastError( ERROR_INVALID_MENU_HANDLE );
+ return FALSE;
}
- }
-
- if(Flags & MF_RIGHTJUSTIFY) /* Same as MF_HELP */
- {
- mii->fType |= MFT_RIGHTJUSTIFY;
- }
- if(Flags & MF_MENUBREAK)
- {
- mii->fType |= MFT_MENUBREAK;
- }
- else if(Flags & MF_MENUBARBREAK)
- {
- mii->fType |= MFT_MENUBARBREAK;
- }
+ if (IsWindow(menu->hWnd))
+ {
+ SetLastError( ERROR_POPUP_ALREADY_ACTIVE );
+ return FALSE;
+ }
- if(Flags & MF_GRAYED || Flags & MF_DISABLED)
- {
- if (Flags & MF_GRAYED)
- mii->fState |= MF_GRAYED;
+ if (MENU_InitPopup( hWnd, hMenu, wFlags ))
+ {
+ MenuInitTracking(hWnd, hMenu, TRUE, wFlags);
- if (Flags & MF_DISABLED)
- mii->fState |= MF_DISABLED;
+ /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
+ if (!(wFlags & TPM_NONOTIFY))
+ SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM) hMenu, 0);
- mii->fMask |= MIIM_STATE;
- }
- else if (Flags & MF_HILITE)
- {
- mii->fState |= MF_HILITE;
- mii->fMask |= MIIM_STATE;
- }
- else /* default state */
- {
- mii->fState |= MFS_ENABLED;
- mii->fMask |= MIIM_STATE;
- }
+ if (MenuShowPopup(hWnd, hMenu, 0, wFlags, x, y, 0, 0 ))
+ ret = MenuTrackMenu(hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd,
+ lpTpm ? &lpTpm->rcExclude : NULL);
+ MenuExitTracking(hWnd, TRUE);
- if(Flags & MF_POPUP && IsMenu((HMENU)IDNewItem))
- {
- mii->fMask |= MIIM_SUBMENU;
- mii->hSubMenu = (HMENU)IDNewItem;
- }
- mii->fMask |= MIIM_ID;
- mii->wID = (UINT)IDNewItem;
- return TRUE;
+ if (menu->hWnd)
+ {
+ ROSMENUINFO MenuInfo;
+ if (IsWindow( menu->hWnd )) // wine hack around this with their destroy function.
+ DestroyWindow( menu->hWnd ); // Fix wrong error return.
+ //menu->hWnd = 0;
+ MenuGetRosMenuInfo(&MenuInfo, menu->head.h);
+ MenuInfo.Wnd = 0;
+ MenuSetRosMenuInfo(&MenuInfo);
+
+ if (!(wFlags & TPM_NONOTIFY))
+ SendMessageW( hWnd, WM_UNINITMENUPOPUP, (WPARAM)hMenu,
+ MAKELPARAM(0, IS_SYSTEM_MENU(menu)) );
+ }
+ }
+ return ret;
}
-NTSTATUS WINAPI
-User32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength)
+/**********************************************************************
+ * TrackPopupMenu (USER32.@)
+ */
+BOOL WINAPI TrackPopupMenu( HMENU Menu, UINT Flags, int x, int y,
+ int Reserved, HWND Wnd, CONST RECT *Rect)
{
- PLOADMENU_CALLBACK_ARGUMENTS Common;
- LRESULT Result;
-
- Common = (PLOADMENU_CALLBACK_ARGUMENTS) Arguments;
-
- Result = (LRESULT)LoadMenuW( Common->hModule,
- IS_INTRESOURCE(Common->MenuName[0]) ?
- MAKEINTRESOURCE(Common->MenuName[0]) :
- (LPCWSTR)&Common->MenuName);
+ return TrackPopupMenuEx( Menu, Flags, x, y, Wnd, NULL);
+}
- return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
+/**********************************************************************
+ * MENU_mnu2mnuii
+ *
+ * Uses flags, id and text ptr, passed by InsertMenu() and
+ * ModifyMenu() to setup a MenuItemInfo structure.
+ */
+static void MENU_mnu2mnuii( UINT flags, UINT_PTR id, LPCWSTR str, LPMENUITEMINFOW pmii, BOOL Unicode)
+{
+ RtlZeroMemory( pmii, sizeof( MENUITEMINFOW));
+ pmii->cbSize = sizeof( MENUITEMINFOW);
+ pmii->fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE;
+ /* setting bitmap clears text and vice versa */
+ if( IS_STRING_ITEM(flags)) {
+ pmii->fMask |= MIIM_STRING | MIIM_BITMAP;
+ if( !str)
+ flags |= MF_SEPARATOR;
+ /* Item beginning with a backspace is a help item */
+ /* FIXME: wrong place, this is only true in win16 */
+ else
+ {
+ if (Unicode)
+ {
+ if (*str == '\b')
+ {
+ flags |= MF_HELP;
+ str++;
+ }
+ }
+ else
+ {
+ LPCSTR NewItemA = (LPCSTR) str;
+ if (*NewItemA == '\b')
+ {
+ flags |= MF_HELP;
+ NewItemA++;
+ str = (LPCWSTR) NewItemA;
+ }
+ TRACE("A cch %d\n",strlen(NewItemA));
+ }
+ }
+ pmii->dwTypeData = (LPWSTR)str;
+ } else if( flags & MFT_BITMAP){
+ pmii->fMask |= MIIM_BITMAP | MIIM_STRING;
+ pmii->hbmpItem = (HBITMAP)str;
+ }
+ if( flags & MF_OWNERDRAW){
+ pmii->fMask |= MIIM_DATA;
+ pmii->dwItemData = (ULONG_PTR) str;
+ }
+ if( flags & MF_POPUP && MENU_GetMenu((HMENU)id)) {
+ pmii->fMask |= MIIM_SUBMENU;
+ pmii->hSubMenu = (HMENU)id;
+ }
+ if( flags & MF_SEPARATOR) flags |= MF_GRAYED | MF_DISABLED;
+ pmii->fState = flags & MENUITEMINFO_STATE_MASK & ~MFS_DEFAULT;
+ pmii->fType = flags & MENUITEMINFO_TYPE_MASK;
+ pmii->wID = (UINT)id;
}
/**********************************************************************
return TRUE;
}
+BOOL
+MenuInit(VOID)
+{
+ NONCLIENTMETRICSW ncm;
+
+ /* get the menu font */
+ if(!hMenuFont || !hMenuFontBold)
+ {
+ ncm.cbSize = sizeof(ncm);
+ if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0))
+ {
+ ERR("MenuInit(): SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed!\n");
+ return FALSE;
+ }
+
+ hMenuFont = CreateFontIndirectW(&ncm.lfMenuFont);
+ if(hMenuFont == NULL)
+ {
+ ERR("MenuInit(): CreateFontIndirectW(hMenuFont) failed!\n");
+ return FALSE;
+ }
+
+ ncm.lfMenuFont.lfWeight = max(ncm.lfMenuFont.lfWeight + 300, 1000);
+ hMenuFontBold = CreateFontIndirectW(&ncm.lfMenuFont);
+ if(hMenuFontBold == NULL)
+ {
+ ERR("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n");
+ DeleteObject(hMenuFont);
+ hMenuFont = NULL;
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+VOID
+MenuCleanup(VOID)
+{
+ if (hMenuFont)
+ {
+ DeleteObject(hMenuFont);
+ hMenuFont = NULL;
+ }
+
+ if (hMenuFontBold)
+ {
+ DeleteObject(hMenuFontBold);
+ hMenuFontBold = NULL;
+ }
+}
+
+NTSTATUS WINAPI
+User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength)
+{
+ LRESULT Result = 0;
+
+ // Will be converted to load bitmaps for OBMI!
+
+ return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
+}
+
+NTSTATUS WINAPI
+User32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength)
+{
+ PLOADMENU_CALLBACK_ARGUMENTS Common;
+ LRESULT Result;
+
+ Common = (PLOADMENU_CALLBACK_ARGUMENTS) Arguments;
+
+ Result = (LRESULT)LoadMenuW( Common->hModule, Common->InterSource ? MAKEINTRESOURCE(Common->InterSource) : (LPCWSTR)&Common->MenuName);
+
+ return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
+}
+
/* FUNCTIONS *****************************************************************/
UINT_PTR uIDNewItem,
LPCSTR lpNewItem)
{
- return(InsertMenuA(hMenu, -1, uFlags | MF_BYPOSITION, uIDNewItem, lpNewItem));
+ MENUITEMINFOW mii;
+ UNICODE_STRING UnicodeString;
+ BOOL res;
+
+ RtlInitUnicodeString(&UnicodeString, 0);
+
+ MENU_mnu2mnuii( uFlags, uIDNewItem, (LPCWSTR)lpNewItem, &mii, FALSE);
+
+ /* copy the text string, it will be one or the other */
+ if (lpNewItem && mii.fMask & MIIM_STRING && !mii.hbmpItem && mii.dwTypeData)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&UnicodeString, (LPSTR)mii.dwTypeData))
+ {
+ SetLastError (ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ mii.dwTypeData = UnicodeString.Buffer;
+ mii.cch = UnicodeString.Length / sizeof(WCHAR);
+ }
+ else
+ {
+ TRACE("AMA Handle bitmaps\n");
+ }
+ ////// Answer a question, why a -1? To hunt for the end of the item list. Get it, to Append?
+ res = NtUserThunkedMenuItemInfo(hMenu, -1, TRUE, TRUE, &mii, &UnicodeString);
+ if ( UnicodeString.Buffer ) RtlFreeUnicodeString ( &UnicodeString );
+ return res;
}
/*
UINT_PTR uIDNewItem,
LPCWSTR lpNewItem)
{
- return(InsertMenuW(hMenu, -1, uFlags | MF_BYPOSITION, uIDNewItem, lpNewItem));
+ MENUITEMINFOW mii;
+ UNICODE_STRING MenuText;
+ BOOL res;
+
+ RtlInitUnicodeString(&MenuText, 0);
+
+ MENU_mnu2mnuii( uFlags, uIDNewItem, lpNewItem, &mii, TRUE);
+
+ /* copy the text string, it will be one or the other */
+ if (lpNewItem && mii.fMask & MIIM_STRING && !mii.hbmpItem && mii.dwTypeData)
+ {
+ RtlInitUnicodeString(&MenuText, (PWSTR)mii.dwTypeData);
+ mii.dwTypeData = MenuText.Buffer;
+ mii.cch = MenuText.Length / sizeof(WCHAR);
+ }
+ res = NtUserThunkedMenuItemInfo(hMenu, -1, TRUE, TRUE, &mii, &MenuText);
+ return res;
}
/*
return NtUserCheckMenuItem(hmenu, uIDCheckItem, uCheck);
}
-
/*
* @implemented
*/
/* don't end up with an orphaned menu */
PostMessageW( top_popup, WM_CANCELMODE, 0, 0);
}
- return TRUE;
+ return fEndMenu;
}
BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID,
return UlongToHandle(Wnd->IDMenu);
}
-
/*
* @implemented
*/
GetMenuItemID(HMENU hMenu,
int nPos)
{
- PMENU pMenu;
- PITEM pItem;
- INT i = 0;
-
- if (!(pMenu = ValidateHandle(hMenu, TYPE_MENU)))
- return -1;
-
- pItem = pMenu->rgItems ? DesktopPtrToUser(pMenu->rgItems) : NULL;
- if ( nPos >= 0 )
- {
- //pItem = &menu->rgItems[nPos]; or pItem[nPos]; after dptu.
- while(pItem) // Do this for now.
- {
- if (i < (INT)pMenu->cItems)
- {
- if ( nPos == i && !pItem->spSubMenu) return pItem->wID;
- }
- pItem = pItem->Next ? DesktopPtrToUser(pItem->Next) : NULL;
- i++;
- }
- }
- return -1;
+ ITEM * lpmi;
+ if (!(lpmi = MENU_FindItem(&hMenu,(UINT*)&nPos,MF_BYPOSITION))) return -1;
+ if (lpmi->spSubMenu) return -1;
+ return lpmi->wID;
}
/*
UINT uFlags)
{
PITEM pItem;
+ UINT Type = 0;
TRACE("(menu=%p, id=%04x, flags=%04x);\n", hMenu, uId, uFlags);
if (!(pItem = MENU_FindItem( &hMenu, &uId, uFlags ))) return -1;
+ if (!pItem->Xlpstr && pItem->hbmp) Type = MFT_BITMAP;
+
if (pItem->spSubMenu)
{
PMENU pSubMenu = DesktopPtrToUser(pItem->spSubMenu);
HMENU hsubmenu = UserHMGetHandle(pSubMenu);
if (!IsMenu(hsubmenu)) return (UINT)-1;
- else return (pSubMenu->cItems << 8) | ((pItem->fState|pItem->fType) & 0xff);
+ else return (pSubMenu->cItems << 8) | ((pItem->fState|pItem->fType|Type) & 0xff);
}
else
- return (pItem->fType | pItem->fState);
+ return (pItem->fType | pItem->fState | Type);
}
/*
int nMaxCount,
UINT uFlag)
{
-/* MENUITEMINFOA mii;
- memset( &mii, 0, sizeof(mii) );
- mii.dwTypeData = lpString;
- mii.fMask = MIIM_STRING;
- mii.cbSize = sizeof(MENUITEMINFOA);
- mii.cch = nMaxCount;
-
- if(!(GetMenuItemInfoA( hMenu, uIDItem, (BOOL)(MF_BYPOSITION & uFlag),&mii)))
- return 0;
- else
- return mii.cch;
-*/
ITEM *item;
LPWSTR text;
////// wine Code, seems to be faster.
if (!lpString || !nMaxCount) return WideCharToMultiByte( CP_ACP, 0, text, -1, NULL, 0, NULL, NULL );
if (!WideCharToMultiByte( CP_ACP, 0, text, -1, lpString, nMaxCount, NULL, NULL ))
lpString[nMaxCount-1] = 0;
- ERR("returning %s\n", lpString);
+ TRACE("A returning %s\n", lpString);
return strlen(lpString);
}
int nMaxCount,
UINT uFlag)
{
-/* MENUITEMINFOW miiW;
- memset( &miiW, 0, sizeof(miiW) );
- miiW.dwTypeData = lpString;
- miiW.fMask = MIIM_STRING | MIIM_FTYPE;
- miiW.fType = MFT_STRING;
- miiW.cbSize = sizeof(MENUITEMINFOW);
- miiW.cch = nMaxCount;
-
- if(!(GetMenuItemInfoW( hMenu, uIDItem, (BOOL)(MF_BYPOSITION & uFlag),&miiW)))
- return 0;
- else
- return miiW.cch;
-*/
ITEM *item;
LPWSTR text;
return 0;
}
lstrcpynW( lpString, text, nMaxCount );
- ERR("returning %S\n", lpString);
+ TRACE("W returning %S\n", lpString);
return strlenW(lpString);
}
UINT_PTR uIDNewItem,
LPCSTR lpNewItem)
{
- MENUITEMINFOA mii;
- memset( &mii, 0, sizeof(mii) );
- mii.cbSize = sizeof(MENUITEMINFOA);
- mii.fMask = MIIM_FTYPE;
-
- MenuSetItemData((LPMENUITEMINFOW) &mii,
- uFlags,
- uIDNewItem,
- (LPCWSTR) lpNewItem,
- FALSE);
-
- return InsertMenuItemA(hMenu, uPosition, (BOOL)((MF_BYPOSITION & uFlags) > 0), &mii);
+ MENUITEMINFOW mii;
+ UNICODE_STRING UnicodeString;
+ BOOL res;
+
+ RtlInitUnicodeString(&UnicodeString, 0);
+
+ MENU_mnu2mnuii( uFlags, uIDNewItem, (LPCWSTR)lpNewItem, &mii, FALSE);
+
+ /* copy the text string, it will be one or the other */
+ if (lpNewItem && mii.fMask & MIIM_STRING && !mii.hbmpItem && mii.dwTypeData)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&UnicodeString, (LPSTR)mii.dwTypeData))
+ {
+ SetLastError (ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ mii.dwTypeData = UnicodeString.Buffer;
+ mii.cch = UnicodeString.Length / sizeof(WCHAR);
+ }
+ else
+ {
+ TRACE("Handle bitmaps\n");
+ }
+ res = NtUserThunkedMenuItemInfo(hMenu, uPosition, (BOOL)(uFlags & MF_BYPOSITION), TRUE, &mii, &UnicodeString);
+ if ( UnicodeString.Buffer ) RtlFreeUnicodeString ( &UnicodeString );
+ return res;
}
/*
}
else
{
- UnicodeString.Buffer = NULL;
+ TRACE("Handle bitmaps\n");
}
res = NtUserThunkedMenuItemInfo(hMenu, uItem, fByPosition, TRUE, &mii, &UnicodeString);
if ( UnicodeString.Buffer ) RtlFreeUnicodeString ( &UnicodeString );
LPCWSTR lpNewItem)
{
MENUITEMINFOW mii;
- memset( &mii, 0, sizeof(mii) );
- mii.cbSize = sizeof(MENUITEMINFOW);
- mii.fMask = MIIM_FTYPE;
+ UNICODE_STRING MenuText;
+ BOOL res;
+
+ RtlInitUnicodeString(&MenuText, 0);
- MenuSetItemData( &mii,
- uFlags,
- uIDNewItem,
- lpNewItem,
- TRUE);
+ MENU_mnu2mnuii( uFlags, uIDNewItem, lpNewItem, &mii, TRUE);
- return InsertMenuItemW(hMenu, uPosition, (BOOL)((MF_BYPOSITION & uFlags) > 0), &mii);
+ /* copy the text string, it will be one or the other */
+ if (lpNewItem && mii.fMask & MIIM_STRING && !mii.hbmpItem && mii.dwTypeData)
+ {
+ RtlInitUnicodeString(&MenuText, (PWSTR)mii.dwTypeData);
+ mii.dwTypeData = MenuText.Buffer;
+ mii.cch = MenuText.Length / sizeof(WCHAR);
+ }
+ res = NtUserThunkedMenuItemInfo(hMenu, uPosition, (BOOL)(uFlags & MF_BYPOSITION), TRUE, &mii, &MenuText);
+ return res;
}
/*
BOOL
WINAPI
ModifyMenuA(
- HMENU hMnu,
+ HMENU hMenu,
UINT uPosition,
UINT uFlags,
UINT_PTR uIDNewItem,
LPCSTR lpNewItem)
{
- MENUITEMINFOA mii;
- memset( &mii, 0, sizeof(mii) );
- mii.cbSize = sizeof(MENUITEMINFOA);
- mii.fMask = MIIM_FTYPE;
-
- MenuSetItemData((LPMENUITEMINFOW) &mii,
- uFlags,
- uIDNewItem,
- (LPCWSTR) lpNewItem,
- FALSE);
-
- //if (mii.hSubMenu && (uFlags & MF_POPUP) && (mii.hSubMenu != (HMENU)uIDNewItem))
- // NtUserDestroyMenu( mii.hSubMenu ); /* ModifyMenu() spec */
-
- return SetMenuItemInfoA( hMnu,
- uPosition,
- (BOOL)(MF_BYPOSITION & uFlags),
- &mii);
+ MENUITEMINFOW mii;
+ UNICODE_STRING UnicodeString;
+ BOOL res;
+
+ RtlInitUnicodeString(&UnicodeString, 0);
+
+ MENU_mnu2mnuii( uFlags, uIDNewItem, (LPCWSTR)lpNewItem, &mii, FALSE);
+
+ /* copy the text string, it will be one or the other */
+ if (lpNewItem && mii.fMask & MIIM_STRING && !mii.hbmpItem && mii.dwTypeData)
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&UnicodeString, (LPSTR)mii.dwTypeData))
+ {
+ SetLastError (ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ mii.dwTypeData = UnicodeString.Buffer;
+ mii.cch = UnicodeString.Length / sizeof(WCHAR);
+ }
+ else
+ {
+ TRACE("Handle bitmaps\n");
+ }
+ res = NtUserThunkedMenuItemInfo(hMenu, uPosition, (BOOL)(uFlags & MF_BYPOSITION), FALSE, &mii, &UnicodeString);
+ if ( UnicodeString.Buffer ) RtlFreeUnicodeString ( &UnicodeString );
+ return res;
}
/*
BOOL
WINAPI
ModifyMenuW(
- HMENU hMnu,
+ HMENU hMenu,
UINT uPosition,
UINT uFlags,
UINT_PTR uIDNewItem,
LPCWSTR lpNewItem)
{
MENUITEMINFOW mii;
- memset ( &mii, 0, sizeof(mii) );
- mii.cbSize = sizeof(MENUITEMINFOW);
- mii.fMask = MIIM_FTYPE;
-
- /* Init new data for this menu item */
- MenuSetItemData( &mii,
- uFlags,
- uIDNewItem,
- lpNewItem,
- TRUE);
-
- //if (mii.hSubMenu && (uFlags & MF_POPUP) && (mii.hSubMenu != (HMENU)uIDNewItem))
- // NtUserDestroyMenu( mii.hSubMenu ); /* ModifyMenu() spec */
-
- return SetMenuItemInfoW( hMnu,
- uPosition,
- (BOOL)(MF_BYPOSITION & uFlags),
- &mii);
+ UNICODE_STRING MenuText;
+ BOOL res;
+
+ RtlInitUnicodeString(&MenuText, 0);
+
+ MENU_mnu2mnuii( uFlags, uIDNewItem, lpNewItem, &mii, TRUE);
+
+ /* copy the text string, it will be one or the other */
+ if (lpNewItem && mii.fMask & MIIM_STRING && !mii.hbmpItem && mii.dwTypeData)
+ {
+ RtlInitUnicodeString(&MenuText, (PWSTR)mii.dwTypeData);
+ mii.dwTypeData = MenuText.Buffer;
+ mii.cch = MenuText.Length / sizeof(WCHAR);
+ }
+ else
+ {
+ TRACE("Handle bitmaps\n");
+ }
+ res = NtUserThunkedMenuItemInfo(hMenu, uPosition, (BOOL)(uFlags & MF_BYPOSITION), FALSE, &mii, &MenuText);
+ return res;
}
/*
NULL); // LPTPMPARAMS is null
}
-
-
/*
* @unimplemented
*/
return FALSE;
}
return NtUserMessageCall(hWnd, Msg, wParam, lParam, Result, FNID_MENU, TRUE);
-
}
/*