Author: cwittich
Date: Wed Mar 17 01:11:31 2010
New Revision: 46236
URL:
http://svn.reactos.org/svn/reactos?rev=46236&view=rev
Log:
[USER32]
reduce diff to wine
Modified:
trunk/reactos/dll/win32/user32/windows/menu.c
Modified: trunk/reactos/dll/win32/user32/windows/menu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/m…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/menu.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/menu.c [iso-8859-1] Wed Mar 17 01:11:31 2010
@@ -57,7 +57,7 @@
/* Use global popup window because there's no way 2 menus can
* be tracked at the same time. */
-static HWND TopPopup;
+static HWND top_popup;
/* Flag set by EndMenu() to force an exit from menu tracking */
static BOOL fEndMenu = FALSE;
@@ -347,6 +347,49 @@
SelectObject(dc, hOldFont);
SetBkMode(dc, bkmode);
DeleteObject(hFont);
+}
+
+/***********************************************************************
+ * MenuFindSubMenu
+ *
+ * Find a Sub menu. Return the position of the submenu, and modifies
+ * *hmenu in case it is found in another sub-menu.
+ * If the submenu cannot be found, NO_SELECTED_ITEM is returned.
+ */
+static UINT FASTCALL MenuFindSubMenu(HMENU *hmenu, HMENU hSubTarget )
+{
+ ROSMENUINFO menu;
+ UINT i;
+ ROSMENUITEMINFO item;
+
+ if (((*hmenu)==(HMENU)0xffff) ||
+ (!MenuGetRosMenuInfo(&menu, *hmenu)))
+ return NO_SELECTED_ITEM;
+
+ MenuInitRosMenuItemInfo(&item);
+ for (i = 0; i < menu.MenuItemCount; i++)
+ {
+ if (! MenuGetRosMenuItemInfo(menu.Self, i, &item))
+ {
+ MenuCleanupRosMenuItemInfo(&item);
+ return NO_SELECTED_ITEM;
+ }
+ if (!(item.fType & MF_POPUP)) continue;
+ if (item.hSubMenu == hSubTarget) {
+ MenuCleanupRosMenuItemInfo(&item);
+ return i;
+ }
+ else {
+ HMENU hsubmenu = item.hSubMenu;
+ UINT pos = MenuFindSubMenu(&hsubmenu, hSubTarget );
+ if (pos != NO_SELECTED_ITEM) {
+ *hmenu = hsubmenu;
+ return pos;
+ }
+ }
+ }
+ MenuCleanupRosMenuItemInfo(&item);
+ return NO_SELECTED_ITEM;
}
/***********************************************************************
@@ -1482,8 +1525,8 @@
hwndOwner, 0, (HINSTANCE) GetWindowLongPtrW(hwndOwner,
GWLP_HINSTANCE),
(LPVOID) MenuInfo.Self);
if ( !MenuInfo.Wnd || ! MenuSetRosMenuInfo(&MenuInfo)) return FALSE;
- if (!TopPopup) {
- TopPopup = MenuInfo.Wnd;
+ if (!top_popup) {
+ top_popup = MenuInfo.Wnd;
}
/* Display the window */
@@ -1494,8 +1537,156 @@
return TRUE;
}
-LRESULT WINAPI
-PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
+/***********************************************************************
+ * MenuSelectItem
+ */
+static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIndex,
+ BOOL sendMenuSelect, HMENU topmenu)
+{
+ ROSMENUITEMINFO ItemInfo;
+ ROSMENUINFO TopMenuInfo;
+ HDC hdc;
+
+ TRACE("owner=%p menu=%p index=0x%04x select=0x%04x\n", hwndOwner, hmenu,
wIndex, sendMenuSelect);
+
+ if (!hmenu || !hmenu->MenuItemCount || !hmenu->Wnd) return;
+ if (hmenu->FocusedItem == wIndex) return;
+ if (hmenu->Flags & MF_POPUP) hdc = GetDC(hmenu->Wnd);
+ else hdc = GetDCEx(hmenu->Wnd, 0, DCX_CACHE | DCX_WINDOW);
+ if (!top_popup) {
+ top_popup = hmenu->Wnd;
+ }
+
+ SelectObject( hdc, hMenuFont );
+
+ MenuInitRosMenuItemInfo(&ItemInfo);
+
+ /* Clear previous highlighted item */
+ if (hmenu->FocusedItem != NO_SELECTED_ITEM)
+ {
+ if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem,
&ItemInfo))
+ {
+ ItemInfo.fMask |= MIIM_STATE;
+ ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
+ MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem,
&ItemInfo);
+ }
+ MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc, &ItemInfo,
+ hmenu->Height, ! (hmenu->Flags & MF_POPUP),
+ ODA_SELECT);
+ }
+
+ /* Highlight new item (if any) */
+ hmenu->FocusedItem = wIndex;
+ MenuSetRosMenuInfo(hmenu);
+ if (hmenu->FocusedItem != NO_SELECTED_ITEM)
+ {
+ if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem,
&ItemInfo))
+ {
+ if (!(ItemInfo.fType & MF_SEPARATOR))
+ {
+ ItemInfo.fMask |= MIIM_STATE;
+ ItemInfo.fState |= MF_HILITE;
+ MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem,
&ItemInfo);
+ MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc,
+ &ItemInfo, hmenu->Height, ! (hmenu->Flags &
MF_POPUP),
+ ODA_SELECT);
+ }
+ if (sendMenuSelect)
+ {
+ SendMessageW(hwndOwner, WM_MENUSELECT,
+ MAKELONG(ItemInfo.fType & MF_POPUP ? wIndex :
ItemInfo.wID,
+ ItemInfo.fType | ItemInfo.fState | MF_MOUSESELECT |
+ (hmenu->Flags & MF_SYSMENU)), (LPARAM)
hmenu->Self);
+ }
+ }
+ }
+ else if (sendMenuSelect) {
+ if(topmenu) {
+ int pos;
+ pos = MenuFindSubMenu(&topmenu, hmenu->Self);
+ if (pos != NO_SELECTED_ITEM)
+ {
+ if (MenuGetRosMenuInfo(&TopMenuInfo, topmenu)
+ && MenuGetRosMenuItemInfo(topmenu, pos, &ItemInfo))
+ {
+ SendMessageW(hwndOwner, WM_MENUSELECT,
+ MAKELONG(Pos, ItemInfo.fType | ItemInfo.fState
+ | MF_MOUSESELECT
+ | (TopMenuInfo.Flags & MF_SYSMENU)),
+ (LPARAM) topmenu);
+ }
+ }
+ }
+ }
+ MenuCleanupRosMenuItemInfo(&ItemInfo);
+ ReleaseDC(hmenu->Wnd, hdc);
+}
+
+/***********************************************************************
+ * MenuMoveSelection
+ *
+ * Moves currently selected item according to the Offset parameter.
+ * If there is no selection then it should select the last item if
+ * Offset is ITEM_PREV or the first item if Offset is ITEM_NEXT.
+ */
+static void FASTCALL
+MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset)
+{
+ INT i;
+ ROSMENUITEMINFO ItemInfo;
+ INT OrigPos;
+
+ TRACE("hwnd=%x menu=%x off=0x%04x\n", WndOwner, MenuInfo, Offset);
+
+ /* Prevent looping */
+ if (0 == MenuInfo->MenuItemCount || 0 == Offset)
+ return;
+ else if (Offset < -1)
+ Offset = -1;
+ else if (Offset > 1)
+ Offset = 1;
+
+ MenuInitRosMenuItemInfo(&ItemInfo);
+
+ OrigPos = MenuInfo->FocusedItem;
+ if (OrigPos == NO_SELECTED_ITEM) /* NO_SELECTED_ITEM is not -1 ! */
+ {
+ OrigPos = 0;
+ i = -1;
+ }
+ else
+ {
+ i = MenuInfo->FocusedItem;
+ }
+
+ do
+ {
+ /* Step */
+ i += Offset;
+ /* Clip and wrap around */
+ if (i < 0)
+ {
+ i = MenuInfo->MenuItemCount - 1;
+ }
+ else if (i >= MenuInfo->MenuItemCount)
+ {
+ i = 0;
+ }
+ /* If this is a good candidate; */
+ if (MenuGetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo) &&
+ 0 == (ItemInfo.fType & MF_SEPARATOR))
+ {
+ MenuSelectItem(WndOwner, MenuInfo, i, TRUE, NULL);
+ MenuCleanupRosMenuItemInfo(&ItemInfo);
+ return;
+ }
+ } while (i != OrigPos);
+
+ /* Not found */
+ MenuCleanupRosMenuItemInfo(&ItemInfo);
+}
+
+LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
TRACE("YES! hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message,
wParam, lParam);
@@ -1532,9 +1723,9 @@
case WM_DESTROY:
/* zero out global pointer in case resident popup window was destroyed. */
- if (Wnd == TopPopup)
- {
- TopPopup = NULL;
+ if (Wnd == top_popup)
+ {
+ top_popup = NULL;
}
break;
@@ -1604,9 +1795,9 @@
case WM_DESTROY:
/* zero out global pointer in case resident popup window was destroyed. */
- if (Wnd == TopPopup)
- {
- TopPopup = NULL;
+ if (Wnd == top_popup)
+ {
+ top_popup = NULL;
}
break;
@@ -1640,140 +1831,134 @@
}
/**********************************************************************
+ * MENU_ParseResource
+ *
+ * Parse a standard menu resource and add items to the menu.
+ * Return a pointer to the end of the resource.
+ *
+ * NOTE: flags is equivalent to the mtOption field
+ */
+static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
+{
+ WORD flags, id = 0;
+ HMENU hSubMenu;
+ LPCSTR str;
+ BOOL end = FALSE;
+
+ do
+ {
+ flags = GET_WORD(res);
+
+ /* remove MF_END flag before passing it to AppendMenu()! */
+ end = (flags & MF_END);
+ if(end) flags ^= MF_END;
+
+ res += sizeof(WORD);
+ if(!(flags & MF_POPUP))
+ {
+ id = GET_WORD(res);
+ res += sizeof(WORD);
+ }
+ str = res;
+ if(!unicode)
+ res += strlen(str) + 1;
+ else
+ res += (strlenW((LPCWSTR)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);
+ }
+ 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);
+ }
+ } while(!end);
+ return res;
+}
+
+
+/**********************************************************************
* MENUEX_ParseResource
*
* Parse an extended menu resource and add items to the menu.
* Return a pointer to the end of the resource.
- *
- * FIXME - should we be passing an LPCSTR to a predominantly UNICODE function?
*/
static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
{
- WORD resinfo;
-
- do
- {
- MENUITEMINFOW mii;
-
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE;
- mii.fType = GET_DWORD(res);
- res += sizeof(DWORD);
- mii.fState = GET_DWORD(res);
- res += sizeof(DWORD);
- mii.wID = GET_DWORD(res);
- res += sizeof(DWORD);
- resinfo = GET_WORD(res);
- res += sizeof(WORD);
- /* Align the text on a word boundary. */
- res += (~((int)res - 1)) & 1;
- mii.dwTypeData = (LPWSTR) res;
- res += (1 + strlenW(mii.dwTypeData)) * sizeof(WCHAR);
- /* Align the following fields on a dword boundary. */
- res += (~((int)res - 1)) & 3;
-
- if (resinfo & 1) /* Pop-up? */
- {
- /* DWORD helpid = GET_DWORD(res); FIXME: use this. */
- res += sizeof(DWORD);
- mii.hSubMenu = CreatePopupMenu();
- if (!mii.hSubMenu)
- return NULL;
- if (!(res = MENUEX_ParseResource(res, mii.hSubMenu)))
- {
- DestroyMenu(mii.hSubMenu);
- return NULL;
- }
- mii.fMask |= MIIM_SUBMENU;
- mii.fType |= MF_POPUP;
- mii.wID = (UINT) mii.hSubMenu;
- }
- else if(!*mii.dwTypeData && !(mii.fType & MF_SEPARATOR))
- {
- mii.fType |= MF_SEPARATOR;
- }
- InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
- }
- while (!(resinfo & MF_END));
- return res;
-}
-
-
-/**********************************************************************
- * MENU_ParseResource
- *
- * Parse a standard menu resource and add items to the menu.
- * Return a pointer to the end of the resource.
- *
- * NOTE: flags is equivalent to the mtOption field
- */
-static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
-{
- WORD flags, id = 0;
- HMENU hSubMenu;
- LPCSTR str;
- BOOL end = FALSE;
-
- do
- {
- flags = GET_WORD(res);
-
- /* remove MF_END flag before passing it to AppendMenu()! */
- end = (flags & MF_END);
- if(end) flags ^= MF_END;
-
- res += sizeof(WORD);
- if(!(flags & MF_POPUP))
- {
- id = GET_WORD(res);
- res += sizeof(WORD);
- }
- str = res;
- if(!unicode)
- res += strlen(str) + 1;
- else
- res += (strlenW((LPCWSTR)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);
- }
- 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);
- }
- } while(!end);
-
- return res;
-}
-
+ WORD resinfo;
+ do {
+ MENUITEMINFOW mii;
+
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE;
+ mii.fType = GET_DWORD(res);
+ res += sizeof(DWORD);
+ mii.fState = GET_DWORD(res);
+ res += sizeof(DWORD);
+ mii.wID = GET_DWORD(res);
+ res += sizeof(DWORD);
+ resinfo = GET_WORD(res);
+ res += sizeof(WORD);
+ /* Align the text on a word boundary. */
+ res += (~((UINT_PTR)res - 1)) & 1;
+ mii.dwTypeData = (LPWSTR) res;
+ res += (1 + strlenW(mii.dwTypeData)) * sizeof(WCHAR);
+ /* Align the following fields on a dword boundary. */
+ res += (~((UINT_PTR)res - 1)) & 3;
+
+ TRACE("Menu item: [%08x,%08x,%04x,%04x,%S]\n",
+ mii.fType, mii.fState, mii.wID, resinfo, mii.dwTypeData);
+
+ if (resinfo & 1) { /* Pop-up? */
+ /* DWORD helpid = GET_DWORD(res); FIXME: use this. */
+ res += sizeof(DWORD);
+ mii.hSubMenu = CreatePopupMenu();
+ if (!mii.hSubMenu)
+ return NULL;
+ if (!(res = MENUEX_ParseResource(res, mii.hSubMenu))) {
+ DestroyMenu(mii.hSubMenu);
+ return NULL;
+ }
+ mii.fMask |= MIIM_SUBMENU;
+ mii.fType |= MF_POPUP;
+ mii.wID = (UINT) mii.hSubMenu;
+ }
+ else if(!*mii.dwTypeData && !(mii.fType & MF_SEPARATOR))
+ {
+ mii.fType |= MF_SEPARATOR;
+ }
+ InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
+ } while (!(resinfo & MF_END));
+ return res;
+}
NTSTATUS WINAPI
User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength)
@@ -1936,272 +2121,6 @@
}
/***********************************************************************
- * MenuInitTracking
- */
-static BOOL FASTCALL
-MenuInitTracking(HWND Wnd, HMENU Menu, BOOL Popup, UINT Flags)
-{
- TRACE("Wnd=%p Menu=%p\n", Wnd, Menu);
-
- HideCaret(0);
-
- /* Send WM_ENTERMENULOOP and WM_INITMENU message only if TPM_NONOTIFY flag is not
specified */
- if (0 == (Flags & TPM_NONOTIFY))
- {
- SendMessageW(Wnd, WM_ENTERMENULOOP, Popup, 0);
- }
-
- SendMessageW(Wnd, WM_SETCURSOR, (WPARAM) Wnd, HTCAPTION);
-
- if (0 == (Flags & TPM_NONOTIFY))
- {
- ROSMENUINFO MenuInfo;
-
- SendMessageW(Wnd, WM_INITMENU, (WPARAM)Menu, 0);
-
- MenuGetRosMenuInfo(&MenuInfo, Menu);
-
- if (0 == MenuInfo.Height)
- {
- /* app changed/recreated menu bar entries in WM_INITMENU
- Recalculate menu sizes else clicks will not work */
- SetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
- SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
-
- }
- /* This makes the menus of applications built with Delphi work.
- * 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(MenuInfo.Self == Menu)
- {
- MenuInfo.Wnd = Wnd;
- MenuSetRosMenuInfo(&MenuInfo);
- }
- }
-
- return TRUE;
-}
-
-/***********************************************************************
- * MenuFindSubMenu
- *
- * Find a Sub menu. Return the position of the submenu, and modifies
- * *hmenu in case it is found in another sub-menu.
- * If the submenu cannot be found, NO_SELECTED_ITEM is returned.
- */
-static UINT FASTCALL
-MenuFindSubMenu(HMENU *Menu, HMENU SubTarget)
-{
- ROSMENUINFO MenuInfo;
- ROSMENUITEMINFO ItemInfo;
- UINT i;
- HMENU SubMenu;
- UINT Pos;
-
- if ((HMENU) 0xffff == *Menu
- || ! MenuGetRosMenuInfo(&MenuInfo, *Menu))
- {
- return NO_SELECTED_ITEM;
- }
-
- MenuInitRosMenuItemInfo(&ItemInfo);
- for (i = 0; i < MenuInfo.MenuItemCount; i++)
- {
- if (! MenuGetRosMenuItemInfo(MenuInfo.Self, i, &ItemInfo))
- {
- MenuCleanupRosMenuItemInfo(&ItemInfo);
- return NO_SELECTED_ITEM;
- }
- if (0 == (ItemInfo.fType & MF_POPUP))
- {
- continue;
- }
- if (ItemInfo.hSubMenu == SubTarget)
- {
- MenuCleanupRosMenuItemInfo(&ItemInfo);
- return i;
- }
- SubMenu = ItemInfo.hSubMenu;
- Pos = MenuFindSubMenu(&SubMenu, SubTarget);
- if (NO_SELECTED_ITEM != Pos)
- {
- *Menu = SubMenu;
- return Pos;
- }
- }
- MenuCleanupRosMenuItemInfo(&ItemInfo);
-
- return NO_SELECTED_ITEM;
-}
-
-/***********************************************************************
- * MenuSelectItem
- */
-static void FASTCALL
-MenuSelectItem(HWND WndOwner, PROSMENUINFO MenuInfo, UINT Index,
- BOOL SendMenuSelect, HMENU TopMenu)
-{
- HDC Dc;
- ROSMENUITEMINFO ItemInfo;
- ROSMENUINFO TopMenuInfo;
- int Pos;
-
- TRACE("owner=%x menu=%p index=0x%04x select=0x%04x\n", WndOwner, MenuInfo,
Index, SendMenuSelect);
-
- if (NULL == MenuInfo || 0 == MenuInfo->MenuItemCount || NULL == MenuInfo->Wnd)
- {
- return;
- }
-
- if (MenuInfo->FocusedItem == Index)
- {
- return;
- }
-
- if (0 != (MenuInfo->Flags & MF_POPUP))
- {
- Dc = GetDC(MenuInfo->Wnd);
- }
- else
- {
- Dc = GetDCEx(MenuInfo->Wnd, 0, DCX_CACHE | DCX_WINDOW);
- }
-
- if (NULL == TopPopup)
- {
- TopPopup = MenuInfo->Wnd;
- }
-
- SelectObject(Dc, hMenuFont);
- MenuInitRosMenuItemInfo(&ItemInfo);
- /* Clear previous highlighted item */
- if (NO_SELECTED_ITEM != MenuInfo->FocusedItem)
- {
- if (MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem,
&ItemInfo))
- {
- ItemInfo.fMask |= MIIM_STATE;
- ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
- MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem,
&ItemInfo);
- }
- MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo,
- MenuInfo->Height, ! (MenuInfo->Flags & MF_POPUP),
- ODA_SELECT);
- }
-
- /* Highlight new item (if any) */
- MenuInfo->FocusedItem = Index;
- MenuSetRosMenuInfo(MenuInfo);
- if (NO_SELECTED_ITEM != MenuInfo->FocusedItem)
- {
- if (MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem,
&ItemInfo))
- {
- if (0 == (ItemInfo.fType & MF_SEPARATOR))
- {
- ItemInfo.fMask |= MIIM_STATE;
- ItemInfo.fState |= MF_HILITE;
- MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem,
&ItemInfo);
- MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc,
- &ItemInfo, MenuInfo->Height, ! (MenuInfo->Flags
& MF_POPUP),
- ODA_SELECT);
- }
- if (SendMenuSelect)
- {
- SendMessageW(WndOwner, WM_MENUSELECT,
- MAKELONG(ItemInfo.fType & MF_POPUP ? Index :
ItemInfo.wID,
- ItemInfo.fType | ItemInfo.fState | MF_MOUSESELECT |
- (MenuInfo->Flags & MF_SYSMENU)), (LPARAM)
MenuInfo->Self);
- }
- }
- }
- else if (SendMenuSelect)
- {
- if (NULL != TopMenu)
- {
- Pos = MenuFindSubMenu(&TopMenu, MenuInfo->Self);
- if (NO_SELECTED_ITEM != Pos)
- {
- if (MenuGetRosMenuInfo(&TopMenuInfo, TopMenu)
- && MenuGetRosMenuItemInfo(TopMenu, Pos, &ItemInfo))
- {
- SendMessageW(WndOwner, WM_MENUSELECT,
- MAKELONG(Pos, ItemInfo.fType | ItemInfo.fState
- | MF_MOUSESELECT
- | (TopMenuInfo.Flags & MF_SYSMENU)),
- (LPARAM) TopMenu);
- }
- }
- }
- }
- MenuCleanupRosMenuItemInfo(&ItemInfo);
- ReleaseDC(MenuInfo->Wnd, Dc);
-}
-
-/***********************************************************************
- * MenuMoveSelection
- *
- * Moves currently selected item according to the Offset parameter.
- * If there is no selection then it should select the last item if
- * Offset is ITEM_PREV or the first item if Offset is ITEM_NEXT.
- */
-static void FASTCALL
-MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset)
-{
- INT i;
- ROSMENUITEMINFO ItemInfo;
- INT OrigPos;
-
- TRACE("hwnd=%x menu=%x off=0x%04x\n", WndOwner, MenuInfo, Offset);
-
- /* Prevent looping */
- if (0 == MenuInfo->MenuItemCount || 0 == Offset)
- return;
- else if (Offset < -1)
- Offset = -1;
- else if (Offset > 1)
- Offset = 1;
-
- MenuInitRosMenuItemInfo(&ItemInfo);
-
- OrigPos = MenuInfo->FocusedItem;
- if (OrigPos == NO_SELECTED_ITEM) /* NO_SELECTED_ITEM is not -1 ! */
- {
- OrigPos = 0;
- i = -1;
- }
- else
- {
- i = MenuInfo->FocusedItem;
- }
-
- do
- {
- /* Step */
- i += Offset;
- /* Clip and wrap around */
- if (i < 0)
- {
- i = MenuInfo->MenuItemCount - 1;
- }
- else if (i >= MenuInfo->MenuItemCount)
- {
- i = 0;
- }
- /* If this is a good candidate; */
- if (MenuGetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo) &&
- 0 == (ItemInfo.fType & MF_SEPARATOR))
- {
- MenuSelectItem(WndOwner, MenuInfo, i, TRUE, NULL);
- MenuCleanupRosMenuItemInfo(&ItemInfo);
- return;
- }
- } while (i != OrigPos);
-
- /* Not found */
- MenuCleanupRosMenuItemInfo(&ItemInfo);
-}
-
-/***********************************************************************
* MenuInitSysMenuPopup
*
* Grey the appropriate items in System menu.
@@ -2400,7 +2319,7 @@
TRACE("owner=%x menu=%x 0x%04x\n", WndOwner, MenuInfo, SendMenuSelect);
- if (NULL != MenuInfo && NULL != TopPopup && NO_SELECTED_ITEM !=
MenuInfo->FocusedItem)
+ if (NULL != MenuInfo && NULL != top_popup && NO_SELECTED_ITEM !=
MenuInfo->FocusedItem)
{
MenuInitRosMenuItemInfo(&ItemInfo);
ItemInfo.fMask |= MIIM_FTYPE | MIIM_STATE;
@@ -3150,36 +3069,29 @@
*
* Handle a VK_RIGHT key event in a menu.
*/
-static void FASTCALL
-MenuKeyRight(MTRACKER *Mt, UINT Flags)
-{
- HMENU MenuTmp;
- ROSMENUINFO MenuInfo;
- ROSMENUINFO CurrentMenuInfo;
- UINT NextCol;
-
- TRACE("MenuKeyRight called, cur %p, top %p.\n",
+static void FASTCALL MenuKeyRight(MTRACKER *Mt, UINT Flags)
+{
+ HMENU hmenutmp;
+ ROSMENUINFO MenuInfo;
+ ROSMENUINFO CurrentMenuInfo;
+ UINT NextCol;
+
+ TRACE("MenuKeyRight called, cur %p, top %p.\n",
Mt->CurrentMenu, Mt->TopMenu);
- if (! MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu))
- {
- return;
- }
- if (0 != (MenuInfo.Flags & MF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu))
+ if (! MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu)) return;
+ if ((MenuInfo.Flags & MF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu))
{
/* If already displaying a popup, try to display sub-popup */
- MenuTmp = Mt->CurrentMenu;
+ hmenutmp = Mt->CurrentMenu;
if (MenuGetRosMenuInfo(&CurrentMenuInfo, Mt->CurrentMenu))
{
Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &CurrentMenuInfo,
TRUE, Flags);
}
/* if subpopup was displayed then we are done */
- if (MenuTmp != Mt->CurrentMenu)
- {
- return;
- }
+ if (hmenutmp != Mt->CurrentMenu) return;
}
if (! MenuGetRosMenuInfo(&CurrentMenuInfo, Mt->CurrentMenu))
@@ -3203,20 +3115,18 @@
if (Mt->CurrentMenu != Mt->TopMenu)
{
MenuHideSubPopups(Mt->OwnerWnd, &MenuInfo, FALSE );
- MenuTmp = Mt->CurrentMenu = Mt->TopMenu;
+ hmenutmp = Mt->CurrentMenu = Mt->TopMenu;
}
else
{
- MenuTmp = NULL;
+ hmenutmp = NULL;
}
/* try to move to the next item */
- if (! MenuDoNextMenu(Mt, VK_RIGHT))
- {
+ if ( !MenuDoNextMenu(Mt, VK_RIGHT))
MenuMoveSelection(Mt->OwnerWnd, &MenuInfo, ITEM_NEXT);
- }
-
- if (NULL != MenuTmp || 0 != (Mt->TrackFlags & TF_SUSPENDPOPUP))
+
+ if ( hmenutmp || Mt->TrackFlags & TF_SUSPENDPOPUP )
{
if (! MenuSuspendPopup(Mt, WM_KEYDOWN)
&& MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu))
@@ -3233,220 +3143,211 @@
*
* Menu tracking code.
*/
-static INT FASTCALL
-MenuTrackMenu(HMENU Menu, UINT Flags, INT x, INT y,
- HWND Wnd, const RECT *Rect )
-{
- MSG Msg;
- ROSMENUINFO MenuInfo;
- ROSMENUITEMINFO ItemInfo;
- BOOL fRemove;
- INT ExecutedMenuId = -1;
- MTRACKER Mt;
- BOOL EnterIdleSent = FALSE;
-
- Mt.TrackFlags = 0;
- Mt.CurrentMenu = Menu;
- Mt.TopMenu = Menu;
- Mt.OwnerWnd = Wnd;
- Mt.Pt.x = x;
- Mt.Pt.y = y;
-
- TRACE("Menu=%x Flags=0x%08x (%d,%d) Wnd=%x (%ld,%ld)-(%ld,%ld)\n",
- Menu, Flags, x, y, Wnd, Rect ? Rect->left : 0, Rect ? Rect->top : 0,
- Rect ? Rect->right : 0, Rect ? Rect->bottom : 0);
-
- if (!IsMenu(Menu))
- {
- SetLastError( ERROR_INVALID_MENU_HANDLE );
- return FALSE;
- }
-
- fEndMenu = FALSE;
- if (! MenuGetRosMenuInfo(&MenuInfo, Menu))
- {
- return FALSE;
- }
-
- if (0 != (Flags & TPM_BUTTONDOWN))
- {
- /* Get the result in order to start the tracking or not */
- fRemove = MenuButtonDown(&Mt, Menu, Flags);
- fEndMenu = ! fRemove;
- }
-
- SetCapture(Mt.OwnerWnd);
- (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, Mt.OwnerWnd);
-
- ERR("MenuTrackMenu 1\n");
- while (! fEndMenu)
- {
- PVOID menu = ValidateHandle(Mt.CurrentMenu, VALIDATE_TYPE_MENU);
- if (!menu) /* sometimes happens if I do a window manager close */
- break;
-
- /* we have to keep the message in the queue until it's
- * clear that menu loop is not over yet. */
-
- for (;;)
- {
- if (PeekMessageW(&Msg, 0, 0, 0, PM_NOREMOVE))
+static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
+ HWND hwnd, const RECT *lprect )
+{
+ MSG msg;
+ ROSMENUINFO MenuInfo;
+ ROSMENUITEMINFO ItemInfo;
+ BOOL fRemove;
+ INT executedMenuId = -1;
+ MTRACKER mt;
+ BOOL enterIdleSent = FALSE;
+
+ mt.TrackFlags = 0;
+ mt.CurrentMenu = hmenu;
+ mt.TopMenu = hmenu;
+ mt.OwnerWnd = hwnd;
+ mt.Pt.x = x;
+ mt.Pt.y = y;
+
+ TRACE("hmenu=%p flags=0x%08x (%d,%d) hwnd=%x (%ld,%ld)-(%ld,%ld)\n",
+ hmenu, wFlags, x, y, hwnd, lprect ? lprect->left : 0, lprect ? lprect->top
: 0,
+ lprect ? lprect->right : 0, lprect ? lprect->bottom : 0);
+
+ if (!IsMenu(hmenu))
+ {
+ SetLastError( ERROR_INVALID_MENU_HANDLE );
+ 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 );
+ fEndMenu = !fRemove;
+ }
+
+ SetCapture(mt.OwnerWnd);
+ (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, mt.OwnerWnd);
+
+ ERR("MenuTrackMenu 1\n");
+ while (! fEndMenu)
+ {
+ PVOID menu = ValidateHandle(mt.CurrentMenu, VALIDATE_TYPE_MENU);
+ if (!menu) /* sometimes happens if I do a window manager close */
+ break;
+
+ /* we have to keep the message in the queue until it's
+ * clear that menu loop is not over yet. */
+
+ for (;;)
+ {
+ if (PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ))
{
- if (! CallMsgFilterW(&Msg, MSGF_MENU))
+ if (!CallMsgFilterW( &msg, MSGF_MENU )) break;
+ /* remove the message from the queue */
+ PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
+ }
+ else
+ {
+ if (!enterIdleSent)
{
- break;
+ HWND win = (wFlags & TPM_ENTERIDLEEX) && (MenuInfo.Flags
& MF_POPUP) ? MenuInfo.Wnd : NULL;
+ enterIdleSent = TRUE;
+ SendMessageW( mt.OwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM) win);
}
- /* remove the message from the queue */
- PeekMessageW(&Msg, 0, Msg.message, Msg.message, PM_REMOVE );
+ WaitMessage();
}
- else
+ }
+
+ /* check if EndMenu() tried to cancel us, by posting this message */
+ if (msg.message == WM_CANCELMODE)
+ {
+ /* we are now out of the loop */
+ fEndMenu = TRUE;
+
+ /* remove the message from the queue */
+ PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
+
+ /* break out of internal loop, ala ESCAPE */
+ break;
+ }
+
+ TranslateMessage( &msg );
+ mt.Pt = msg.pt;
+
+ if ( (msg.hwnd == MenuInfo.Wnd) || (msg.message!=WM_TIMER) )
+ enterIdleSent=FALSE;
+
+ fRemove = FALSE;
+ if ((msg.message >= WM_MOUSEFIRST) && (msg.message <=
WM_MOUSELAST))
+ {
+ /*
+ * Use the mouse coordinates in lParam instead of those in the MSG
+ * struct to properly handle synthetic messages. They are already
+ * in screen coordinates.
+ */
+ mt.Pt.x = (short)LOWORD(msg.lParam);
+ mt.Pt.y = (short)HIWORD(msg.lParam);
+
+ /* Find a menu for this mouse event */
+ hmenu = MenuPtMenu(mt.TopMenu, mt.Pt);
+
+ switch(msg.message)
{
- if (! EnterIdleSent)
- {
- HWND Win = (0 != (Flags & TPM_ENTERIDLEEX)
- && 0 != (MenuInfo.Flags & MF_POPUP)) ?
MenuInfo.Wnd : NULL;
- EnterIdleSent = TRUE;
- SendMessageW(Mt.OwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM) Win);
- }
- WaitMessage();
- }
- }
-
- /* check if EndMenu() tried to cancel us, by posting this message */
- if (Msg.message == WM_CANCELMODE)
- {
- /* we are now out of the loop */
- fEndMenu = TRUE;
-
- /* remove the message from the queue */
- PeekMessageW(&Msg, 0, Msg.message, Msg.message, PM_REMOVE);
-
- /* break out of internal loop, ala ESCAPE */
- break;
- }
-
- TranslateMessage(&Msg);
- Mt.Pt = Msg.pt;
-
- if (Msg.hwnd == MenuInfo.Wnd || Msg.message != WM_TIMER)
- {
- EnterIdleSent = FALSE;
- }
-
- fRemove = FALSE;
- if ((Msg.message >= WM_MOUSEFIRST) && (Msg.message <= WM_MOUSELAST))
- {
- /*
- * Use the mouse coordinates in lParam instead of those in the MSG
- * struct to properly handle synthetic messages. They are already
- * in screen coordinates.
- */
- Mt.Pt.x = (short) LOWORD(Msg.lParam);
- Mt.Pt.y = (short) HIWORD(Msg.lParam);
-
- /* Find a menu for this mouse event */
- Menu = MenuPtMenu(Mt.TopMenu, Mt.Pt);
-
- switch(Msg.message)
- {
- /* no WM_NC... messages in captured state */
-
- case WM_RBUTTONDBLCLK:
- case WM_RBUTTONDOWN:
- if (!(Flags & TPM_RIGHTBUTTON)) break;
+ /* no WM_NC... messages in captured state */
+
+ case WM_RBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ if (!(wFlags & TPM_RIGHTBUTTON)) break;
/* fall through */
- case WM_LBUTTONDBLCLK:
- case WM_LBUTTONDOWN:
+ case WM_LBUTTONDBLCLK:
+ case WM_LBUTTONDOWN:
/* If the message belongs to the menu, removes it from the queue */
/* Else, end menu tracking */
- fRemove = MenuButtonDown(&Mt, Menu, Flags);
- fEndMenu = ! fRemove;
+ fRemove = MenuButtonDown(&mt, hmenu, wFlags);
+ fEndMenu = !fRemove;
break;
- case WM_RBUTTONUP:
- if (0 == (Flags & TPM_RIGHTBUTTON)) break;
+ case WM_RBUTTONUP:
+ if (!(wFlags & TPM_RIGHTBUTTON)) break;
/* fall through */
- case WM_LBUTTONUP:
+ case WM_LBUTTONUP:
/* Check if a menu was selected by the mouse */
- if (Menu)
- {
- ExecutedMenuId = MenuButtonUp(&Mt, Menu, Flags);
-
- /* End the loop if ExecutedMenuId is an item ID */
- /* or if the job was done (ExecutedMenuId = 0). */
- fEndMenu = fRemove = (-1 != ExecutedMenuId);
- }
+ if (hmenu)
+ {
+ executedMenuId = MenuButtonUp( &mt, hmenu, wFlags);
+
+ /* End the loop if executedMenuId is an item ID */
+ /* or if the job was done (executedMenuId = 0). */
+ fEndMenu = fRemove = (executedMenuId != -1);
+ }
else
- {
+ {
/* No menu was selected by the mouse */
/* if the function was called by TrackPopupMenu, continue
with the menu tracking. If not, stop it */
- fEndMenu = (0 != (Flags & TPM_POPUPMENU) ? FALSE : TRUE);
- }
+ fEndMenu = ((wFlags & TPM_POPUPMENU) ? FALSE : TRUE);
+ }
break;
- case WM_MOUSEMOVE:
- if (Menu)
- {
- fEndMenu |= !MenuMouseMove(&Mt, Menu, Flags);
- }
+ case WM_MOUSEMOVE:
+ if (hmenu)
+ fEndMenu |= !MenuMouseMove(&mt, hmenu, wFlags);
break;
- } /* switch(Msg.message) - mouse */
- }
- else if ((Msg.message >= WM_KEYFIRST) && (Msg.message <=
WM_KEYLAST))
+ } /* switch(Msg.message) - mouse */
+ }
+ else if ((msg.message >= WM_KEYFIRST) && (msg.message <=
WM_KEYLAST))
{
fRemove = TRUE; /* Keyboard messages are always removed */
- switch(Msg.message)
+ switch(msg.message)
{
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
- switch(Msg.wParam)
+ switch(msg.wParam)
{
case VK_MENU:
fEndMenu = TRUE;
break;
case VK_HOME:
case VK_END:
- if (MenuGetRosMenuInfo(&MenuInfo, Mt.CurrentMenu))
+ if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
{
- MenuSelectItem(Mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM,
+ MenuSelectItem(mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM,
FALSE, 0 );
- MenuMoveSelection(Mt.OwnerWnd, &MenuInfo,
- VK_HOME == Msg.wParam ? ITEM_NEXT :
ITEM_PREV);
+ MenuMoveSelection(mt.OwnerWnd, &MenuInfo,
+ VK_HOME == msg.wParam ? ITEM_NEXT :
ITEM_PREV);
}
break;
case VK_UP:
case VK_DOWN: /* If on menu bar, pull-down the menu */
- if (MenuGetRosMenuInfo(&MenuInfo, Mt.CurrentMenu))
+ if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
{
- if (0 == (MenuInfo.Flags & MF_POPUP))
+ if (!(MenuInfo.Flags & MF_POPUP))
{
- if (MenuGetRosMenuInfo(&MenuInfo, Mt.TopMenu))
+ if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
{
- Mt.CurrentMenu = MenuShowSubPopup(Mt.OwnerWnd,
&MenuInfo,
- TRUE, Flags);
+ mt.CurrentMenu = MenuShowSubPopup(mt.OwnerWnd,
&MenuInfo,
+ TRUE, wFlags);
}
}
else /* otherwise try to move selection */
{
- MenuMoveSelection(Mt.OwnerWnd, &MenuInfo,
- VK_DOWN == Msg.wParam ? ITEM_NEXT :
ITEM_PREV);
+ MenuMoveSelection(mt.OwnerWnd, &MenuInfo,
+ VK_DOWN == msg.wParam ? ITEM_NEXT :
ITEM_PREV);
}
}
break;
case VK_LEFT:
- MenuKeyLeft(&Mt, Flags);
+ MenuKeyLeft(&mt, wFlags);
break;
case VK_RIGHT:
- MenuKeyRight(&Mt, Flags);
+ MenuKeyRight(&mt, wFlags);
break;
case VK_ESCAPE:
- fEndMenu = MenuKeyEscape(&Mt, Flags);
+ fEndMenu = MenuKeyEscape(&mt, wFlags);
break;
case VK_F1:
@@ -3454,12 +3355,9 @@
HELPINFO hi;
hi.cbSize = sizeof(HELPINFO);
hi.iContextType = HELPINFO_MENUITEM;
- if (MenuGetRosMenuInfo(&MenuInfo, Mt.CurrentMenu))
+ if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
{
- if (NO_SELECTED_ITEM == MenuInfo.FocusedItem)
- {
- hi.iCtrlId = 0;
- }
+ if (MenuInfo.FocusedItem == NO_SELECTED_ITEM) hi.iCtrlId =
0;
else
{
MenuInitRosMenuItemInfo(&ItemInfo);
@@ -3476,10 +3374,10 @@
MenuCleanupRosMenuItemInfo(&ItemInfo);
}
}
- hi.hItemHandle = Menu;
- hi.dwContextId = MenuInfo.dwContextHelpID;
- hi.MousePos = Msg.pt;
- SendMessageW(Wnd, WM_HELP, 0, (LPARAM) &hi);
+ hi.hItemHandle = hmenu;
+ hi.dwContextId = MenuInfo.dwContextHelpID;
+ hi.MousePos = msg.pt;
+ SendMessageW(hwnd, WM_HELP, 0, (LPARAM) &hi);
break;
}
@@ -3488,187 +3386,218 @@
}
break; /* WM_KEYDOWN */
- case WM_CHAR:
- case WM_SYSCHAR:
+ case WM_CHAR:
+ case WM_SYSCHAR:
{
- UINT Pos;
-
- if (! MenuGetRosMenuInfo(&MenuInfo, Mt.CurrentMenu))
+ UINT pos;
+
+ if (! MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu)) break;
+ if (msg.wParam == L'\r' || msg.wParam == L' ')
{
- break;
+ executedMenuId = MenuExecFocusedItem(&mt, &MenuInfo,
wFlags);
+ fEndMenu = (executedMenuId != -2);
+ break;
}
- if (L'\r' == Msg.wParam || L' ' == Msg.wParam)
+
+ /* Hack to avoid control chars. */
+ /* We will find a better way real soon... */
+ if (msg.wParam < 32) break;
+
+ pos = MenuFindItemByKey(mt.OwnerWnd, &MenuInfo,
+ LOWORD(msg.wParam), FALSE);
+ if (pos == (UINT)-2) fEndMenu = TRUE;
+ else if (pos == (UINT)-1) MessageBeep(0);
+ else
{
- ExecutedMenuId = MenuExecFocusedItem(&Mt, &MenuInfo,
Flags);
- fEndMenu = (ExecutedMenuId != -2);
- break;
+ MenuSelectItem(mt.OwnerWnd, &MenuInfo, pos,
+ TRUE, 0);
+ executedMenuId = MenuExecFocusedItem(&mt, &MenuInfo,
wFlags);
+ fEndMenu = (executedMenuId != -2);
}
-
- /* Hack to avoid control chars. */
- /* We will find a better way real soon... */
- if (Msg.wParam < 32)
- {
- break;
- }
-
- Pos = MenuFindItemByKey(Mt.OwnerWnd, &MenuInfo,
- LOWORD(Msg.wParam), FALSE);
- if ((UINT) -2 == Pos)
- {
- fEndMenu = TRUE;
- }
- else if ((UINT) -1 == Pos)
- {
- MessageBeep(0);
- }
- else
- {
- MenuSelectItem(Mt.OwnerWnd, &MenuInfo, Pos, TRUE, 0);
- ExecutedMenuId = MenuExecFocusedItem(&Mt, &MenuInfo,
Flags);
- fEndMenu = (-2 != ExecutedMenuId);
- }
- }
- break;
+ }
+ break;
} /* switch(msg.message) - kbd */
}
- else
- {
- PeekMessageW( &Msg, 0, Msg.message, Msg.message, PM_REMOVE );
- DispatchMessageW(&Msg);
- continue;
- }
-
- if (! fEndMenu)
- {
- fRemove = TRUE;
- }
-
- /* finally remove message from the queue */
-
- if (fRemove && 0 == (Mt.TrackFlags & TF_SKIPREMOVE))
- {
- PeekMessageW(&Msg, 0, Msg.message, Msg.message, PM_REMOVE);
- }
- else
- {
- Mt.TrackFlags &= ~TF_SKIPREMOVE;
- }
- }
- ERR("MenuTrackMenu 2\n");
-
- (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
- SetCapture(NULL); /* release the capture */
-
- /* If dropdown is still painted and the close box is clicked on
- then the menu will be destroyed as part of the DispatchMessage above.
- This will then invalidate the menu handle in Mt.hTopMenu. We should
- check for this first. */
- if (IsMenu(Mt.TopMenu))
- {
- if (IsWindow(Mt.OwnerWnd))
- {
- if (MenuGetRosMenuInfo(&MenuInfo, Mt.TopMenu))
+ else
+ {
+ PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
+ DispatchMessageW( &msg );
+ continue;
+ }
+
+ if (!fEndMenu) fRemove = TRUE;
+
+ /* finally remove message from the queue */
+
+ if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) )
+ PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
+ else mt.TrackFlags &= ~TF_SKIPREMOVE;
+ }
+
+ (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
+ SetCapture(NULL); /* release the capture */
+
+ /* If dropdown is still painted and the close box is clicked on
+ then the menu will be destroyed as part of the DispatchMessage above.
+ This will then invalidate the menu handle in mt.hTopMenu. We should
+ check for this first. */
+ if( IsMenu( mt.TopMenu ) )
+ {
+ if (IsWindow(mt.OwnerWnd))
+ {
+ if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
{
- MenuHideSubPopups(Mt.OwnerWnd, &MenuInfo, FALSE);
-
- if (0 != (MenuInfo.Flags & MF_POPUP))
+ MenuHideSubPopups(mt.OwnerWnd, &MenuInfo, FALSE);
+
+ if (MenuInfo.Flags & MF_POPUP)
{
- DestroyWindow(MenuInfo.Wnd);
- MenuInfo.Wnd = NULL;
-
- if (!(MenuInfo.Flags & TPM_NONOTIFY))
- SendMessageW( Mt.OwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)Mt.TopMenu,
+ DestroyWindow(MenuInfo.Wnd);
+ MenuInfo.Wnd = NULL;
+
+ if (!(MenuInfo.Flags & TPM_NONOTIFY))
+ SendMessageW( mt.OwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.TopMenu,
MAKELPARAM(0, IS_SYSTEM_MENU(&MenuInfo)) );
}
- MenuSelectItem(Mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM, FALSE, NULL);
+ MenuSelectItem( mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM, FALSE, 0
);
}
- SendMessageW(Mt.OwnerWnd, WM_MENUSELECT, MAKELONG(0, 0xffff), 0);
- }
-
- if (MenuGetRosMenuInfo(&MenuInfo, Mt.TopMenu))
- {
- /* Reset the variable for hiding menu */
- MenuInfo.TimeToHide = FALSE;
- MenuSetRosMenuInfo(&MenuInfo);
- }
- }
-
- /* The return value is only used by TrackPopupMenu */
- if (!(Flags & TPM_RETURNCMD)) return TRUE;
- if (ExecutedMenuId < 0) ExecutedMenuId = 0;
- return ExecutedMenuId;
-}
-
+ SendMessageW( mt.OwnerWnd, WM_MENUSELECT, MAKEWPARAM(0, 0xffff), 0 );
+ }
+
+ /* Reset the variable for hiding menu */
+ if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
+ {
+ MenuInfo.TimeToHide = FALSE;
+ MenuSetRosMenuInfo(&MenuInfo);
+ }
+ }
+
+ /* The return value is only used by TrackPopupMenu */
+ if (!(wFlags & TPM_RETURNCMD)) return TRUE;
+ if (executedMenuId == -1) executedMenuId = 0;
+ return executedMenuId;
+}
+
+/***********************************************************************
+ * MenuInitTracking
+ */
+static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
+{
+ ROSMENUINFO MenuInfo;
+
+ TRACE("hwnd=%p hmenu=%p\n", hWnd, hMenu);
+
+ HideCaret(0);
+
+ /* Send WM_ENTERMENULOOP and WM_INITMENU message only if TPM_NONOTIFY flag is not
specified */
+ if (!(wFlags & TPM_NONOTIFY))
+ SendMessageW( hWnd, WM_ENTERMENULOOP, bPopup, 0 );
+
+ SendMessageW( hWnd, WM_SETCURSOR, (WPARAM)hWnd, HTCAPTION );
+
+ if (!(wFlags & TPM_NONOTIFY))
+ {
+ SendMessageW( hWnd, WM_INITMENU, (WPARAM)hMenu, 0 );
+
+ MenuGetRosMenuInfo(&MenuInfo, hMenu);
+
+ if (!MenuInfo.Height)
+ {
+ /* app changed/recreated menu bar entries in WM_INITMENU
+ Recalculate menu sizes else clicks will not work */
+ SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
+
+ }
+ /* This makes the menus of applications built with Delphi work.
+ * 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(MenuInfo.Self == hMenu)
+ {
+ MenuInfo.Wnd = hWnd;
+ MenuSetRosMenuInfo(&MenuInfo);
+ }
+ }
+
+ return TRUE;
+}
/***********************************************************************
* MenuExitTracking
*/
-static BOOL FASTCALL
-MenuExitTracking(HWND Wnd)
-{
- TRACE("hwnd=%p\n", Wnd);
-
- SendMessageW(Wnd, WM_EXITMENULOOP, 0, 0);
- ShowCaret(0);
- return TRUE;
-}
-
-
-VOID
-MenuTrackMouseMenuBar(HWND Wnd, ULONG Ht, POINT Pt)
-{
- HMENU Menu = (HTSYSMENU == Ht) ? NtUserGetSystemMenu(Wnd, FALSE) : GetMenu(Wnd);
- UINT Flags = TPM_ENTERIDLEEX | TPM_BUTTONDOWN | TPM_LEFTALIGN | TPM_LEFTBUTTON;
-
- TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", Wnd, Ht, Pt.x, Pt.y);
-
- if (IsMenu(Menu))
- {
- /* map point to parent client coordinates */
- HWND Parent = GetAncestor(Wnd, GA_PARENT );
- if (Parent != GetDesktopWindow())
- {
- ScreenToClient(Parent, &Pt);
- }
-
- MenuInitTracking(Wnd, Menu, FALSE, Flags);
- MenuTrackMenu(Menu, Flags, Pt.x, Pt.y, Wnd, NULL);
- MenuExitTracking(Wnd);
- }
-}
-
-
-VOID
-MenuTrackKbdMenuBar(HWND hWnd, UINT wParam, WCHAR wChar)
+static BOOL FASTCALL MenuExitTracking(HWND hWnd)
+{
+ TRACE("hwnd=%p\n", hWnd);
+
+ SendMessageW( hWnd, WM_EXITMENULOOP, 0, 0 );
+ ShowCaret(0);
+ top_popup = 0;
+ return TRUE;
+}
+
+/***********************************************************************
+ * MenuTrackMouseMenuBar
+ *
+ * Menu-bar tracking upon a mouse event. Called from NC_HandleSysCommand().
+ */
+VOID MenuTrackMouseMenuBar( HWND hWnd, ULONG ht, POINT pt)
+{
+ HMENU hMenu = (ht == HTSYSMENU) ? NtUserGetSystemMenu( hWnd, FALSE) : GetMenu(hWnd);
+ UINT wFlags = TPM_ENTERIDLEEX | TPM_BUTTONDOWN | TPM_LEFTALIGN | TPM_LEFTBUTTON;
+
+ TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", hWnd, ht, pt.x, pt.y);
+
+ if (IsMenu(hMenu))
+ {
+ /* map point to parent client coordinates */
+ HWND Parent = GetAncestor(hWnd, GA_PARENT );
+ if (Parent != GetDesktopWindow())
+ {
+ ScreenToClient(Parent, &pt);
+ }
+
+ MenuInitTracking(hWnd, hMenu, FALSE, wFlags);
+ MenuTrackMenu(hMenu, wFlags, pt.x, pt.y, hWnd, NULL);
+ MenuExitTracking(hWnd);
+ }
+}
+
+
+/***********************************************************************
+ * MenuTrackKbdMenuBar
+ *
+ * Menu-bar tracking upon a keyboard event. Called from NC_HandleSysCommand().
+ */
+VOID MenuTrackKbdMenuBar(HWND hwnd, UINT wParam, WCHAR wChar)
{
UINT uItem = NO_SELECTED_ITEM;
HMENU hTrackMenu;
ROSMENUINFO MenuInfo;
UINT wFlags = TPM_ENTERIDLEEX | TPM_LEFTALIGN | TPM_LEFTBUTTON;
- TRACE("hwnd %p wParam 0x%04x wChar 0x%04x\n", hWnd, wParam, wChar);
+ TRACE("hwnd %p wParam 0x%04x wChar 0x%04x\n", hwnd, wParam, wChar);
/* find window that has a menu */
- while (!((GetWindowLongPtrW( hWnd, GWL_STYLE ) &
+ while (!((GetWindowLongPtrW( hwnd, GWL_STYLE ) &
(WS_CHILD | WS_POPUP)) != WS_CHILD))
- if (!(hWnd = GetAncestor( hWnd, GA_PARENT ))) return;
+ if (!(hwnd = GetAncestor( hwnd, GA_PARENT ))) return;
/* check if we have to track a system menu */
- hTrackMenu = GetMenu( hWnd );
- if (!hTrackMenu || IsIconic(hWnd) || wChar == ' ' )
- {
- if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_SYSMENU)) return;
- hTrackMenu = NtUserGetSystemMenu(hWnd, FALSE);
+ hTrackMenu = GetMenu( hwnd );
+ if (!hTrackMenu || IsIconic(hwnd) || wChar == ' ' )
+ {
+ if (!(GetWindowLongPtrW( hwnd, GWL_STYLE ) & WS_SYSMENU)) return;
+ hTrackMenu = NtUserGetSystemMenu(hwnd, FALSE);
uItem = 0;
wParam |= HTSYSMENU; /* prevent item lookup */
}
if (!IsMenu( hTrackMenu )) return;
- MenuInitTracking( hWnd, hTrackMenu, FALSE, wFlags );
+ MenuInitTracking( hwnd, hTrackMenu, FALSE, wFlags );
if (! MenuGetRosMenuInfo(&MenuInfo, hTrackMenu))
{
@@ -3677,7 +3606,7 @@
if( wChar && wChar != ' ' )
{
- uItem = MenuFindItemByKey( hWnd, &MenuInfo, wChar, (wParam & HTSYSMENU)
);
+ uItem = MenuFindItemByKey( hwnd, &MenuInfo, wChar, (wParam & HTSYSMENU)
);
if ( uItem >= (UINT)(-2) )
{
if( uItem == (UINT)(-1) ) MessageBeep(0);
@@ -3687,7 +3616,7 @@
}
}
- MenuSelectItem( hWnd, &MenuInfo, uItem, TRUE, 0 );
+ MenuSelectItem( hwnd, &MenuInfo, uItem, TRUE, 0 );
if (wParam & HTSYSMENU)
{
@@ -3698,14 +3627,14 @@
else
{
if( uItem == NO_SELECTED_ITEM )
- MenuMoveSelection( hWnd, &MenuInfo, ITEM_NEXT );
+ MenuMoveSelection( hwnd, &MenuInfo, ITEM_NEXT );
else
- PostMessageW( hWnd, WM_KEYDOWN, VK_DOWN, 0L );
+ PostMessageW( hwnd, WM_KEYDOWN, VK_DOWN, 0L );
}
track_menu:
- MenuTrackMenu( hTrackMenu, wFlags, 0, 0, hWnd, NULL );
- MenuExitTracking( hWnd );
+ MenuTrackMenu( hTrackMenu, wFlags, 0, 0, hwnd, NULL );
+ MenuExitTracking( hwnd );
}