Author: jimtabor Date: Sat Aug 8 00:25:04 2015 New Revision: 68621
URL: http://svn.reactos.org/svn/reactos?rev=68621&view=rev Log: [Win32k] - Move menu related functions. Support more system commands. Add a thread based menu structure.
Modified: trunk/reactos/win32ss/user/ntuser/menu.c trunk/reactos/win32ss/user/ntuser/menu.h trunk/reactos/win32ss/user/ntuser/window.c
Modified: trunk/reactos/win32ss/user/ntuser/menu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/menu.c?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/menu.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/menu.c [iso-8859-1] Sat Aug 8 00:25:04 2015 @@ -620,6 +620,7 @@ BOOL FASTCALL IntSetMenuFlagRtoL(PMENU Menu) { + ERR("SetMenuFlagRtoL\n"); Menu->fFlags |= MNF_RTOL; return TRUE; } @@ -704,6 +705,12 @@
Menu->TimeToHide = lpmi->TimeToHide; Menu->hWnd = lpmi->Wnd; + } + if ( lpmi->fMask & MIM_STYLE) + { + if (lpmi->dwStyle & MNS_AUTODISMISS) FIXME("MNS_AUTODISMISS unimplemented wine\n"); + if (lpmi->dwStyle & MNS_DRAGDROP) FIXME("MNS_DRAGDROP unimplemented wine\n"); + if (lpmi->dwStyle & MNS_MODELESS) FIXME("MNS_MODELESS unimplemented wine\n"); } return TRUE; } @@ -971,8 +978,16 @@ MenuItem->fState ^= (res ^ uEnable) & (MF_GRAYED | MF_DISABLED);
/* If the close item in the system menu change update the close button */ - if((MenuItem->wID == SC_CLOSE) && (res != uEnable)) - { + if (res != uEnable) + { + switch (MenuItem->wID) // More than just close. + { + case SC_CLOSE: + case SC_MAXIMIZE: + case SC_MINIMIZE: + case SC_MOVE: + case SC_RESTORE: + case SC_SIZE: if (MenuObject->fFlags & MNF_SYSSUBMENU && MenuObject->spwndNotify != 0) { RECTL rc = MenuObject->spwndNotify->rcWindow; @@ -982,6 +997,9 @@ rc.bottom = 0; co_UserRedrawWindow(MenuObject->spwndNotify, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN); } + default: + break; + } } return res; } @@ -1822,6 +1840,77 @@ return TRUE; }
+BOOL FASTCALL +IntSetMenu( + PWND Wnd, + HMENU Menu, + BOOL *Changed) +{ + PMENU OldMenu, NewMenu = NULL; + + if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD) + { + ERR("SetMenu: Invalid handle 0x%p!\n",UserHMGetHandle(Wnd)); + EngSetLastError(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + + *Changed = (Wnd->IDMenu != (UINT) Menu); + if (! *Changed) + { + return TRUE; + } + + if (Wnd->IDMenu) + { + OldMenu = IntGetMenuObject((HMENU) Wnd->IDMenu); + ASSERT(NULL == OldMenu || OldMenu->hWnd == Wnd->head.h); + } + else + { + OldMenu = NULL; + } + + if (NULL != Menu) + { + NewMenu = IntGetMenuObject(Menu); + if (NULL == NewMenu) + { + if (NULL != OldMenu) + { + IntReleaseMenuObject(OldMenu); + } + EngSetLastError(ERROR_INVALID_MENU_HANDLE); + return FALSE; + } + if (NULL != NewMenu->hWnd) + { + /* Can't use the same menu for two windows */ + if (NULL != OldMenu) + { + IntReleaseMenuObject(OldMenu); + } + EngSetLastError(ERROR_INVALID_MENU_HANDLE); + return FALSE; + } + + } + + Wnd->IDMenu = (UINT) Menu; + if (NULL != NewMenu) + { + NewMenu->hWnd = Wnd->head.h; + IntReleaseMenuObject(NewMenu); + } + if (NULL != OldMenu) + { + OldMenu->hWnd = NULL; + IntReleaseMenuObject(OldMenu); + } + + return TRUE; +} +
/* FUNCTIONS *****************************************************************/
@@ -2142,6 +2231,7 @@ HMENU hMenu; MENUBARINFO kmbi; BOOL Ret; + PPOPUPMENU pPopupMenu; NTSTATUS Status = STATUS_SUCCESS; PMENU Menu = NULL; DECLARE_RETURN(BOOL); @@ -2226,7 +2316,13 @@ kmbi.hwndMenu = NULL; kmbi.fBarFocused = FALSE; kmbi.fFocused = FALSE; - //kmbi.fBarFocused = top_popup_hmenu == hMenu; + + pPopupMenu = ((PMENUWND)pWnd)->ppopupmenu; + if (pPopupMenu) + { + //kmbi.fBarFocused = pPopupMenu->spmenu == Menu; + } + if (idItem) { kmbi.fFocused = Menu->iItem == idItem-1; @@ -2238,8 +2334,8 @@ /* else { kmbi.fFocused = kmbi.fBarFocused; - } -*/ + }*/ + _SEH2_TRY { RtlCopyMemory(pmbi, &kmbi, sizeof(MENUBARINFO)); @@ -2503,6 +2599,49 @@ UserLeave(); END_CLEANUP;
+} + +/* + * @implemented + */ +BOOL APIENTRY +NtUserSetMenu( + HWND hWnd, + HMENU Menu, + BOOL Repaint) +{ + PWND Window; + BOOL Changed; + DECLARE_RETURN(BOOL); + + TRACE("Enter NtUserSetMenu\n"); + UserEnterExclusive(); + + if (!(Window = UserGetWindowObject(hWnd))) + { + RETURN( FALSE); + } + + if (! IntSetMenu(Window, Menu, &Changed)) + { + RETURN( FALSE); + } + + // Not minimized and please repaint!!! + if (!(Window->style & WS_MINIMIZE) && (Repaint || Changed)) + { + USER_REFERENCE_ENTRY Ref; + UserRefObjectCo(Window, &Ref); + co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); + UserDerefObjectCo(Window); + } + + RETURN( TRUE); + +CLEANUP: + TRACE("Leave NtUserSetMenu, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; }
/*
Modified: trunk/reactos/win32ss/user/ntuser/menu.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/menu.h?... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/menu.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/menu.h [iso-8859-1] Sat Aug 8 00:25:04 2015 @@ -9,6 +9,55 @@ #ifndef MF_END #define MF_END (0x0080) #endif + +typedef struct tagMENUSTATE +{ + PPOPUPMENU pGlobalPopupMenu; + struct + { + ULONG fMenuStarted:1; + ULONG fIsSysMenu:1; + ULONG fInsideMenuLoop:1; + ULONG fButtonDown:1; + ULONG fInEndMenu:1; + ULONG fUnderline:1; + ULONG fButtonAlwaysDown:1; + ULONG fDragging:1; + ULONG fModelessMenu:1; + ULONG fInCallHandleMenuMessages:1; + ULONG fDragAndDrop:1; + ULONG fAutoDismiss:1; + ULONG fAboutToAutoDismiss:1; + ULONG fIgnoreButtonUp:1; + ULONG fMouseOffMenu:1; + ULONG fInDoDragDrop:1; + ULONG fActiveNoForeground:1; + ULONG fNotifyByPos:1; + ULONG fSetCapture:1; + ULONG iAniDropDir:5; + }; + POINT ptMouseLast; + INT mnFocus; + INT cmdLast; + PTHREADINFO ptiMenuStateOwner; + DWORD dwLockCount; + struct tagMENUSTATE* pmnsPrev; + POINT ptButtonDown; + ULONG_PTR uButtonDownHitArea; + UINT uButtonDownIndex; + INT vkButtonDown; + ULONG_PTR uDraggingHitArea; + UINT uDraggingIndex; + UINT uDraggingFlags; + HDC hdcWndAni; + DWORD dwAniStartTime; + INT ixAni; + INT iyAni; + INT cxAni; + INT cyAni; + HBITMAP hbmAni; + HDC hdcAni; +} MENUSTATE, *PMENUSTATE;
typedef struct _SETMENUITEMRECT { @@ -51,3 +100,4 @@ BOOL FASTCALL IntRemoveMenuItem(PMENU Menu, UINT uPosition, UINT uFlags, BOOL bRecurse); PITEM FASTCALL MENU_FindItem( PMENU *pmenu, UINT *nPos, UINT wFlags ); BOOL FASTCALL IntMenuItemInfo(PMENU Menu, UINT Item, BOOL ByPosition, PROSMENUITEMINFO UnsafeItemInfo, BOOL SetOrGet, PUNICODE_STRING lpstr); +BOOL FASTCALL IntSetMenu(PWND Wnd,HMENU Menu,BOOL *Changed);
Modified: trunk/reactos/win32ss/user/ntuser/window.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/window.... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] Sat Aug 8 00:25:04 2015 @@ -792,77 +792,6 @@ pWnd->lpfnWndProc = (chWndProc ? chWndProc : NewWndProc); } return Ret; -} - -static BOOL FASTCALL -IntSetMenu( - PWND Wnd, - HMENU Menu, - BOOL *Changed) -{ - PMENU OldMenu, NewMenu = NULL; - - if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD) - { - ERR("SetMenu: Invalid handle 0x%p!\n",UserHMGetHandle(Wnd)); - EngSetLastError(ERROR_INVALID_WINDOW_HANDLE); - return FALSE; - } - - *Changed = (Wnd->IDMenu != (UINT) Menu); - if (! *Changed) - { - return TRUE; - } - - if (Wnd->IDMenu) - { - OldMenu = IntGetMenuObject((HMENU) Wnd->IDMenu); - ASSERT(NULL == OldMenu || OldMenu->hWnd == Wnd->head.h); - } - else - { - OldMenu = NULL; - } - - if (NULL != Menu) - { - NewMenu = IntGetMenuObject(Menu); - if (NULL == NewMenu) - { - if (NULL != OldMenu) - { - IntReleaseMenuObject(OldMenu); - } - EngSetLastError(ERROR_INVALID_MENU_HANDLE); - return FALSE; - } - if (NULL != NewMenu->hWnd) - { - /* Can't use the same menu for two windows */ - if (NULL != OldMenu) - { - IntReleaseMenuObject(OldMenu); - } - EngSetLastError(ERROR_INVALID_MENU_HANDLE); - return FALSE; - } - - } - - Wnd->IDMenu = (UINT) Menu; - if (NULL != NewMenu) - { - NewMenu->hWnd = Wnd->head.h; - IntReleaseMenuObject(NewMenu); - } - if (NULL != OldMenu) - { - OldMenu->hWnd = NULL; - IntReleaseMenuObject(OldMenu); - } - - return TRUE; }
@@ -3943,51 +3872,6 @@ * @implemented */ BOOL APIENTRY -NtUserSetMenu( - HWND hWnd, - HMENU Menu, - BOOL Repaint) -{ - PWND Window; - BOOL Changed; - DECLARE_RETURN(BOOL); - - TRACE("Enter NtUserSetMenu\n"); - UserEnterExclusive(); - - if (!(Window = UserGetWindowObject(hWnd))) - { - RETURN( FALSE); - } - - if (! IntSetMenu(Window, Menu, &Changed)) - { - RETURN( FALSE); - } - - if (Changed && Repaint) - { - USER_REFERENCE_ENTRY Ref; - - UserRefObjectCo(Window, &Ref); - co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | - SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); - - UserDerefObjectCo(Window); - } - - RETURN( TRUE); - -CLEANUP: - TRACE("Leave NtUserSetMenu, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - -/* - * @implemented - */ -BOOL APIENTRY NtUserSetWindowFNID(HWND hWnd, WORD fnID) {