initial support for system menus

svn path=/trunk/; revision=5720
This commit is contained in:
Thomas Bluemel 2003-08-21 15:26:19 +00:00
parent 45e8d98b48
commit dad429cc35
8 changed files with 206 additions and 56 deletions

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll * PROJECT: ReactOS user32.dll
@ -210,20 +210,6 @@ GetMouseMovePointsEx(
} }
/*
* @unimplemented
*/
HMENU
STDCALL
GetSystemMenu(
HWND hWnd,
WINBOOL bRevert)
{
UNIMPLEMENTED;
return (HMENU)0;
}
/* /*
* @unimplemented * @unimplemented
*/ */
@ -989,17 +975,6 @@ SetSystemTimer(
return FALSE; return FALSE;
} }
/*
* @unimplemented
*/
WINBOOL
STDCALL
SetSystemMenu ( HWND hwnd, HMENU hMenu )
{
UNIMPLEMENTED;
return FALSE;
}
/* /*
* @unimplemented * @unimplemented
*/ */

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll * PROJECT: ReactOS user32.dll
@ -1712,4 +1712,43 @@ SetLastErrorEx(DWORD dwErrCode, DWORD dwType)
SetLastError(dwErrCode); 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 */ /* EOF */

View file

@ -97,6 +97,8 @@ ExpWinStaObjectCreate(PVOID ObjectBody,
return Status; return Status;
} }
WinSta->SystemMenuTemplate = (HANDLE)0;
DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name); DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name);
return STATUS_SUCCESS; return STATUS_SUCCESS;

View file

@ -18,6 +18,7 @@ typedef struct _WINSTATION_OBJECT
LIST_ENTRY DesktopListHead; LIST_ENTRY DesktopListHead;
PRTL_ATOM_TABLE AtomTable; PRTL_ATOM_TABLE AtomTable;
PVOID HandleTable; PVOID HandleTable;
HANDLE SystemMenuTemplate;
struct _DESKTOP_OBJECT* ActiveDesktop; struct _DESKTOP_OBJECT* ActiveDesktop;
/* FIXME: Clipboard */ /* FIXME: Clipboard */
} WINSTATION_OBJECT, *PWINSTATION_OBJECT; } WINSTATION_OBJECT, *PWINSTATION_OBJECT;

View file

@ -38,6 +38,7 @@ typedef struct _MENU_OBJECT
PMENU_ITEM MenuItemList; PMENU_ITEM MenuItemList;
MENUINFO MenuInfo; MENUINFO MenuInfo;
BOOL RtoL; BOOL RtoL;
BOOL IsSystemMenu;
} MENU_OBJECT, *PMENU_OBJECT; } MENU_OBJECT, *PMENU_OBJECT;
PMENU_OBJECT FASTCALL PMENU_OBJECT FASTCALL
@ -58,10 +59,13 @@ UINT FASTCALL
IntDeleteMenuItems(PMENU_OBJECT MenuObject, BOOL bRecurse); IntDeleteMenuItems(PMENU_OBJECT MenuObject, BOOL bRecurse);
BOOL FASTCALL BOOL FASTCALL
IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse); IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProcess);
PMENU_OBJECT FASTCALL PMENU_OBJECT FASTCALL
IntCreateMenu(PHANDLE Handle); IntCreateMenu(PHANDLE Handle, BOOL AsSysMenuTemplate);
PMENU_OBJECT FASTCALL
IntCloneMenu(PMENU_OBJECT Source);
BOOL FASTCALL BOOL FASTCALL
IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject); IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject);

View file

