diff --git a/reactos/lib/user32/misc/stubs.c b/reactos/lib/user32/misc/stubs.c index 72e17874417..b88d072e714 100644 --- a/reactos/lib/user32/misc/stubs.c +++ b/reactos/lib/user32/misc/stubs.c @@ -1,4 +1,4 @@ -/* $Id: stubs.c,v 1.34 2003/08/20 03:07:33 silverblade Exp $ +/* $Id: stubs.c,v 1.35 2003/08/21 15:26:18 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -210,20 +210,6 @@ GetMouseMovePointsEx( } -/* - * @unimplemented - */ -HMENU -STDCALL -GetSystemMenu( - HWND hWnd, - WINBOOL bRevert) -{ - UNIMPLEMENTED; - return (HMENU)0; -} - - /* * @unimplemented */ @@ -989,17 +975,6 @@ SetSystemTimer( return FALSE; } -/* - * @unimplemented - */ -WINBOOL -STDCALL -SetSystemMenu ( HWND hwnd, HMENU hMenu ) -{ - UNIMPLEMENTED; - return FALSE; -} - /* * @unimplemented */ diff --git a/reactos/lib/user32/windows/window.c b/reactos/lib/user32/windows/window.c index 5053c94c316..90f1631268b 100644 --- a/reactos/lib/user32/windows/window.c +++ b/reactos/lib/user32/windows/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.69 2003/08/20 03:07:33 silverblade Exp $ +/* $Id: window.c,v 1.70 2003/08/21 15:26:19 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -1712,4 +1712,43 @@ SetLastErrorEx(DWORD dwErrCode, DWORD dwType) SetLastError(dwErrCode); } +/* + * @implemented + */ +WINBOOL +STDCALL +SetSystemMenu ( + HWND hwnd, + HMENU hMenu) +{ + if(!hwnd) + { + SetLastError(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + if(!hMenu) + { + SetLastError(ERROR_INVALID_MENU_HANDLE); + return FALSE; + } + return NtUserSetSystemMenu(hwnd, hMenu); +} + +/* + * @implemented + */ +HMENU +STDCALL +GetSystemMenu( + HWND hWnd, + WINBOOL bRevert) +{ + if(!hWnd) + { + SetLastError(ERROR_INVALID_WINDOW_HANDLE); + return (HMENU)0; + } + return NtUserGetSystemMenu(hWnd, bRevert); +} + /* EOF */ diff --git a/reactos/ntoskrnl/ex/win32k.c b/reactos/ntoskrnl/ex/win32k.c index f8bbc2874d2..0bfbbb9574d 100644 --- a/reactos/ntoskrnl/ex/win32k.c +++ b/reactos/ntoskrnl/ex/win32k.c @@ -97,6 +97,8 @@ ExpWinStaObjectCreate(PVOID ObjectBody, return Status; } + WinSta->SystemMenuTemplate = (HANDLE)0; + DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name); return STATUS_SUCCESS; diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 6fa9a49beb8..cd29ca83187 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -18,6 +18,7 @@ typedef struct _WINSTATION_OBJECT LIST_ENTRY DesktopListHead; PRTL_ATOM_TABLE AtomTable; PVOID HandleTable; + HANDLE SystemMenuTemplate; struct _DESKTOP_OBJECT* ActiveDesktop; /* FIXME: Clipboard */ } WINSTATION_OBJECT, *PWINSTATION_OBJECT; diff --git a/reactos/subsys/win32k/include/menu.h b/reactos/subsys/win32k/include/menu.h index bf78f58dd06..250bf8a6c6b 100644 --- a/reactos/subsys/win32k/include/menu.h +++ b/reactos/subsys/win32k/include/menu.h @@ -38,6 +38,7 @@ typedef struct _MENU_OBJECT PMENU_ITEM MenuItemList; MENUINFO MenuInfo; BOOL RtoL; + BOOL IsSystemMenu; } MENU_OBJECT, *PMENU_OBJECT; PMENU_OBJECT FASTCALL @@ -58,10 +59,13 @@ UINT FASTCALL IntDeleteMenuItems(PMENU_OBJECT MenuObject, BOOL bRecurse); BOOL FASTCALL -IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse); +IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProcess); PMENU_OBJECT FASTCALL -IntCreateMenu(PHANDLE Handle); +IntCreateMenu(PHANDLE Handle, BOOL AsSysMenuTemplate); + +PMENU_OBJECT FASTCALL +IntCloneMenu(PMENU_OBJECT Source); BOOL FASTCALL IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject); diff --git a/reactos/subsys/win32k/include/window.h b/reactos/subsys/win32k/include/window.h index 7568afee4c7..e1f89eadf2b 100644 --- a/reactos/subsys/win32k/include/window.h +++ b/reactos/subsys/win32k/include/window.h @@ -43,6 +43,8 @@ typedef struct _WINDOW_OBJECT HWND ParentHandle; /* Window menu handle. */ HMENU Menu; + /* system menu handle. */ + HMENU SystemMenu; /* Handle of the module that created the window. */ HINSTANCE Instance; /* Unknown. */ diff --git a/reactos/subsys/win32k/ntuser/menu.c b/reactos/subsys/win32k/ntuser/menu.c index b66d30429f5..b807eb4e513 100644 --- a/reactos/subsys/win32k/ntuser/menu.c +++ b/reactos/subsys/win32k/ntuser/menu.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: menu.c,v 1.22 2003/08/20 18:55:03 chorns Exp $ +/* $Id: menu.c,v 1.23 2003/08/21 15:26:19 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -168,7 +168,7 @@ IntFreeMenuItem(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, MenuItem->hSubMenu ); if(SubMenuObject) { - IntDestroyMenuObject(SubMenuObject, bRecurse); + IntDestroyMenuObject(SubMenuObject, bRecurse, TRUE); } } @@ -219,21 +219,25 @@ IntDeleteMenuItems(PMENU_OBJECT MenuObject, BOOL bRecurse) } BOOL FASTCALL -IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse) +IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProcess) { PW32PROCESS W32Process; if(MenuObject) - { - W32Process = PsGetWin32Process(); + { + if(RemoveFromProcess) + W32Process = PsGetWin32Process(); /* remove all menu items */ ExAcquireFastMutexUnsafe (&MenuObject->MenuItemsLock); IntDeleteMenuItems(MenuObject, bRecurse); /* do not destroy submenus */ ExReleaseFastMutexUnsafe (&MenuObject->MenuItemsLock); - ExAcquireFastMutexUnsafe(&W32Process->MenuListLock); - RemoveEntryList(&MenuObject->ListEntry); - ExReleaseFastMutexUnsafe(&W32Process->MenuListLock); + if(RemoveFromProcess) + { + ExAcquireFastMutexUnsafe(&W32Process->MenuListLock); + RemoveEntryList(&MenuObject->ListEntry); + ExReleaseFastMutexUnsafe(&W32Process->MenuListLock); + } IntReleaseMenuObject(MenuObject); // needed? @@ -245,13 +249,20 @@ IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse) } PMENU_OBJECT FASTCALL -IntCreateMenu(PHANDLE Handle) +IntCreateMenu(PHANDLE Handle, BOOL AsSysMenuTemplate) { PW32PROCESS Win32Process = PsGetWin32Process(); PMENU_OBJECT MenuObject = (PMENU_OBJECT)ObmCreateObject( Win32Process->WindowStation->HandleTable, Handle, otMenu, sizeof(MENU_OBJECT)); + + if(AsSysMenuTemplate && !Win32Process->WindowStation->SystemMenuTemplate) + { + Win32Process->WindowStation->SystemMenuTemplate = (HANDLE)*Handle; + } + else + AsSysMenuTemplate = FALSE; if(!MenuObject) { @@ -273,14 +284,24 @@ IntCreateMenu(PHANDLE Handle) MenuObject->MenuItemList = NULL; ExInitializeFastMutex(&MenuObject->MenuItemsLock); - /* Insert menu item into process menu handle list */ - ExAcquireFastMutexUnsafe (&Win32Process->MenuListLock); - InsertTailList (&Win32Process->MenuListHead, &MenuObject->ListEntry); - ExReleaseFastMutexUnsafe (&Win32Process->MenuListLock); + if(!AsSysMenuTemplate) + { + /* Insert menu item into process menu handle list */ + ExAcquireFastMutexUnsafe (&Win32Process->MenuListLock); + InsertTailList (&Win32Process->MenuListHead, &MenuObject->ListEntry); + ExReleaseFastMutexUnsafe (&Win32Process->MenuListLock); + } return MenuObject; } +PMENU_OBJECT FASTCALL +IntCloneMenu(PMENU_OBJECT Source) +{ + DbgPrint("IntCloneMenu()\n"); + return NULL; +} + BOOL FASTCALL IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject) { @@ -874,7 +895,7 @@ IntCleanupMenus(struct _EPROCESS *Process, PW32PROCESS Win32Process) MenuObject = CONTAINING_RECORD(Win32Process->MenuListHead.Flink, MENU_OBJECT, ListEntry); ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock); - IntDestroyMenuObject(MenuObject, FALSE); + IntDestroyMenuObject(MenuObject, FALSE, TRUE); ExAcquireFastMutexUnsafe(&Win32Process->MenuListLock); } ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock); @@ -974,7 +995,7 @@ NtUserCreateMenu(VOID) return (HMENU)0; } - IntCreateMenu(&Handle); + IntCreateMenu(&Handle, FALSE); ObDereferenceObject(WinStaObject); return (HMENU)Handle; } @@ -1020,7 +1041,7 @@ NtUserDestroyMenu( return FALSE; } - return IntDestroyMenuObject(MenuObject, FALSE); + return IntDestroyMenuObject(MenuObject, FALSE, TRUE); } diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 83e12f62c6b..23103bd49dd 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: window.c,v 1.97 2003/08/19 11:48:50 weiden Exp $ +/* $Id: window.c,v 1.98 2003/08/21 15:26:19 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -301,6 +301,71 @@ IntReleaseWindowObject(PWINDOW_OBJECT Window) ObmDereferenceObject(Window); } +HMENU FASTCALL +IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert) +{ + PMENU_OBJECT MenuObject; + PW32PROCESS W32Process; + + if(bRevert) + { + if(WindowObject->SystemMenu) + { + MenuObject = IntGetMenuObject(WindowObject->SystemMenu); + if(MenuObject) + { + IntDestroyMenuObject(MenuObject, FALSE, TRUE); + } + } + W32Process = PsGetWin32Process(); + if(W32Process->WindowStation->SystemMenuTemplate) + { + /* clone system menu */ + MenuObject = IntGetMenuObject(W32Process->WindowStation->SystemMenuTemplate); + if(!MenuObject) + return (HMENU)0; + + MenuObject = IntCloneMenu(MenuObject); + if(MenuObject) + { + WindowObject->SystemMenu = MenuObject->Self; + MenuObject->IsSystemMenu = TRUE; + } + } + /* FIXME Load system menu here? + else + { + + }*/ + return (HMENU)0; + } + else + { + return WindowObject->SystemMenu; + } +} + +BOOL FASTCALL +IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject) +{ + PMENU_OBJECT OldMenuObject; + if(WindowObject->SystemMenu) + { + OldMenuObject = IntGetMenuObject(WindowObject->SystemMenu); + if(OldMenuObject) + { + OldMenuObject->IsSystemMenu = FALSE; + IntReleaseMenuObject(OldMenuObject); + } + } + + WindowObject->SystemMenu = MenuObject->Self; + if(MenuObject) /* FIXME check window style, propably return FALSE ? */ + MenuObject->IsSystemMenu = TRUE; + + return TRUE; +} + /*! * Internal function. * Returns client window rectangle relative to the upper-left corner of client area. @@ -596,6 +661,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, PWNDCLASS_OBJECT ClassObject; PWINDOW_OBJECT WindowObject; PWINDOW_OBJECT ParentWindow; + PMENU_OBJECT SystemMenu; UNICODE_STRING WindowName; NTSTATUS Status; HANDLE Handle; @@ -679,6 +745,8 @@ NtUserCreateWindowEx(DWORD dwExStyle, WindowObject->Style = dwStyle & ~WS_VISIBLE; DbgPrint("1: Style is now %d\n", WindowObject->Style); + SystemMenu = IntGetSystemMenu(WindowObject, TRUE); + WindowObject->x = x; WindowObject->y = y; WindowObject->Width = nWidth; @@ -686,6 +754,10 @@ NtUserCreateWindowEx(DWORD dwExStyle, WindowObject->ContextHelpId = 0; WindowObject->ParentHandle = hWndParent; WindowObject->Menu = hMenu; + if(SystemMenu) + WindowObject->SystemMenu = SystemMenu->Self; + else + WindowObject->SystemMenu = (HMENU)0; WindowObject->Instance = hInstance; WindowObject->Parameters = lpParam; WindowObject->Self = Handle; @@ -848,7 +920,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n"); return((HWND)0); } - + /* Send move and size messages. */ if (!(WindowObject->Flags & WINDOWOBJECT_NEED_SIZE)) { @@ -2577,7 +2649,7 @@ NtUserSetMenu( /* - * @unimplemented + * @implemented */ HMENU STDCALL @@ -2585,14 +2657,23 @@ NtUserGetSystemMenu( HWND hWnd, BOOL bRevert) { - UNIMPLEMENTED - - return 0; + HMENU res = (HMENU)0; + PWINDOW_OBJECT WindowObject; + WindowObject = IntGetWindowObject((HWND)hWnd); + if(!WindowObject) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return (HMENU)0; + } + + res = IntGetSystemMenu(WindowObject, bRevert); + + IntReleaseWindowObject(WindowObject); + return res; } - /* - * @unimplemented + * @implemented */ BOOL STDCALL @@ -2600,9 +2681,34 @@ NtUserSetSystemMenu( HWND hWnd, HMENU hMenu) { - UNIMPLEMENTED - - return 0; + BOOL res = FALSE; + PWINDOW_OBJECT WindowObject; + PMENU_OBJECT MenuObject; + WindowObject = IntGetWindowObject((HWND)hWnd); + if(!WindowObject) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + + if(hMenu) + { + /* assign new menu handle */ + MenuObject = IntGetMenuObject(hMenu); + if(!MenuObject) + { + IntReleaseWindowObject(WindowObject); + SetLastWin32Error(ERROR_INVALID_MENU_HANDLE); + return FALSE; + } + + res = IntSetSystemMenu(WindowObject, MenuObject); + + IntReleaseMenuObject(MenuObject); + } + + IntReleaseWindowObject(WindowObject); + return res; }