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
* 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
*/

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
* 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 */

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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. */

View file

@ -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);
}

View file

@ -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;
}