@ -43,6 +43,8 @@ typedef struct _WINDOW_OBJECT
HWND ParentHandle; HWND ParentHandle;
/* Window menu handle. */ /* Window menu handle. */
HMENU Menu; HMENU Menu;
/* system menu handle. */
HMENU SystemMenu;
/* Handle of the module that created the window. */ /* Handle of the module that created the window. */
HINSTANCE Instance; HINSTANCE Instance;
/* Unknown. */ /* Unknown. */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -168,7 +168,7 @@ IntFreeMenuItem(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem,
MenuItem->hSubMenu ); MenuItem->hSubMenu );
if(SubMenuObject) if(SubMenuObject)
{ {
IntDestroyMenuObject(SubMenuObject, bRecurse); IntDestroyMenuObject(SubMenuObject, bRecurse, TRUE);
} }
} }
@ -219,21 +219,25 @@ IntDeleteMenuItems(PMENU_OBJECT MenuObject, BOOL bRecurse)
} }
BOOL FASTCALL BOOL FASTCALL
IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse) IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProcess)
{ {
PW32PROCESS W32Process; PW32PROCESS W32Process;
if(MenuObject) if(MenuObject)
{ {
if(RemoveFromProcess)
W32Process = PsGetWin32Process(); W32Process = PsGetWin32Process();
/* remove all menu items */ /* remove all menu items */
ExAcquireFastMutexUnsafe (&MenuObject->MenuItemsLock); ExAcquireFastMutexUnsafe (&MenuObject->MenuItemsLock);
IntDeleteMenuItems(MenuObject, bRecurse); /* do not destroy submenus */ IntDeleteMenuItems(MenuObject, bRecurse); /* do not destroy submenus */
ExReleaseFastMutexUnsafe (&MenuObject->MenuItemsLock); ExReleaseFastMutexUnsafe (&MenuObject->MenuItemsLock);
if(RemoveFromProcess)
{
ExAcquireFastMutexUnsafe(&W32Process->MenuListLock); ExAcquireFastMutexUnsafe(&W32Process->MenuListLock);
RemoveEntryList(&MenuObject->ListEntry); RemoveEntryList(&MenuObject->ListEntry);
ExReleaseFastMutexUnsafe(&W32Process->MenuListLock); ExReleaseFastMutexUnsafe(&W32Process->MenuListLock);
}
IntReleaseMenuObject(MenuObject); // needed? IntReleaseMenuObject(MenuObject); // needed?
@ -245,7 +249,7 @@ IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse)
} }
PMENU_OBJECT FASTCALL PMENU_OBJECT FASTCALL
IntCreateMenu(PHANDLE Handle) IntCreateMenu(PHANDLE Handle, BOOL AsSysMenuTemplate)
{ {
PW32PROCESS Win32Process = PsGetWin32Process(); PW32PROCESS Win32Process = PsGetWin32Process();
@ -253,6 +257,13 @@ IntCreateMenu(PHANDLE Handle)
Win32Process->WindowStation->HandleTable, Handle, Win32Process->WindowStation->HandleTable, Handle,
otMenu, sizeof(MENU_OBJECT)); otMenu, sizeof(MENU_OBJECT));
if(AsSysMenuTemplate && !Win32Process->WindowStation->SystemMenuTemplate)
{
Win32Process->WindowStation->SystemMenuTemplate = (HANDLE)*Handle;
}
else
AsSysMenuTemplate = FALSE;
if(!MenuObject) if(!MenuObject)
{ {
*Handle = 0; *Handle = 0;
@ -273,14 +284,24 @@ IntCreateMenu(PHANDLE Handle)
MenuObject->MenuItemList = NULL; MenuObject->MenuItemList = NULL;
ExInitializeFastMutex(&MenuObject->MenuItemsLock); ExInitializeFastMutex(&MenuObject->MenuItemsLock);
if(!AsSysMenuTemplate)
{
/* Insert menu item into process menu handle list */ /* Insert menu item into process menu handle list */
ExAcquireFastMutexUnsafe (&Win32Process->MenuListLock); ExAcquireFastMutexUnsafe (&Win32Process->MenuListLock);
InsertTailList (&Win32Process->MenuListHead, &MenuObject->ListEntry); InsertTailList (&Win32Process->MenuListHead, &MenuObject->ListEntry);
ExReleaseFastMutexUnsafe (&Win32Process->MenuListLock); ExReleaseFastMutexUnsafe (&Win32Process->MenuListLock);
}
return MenuObject; return MenuObject;
} }
PMENU_OBJECT FASTCALL
IntCloneMenu(PMENU_OBJECT Source)
{
DbgPrint("IntCloneMenu()\n");
return NULL;
}
BOOL FASTCALL BOOL FASTCALL
IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject) IntSetMenuFlagRtoL(PMENU_OBJECT MenuObject)
{ {
@ -874,7 +895,7 @@ IntCleanupMenus(struct _EPROCESS *Process, PW32PROCESS Win32Process)
MenuObject = CONTAINING_RECORD(Win32Process->MenuListHead.Flink, MENU_OBJECT, ListEntry); MenuObject = CONTAINING_RECORD(Win32Process->MenuListHead.Flink, MENU_OBJECT, ListEntry);
ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock); ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock);
IntDestroyMenuObject(MenuObject, FALSE); IntDestroyMenuObject(MenuObject, FALSE, TRUE);
ExAcquireFastMutexUnsafe(&Win32Process->MenuListLock); ExAcquireFastMutexUnsafe(&Win32Process->MenuListLock);
} }
ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock); ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock);
@ -974,7 +995,7 @@ NtUserCreateMenu(VOID)
return (HMENU)0; return (HMENU)0;
} }
IntCreateMenu(&Handle); IntCreateMenu(&Handle, FALSE);
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
return (HMENU)Handle; return (HMENU)Handle;
} }
@ -1020,7 +1041,7 @@ NtUserDestroyMenu(
return FALSE; return FALSE;
} }
return IntDestroyMenuObject(MenuObject, FALSE); return IntDestroyMenuObject(MenuObject, FALSE, TRUE);
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -301,6 +301,71 @@ IntReleaseWindowObject(PWINDOW_OBJECT Window)
ObmDereferenceObject(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. * Internal function.
* Returns client window rectangle relative to the upper-left corner of client area. * Returns client window rectangle relative to the upper-left corner of client area.
@ -596,6 +661,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
PWNDCLASS_OBJECT ClassObject; PWNDCLASS_OBJECT ClassObject;
PWINDOW_OBJECT WindowObject; PWINDOW_OBJECT WindowObject;
PWINDOW_OBJECT ParentWindow; PWINDOW_OBJECT ParentWindow;
PMENU_OBJECT SystemMenu;
UNICODE_STRING WindowName; UNICODE_STRING WindowName;
NTSTATUS Status; NTSTATUS Status;
HANDLE Handle; HANDLE Handle;
@ -679,6 +745,8 @@ NtUserCreateWindowEx(DWORD dwExStyle,
WindowObject->Style = dwStyle & ~WS_VISIBLE; WindowObject->Style = dwStyle & ~WS_VISIBLE;
DbgPrint("1: Style is now %d\n", WindowObject->Style); DbgPrint("1: Style is now %d\n", WindowObject->Style);
SystemMenu = IntGetSystemMenu(WindowObject, TRUE);
WindowObject->x = x; WindowObject->x = x;
WindowObject->y = y; WindowObject->y = y;
WindowObject->Width = nWidth; WindowObject->Width = nWidth;
@ -686,6 +754,10 @@ NtUserCreateWindowEx(DWORD dwExStyle,
WindowObject->ContextHelpId = 0; WindowObject->ContextHelpId = 0;
WindowObject->ParentHandle = hWndParent; WindowObject->ParentHandle = hWndParent;
WindowObject->Menu = hMenu; WindowObject->Menu = hMenu;
if(SystemMenu)
WindowObject->SystemMenu = SystemMenu->Self;
else
WindowObject->SystemMenu = (HMENU)0;
WindowObject->Instance = hInstance; WindowObject->Instance = hInstance;
WindowObject->Parameters = lpParam; WindowObject->Parameters = lpParam;
WindowObject->Self = Handle; WindowObject->Self = Handle;
@ -2577,7 +2649,7 @@ NtUserSetMenu(
/* /*
* @unimplemented * @implemented
*/ */
HMENU HMENU
STDCALL STDCALL
@ -2585,14 +2657,23 @@ NtUserGetSystemMenu(
HWND hWnd, HWND hWnd,
BOOL bRevert) BOOL bRevert)
{ {
UNIMPLEMENTED HMENU res = (HMENU)0;
PWINDOW_OBJECT WindowObject;
return 0; 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 BOOL
STDCALL STDCALL
@ -2600,9 +2681,34 @@ NtUserSetSystemMenu(
HWND hWnd, HWND hWnd,
HMENU hMenu) HMENU hMenu)
{ {
UNIMPLEMENTED BOOL res = FALSE;
PWINDOW_OBJECT WindowObject;
PMENU_OBJECT MenuObject;
WindowObject = IntGetWindowObject((HWND)hWnd);
if(!WindowObject)
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE;
}
return 0; 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;
} }