work on system menus

svn path=/trunk/; revision=5728
This commit is contained in:
Thomas Bluemel 2003-08-21 20:29:44 +00:00
parent 60e08b722e
commit 2a0a6362e3
11 changed files with 174 additions and 59 deletions

View file

@ -11,7 +11,8 @@
#define USER32_CALLBACK_SENDWINDOWPOSCHANGED (7) #define USER32_CALLBACK_SENDWINDOWPOSCHANGED (7)
#define USER32_CALLBACK_SENDSTYLECHANGING (8) #define USER32_CALLBACK_SENDSTYLECHANGING (8)
#define USER32_CALLBACK_SENDSTYLECHANGED (9) #define USER32_CALLBACK_SENDSTYLECHANGED (9)
#define USER32_CALLBACK_MAXIMUM (9) #define USER32_CALLBACK_LOADSYSMENUTEMPLATE (10)
#define USER32_CALLBACK_MAXIMUM (10)
typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
{ {
@ -119,5 +120,7 @@ NTSTATUS STDCALL
User32SendSTYLECHANGINGMessageForKernel(PVOID Arguments, ULONG ArgumentLength); User32SendSTYLECHANGINGMessageForKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS STDCALL NTSTATUS STDCALL
User32SendSTYLECHANGEDMessageForKernel(PVOID Arguments, ULONG ArgumentLength); User32SendSTYLECHANGEDMessageForKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS STDCALL
User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength);
#endif /* __INCLUDE_USER32_CALLBACK_H */ #endif /* __INCLUDE_USER32_CALLBACK_H */

View file

@ -177,7 +177,6 @@ NtUserCallOneParam(
#define TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW 0x56 #define TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW 0x56
#define TWOPARAM_ROUTINE_VALIDATERGN 0x57 #define TWOPARAM_ROUTINE_VALIDATERGN 0x57
#define TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID 0x58 #define TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID 0x58
#define TWOPARAM_ROUTINE_SETWINSTASYSMENU 0x59
DWORD DWORD
STDCALL STDCALL
NtUserCallTwoParam( NtUserCallTwoParam(

View file

@ -111,6 +111,8 @@ Init(VOID)
(PVOID)User32SendSTYLECHANGINGMessageForKernel; (PVOID)User32SendSTYLECHANGINGMessageForKernel;
NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_SENDSTYLECHANGED] = NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_SENDSTYLECHANGED] =
(PVOID)User32SendSTYLECHANGEDMessageForKernel; (PVOID)User32SendSTYLECHANGEDMessageForKernel;
NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_LOADSYSMENUTEMPLATE] =
(PVOID)User32LoadSysMenuTemplateForKernel;
/* Allocate an index for user32 thread local data. */ /* Allocate an index for user32 thread local data. */
User32TlsIndex = TlsAlloc(); User32TlsIndex = TlsAlloc();

View file

@ -1,4 +1,4 @@
/* $Id: winsta.c,v 1.10 2003/08/21 16:04:26 weiden Exp $ /* $Id: winsta.c,v 1.11 2003/08/21 20:29:43 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
@ -67,29 +67,13 @@ CreateWindowStationW(LPWSTR lpwinsta,
ACCESS_MASK dwDesiredAccess, ACCESS_MASK dwDesiredAccess,
LPSECURITY_ATTRIBUTES lpsa) LPSECURITY_ATTRIBUTES lpsa)
{ {
HWINSTA res;
UNICODE_STRING WindowStationName; UNICODE_STRING WindowStationName;
HMENU SysMenuTemplate;
HMODULE hUser32;
RtlInitUnicodeString(&WindowStationName, lpwinsta); RtlInitUnicodeString(&WindowStationName, lpwinsta);
res = NtUserCreateWindowStation(&WindowStationName, return NtUserCreateWindowStation(&WindowStationName,
dwDesiredAccess, dwDesiredAccess,
lpsa, 0, 0, 0); lpsa, 0, 0, 0);
hUser32 = GetModuleHandleW(L"user32.dll");
SysMenuTemplate = LoadMenuW(hUser32, L"SYSMENU");
if(SysMenuTemplate)
{
NtUserCallTwoParam((DWORD)res, (DWORD)SysMenuTemplate,
TWOPARAM_ROUTINE_SETWINSTASYSMENU);
/* we don't need the menu anymore, it's been cloned */
DestroyMenu(SysMenuTemplate);
}
return res;
} }

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.26 2003/08/20 10:08:53 weiden Exp $ /* $Id: menu.c,v 1.27 2003/08/21 20:29:43 weiden Exp $
* *
* PROJECT: ReactOS user32.dll * PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/menu.c * FILE: lib/user32/windows/menu.c
@ -36,6 +36,7 @@
#include <window.h> #include <window.h>
#include <strpool.h> #include <strpool.h>
#include <user32/callback.h>
#include "user32/regcontrol.h" #include "user32/regcontrol.h"
#include "../controls/controls.h" #include "../controls/controls.h"
@ -241,6 +242,17 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
} }
NTSTATUS STDCALL
User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength)
{
LRESULT Result;
HMODULE hUser32;
hUser32 = GetModuleHandleW(L"user32.dll");
Result = (LRESULT)LoadMenuW(hUser32, L"SYSMENU");
return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
}
BOOL BOOL
MenuInit(VOID) MenuInit(VOID)
{ {
@ -811,7 +823,6 @@ InsertMenuItemW(
(MENU_ITEM_TYPE(mi.fType) == MF_STRING) && mi.dwTypeData) (MENU_ITEM_TYPE(mi.fType) == MF_STRING) && mi.dwTypeData)
{ {
len = lstrlenW(lpmii->dwTypeData); len = lstrlenW(lpmii->dwTypeData);
mi.dwTypeData = RtlAllocateHeap(hHeap, 0, (len + 1) * sizeof(WCHAR)); mi.dwTypeData = RtlAllocateHeap(hHeap, 0, (len + 1) * sizeof(WCHAR));
if(!mi.dwTypeData) if(!mi.dwTypeData)
{ {

View file

@ -41,4 +41,7 @@ IntSendSTYLECHANGINGMessage(HWND Wnd, DWORD WhichStyle, STYLESTRUCT* Style);
LRESULT STDCALL LRESULT STDCALL
IntSendSTYLECHANGEDMessage(HWND Wnd, DWORD WhichStyle, STYLESTRUCT* Style); IntSendSTYLECHANGEDMessage(HWND Wnd, DWORD WhichStyle, STYLESTRUCT* Style);
HMENU STDCALL
IntLoadSysMenuTemplate();
#endif /* __SUBSYS_WIN32K_INCLUDE_CALLBACK_H */ #endif /* __SUBSYS_WIN32K_INCLUDE_CALLBACK_H */

View file

@ -62,7 +62,7 @@ BOOL FASTCALL
IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProcess); IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProcess);
PMENU_OBJECT FASTCALL PMENU_OBJECT FASTCALL
IntCreateMenu(PHANDLE Handle, BOOL AsSysMenuTemplate); IntCreateMenu(PHANDLE Handle);
PMENU_OBJECT FASTCALL PMENU_OBJECT FASTCALL
IntCloneMenu(PMENU_OBJECT Source); IntCloneMenu(PMENU_OBJECT Source);

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: callback.c,v 1.12 2003/08/19 11:48:49 weiden Exp $ /* $Id: callback.c,v 1.13 2003/08/21 20:29:43 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -380,4 +380,26 @@ IntCallTrampolineWindowProc(WNDPROC Proc,
} }
} }
HMENU STDCALL
IntLoadSysMenuTemplate()
{
LRESULT Result;
NTSTATUS Status;
PVOID ResultPointer;
ULONG ResultLength;
ResultPointer = &Result;
ResultLength = sizeof(LRESULT);
Status = NtW32Call(USER32_CALLBACK_LOADSYSMENUTEMPLATE,
NULL,
0,
&ResultPointer,
&ResultLength);
if (!NT_SUCCESS(Status))
{
return(0);
}
return (HMENU)Result;
}
/* EOF */ /* EOF */

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.23 2003/08/21 15:26:19 weiden Exp $ /* $Id: menu.c,v 1.24 2003/08/21 20:29:43 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -225,8 +225,8 @@ IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProc
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 */
@ -249,7 +249,7 @@ IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProc
} }
PMENU_OBJECT FASTCALL PMENU_OBJECT FASTCALL
IntCreateMenu(PHANDLE Handle, BOOL AsSysMenuTemplate) IntCreateMenu(PHANDLE Handle)
{ {
PW32PROCESS Win32Process = PsGetWin32Process(); PW32PROCESS Win32Process = PsGetWin32Process();
@ -257,13 +257,6 @@ IntCreateMenu(PHANDLE Handle, BOOL AsSysMenuTemplate)
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;
@ -284,22 +277,101 @@ IntCreateMenu(PHANDLE Handle, BOOL AsSysMenuTemplate)
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;
} }
BOOL FASTCALL
IntCloneMenuItems(PMENU_OBJECT Destination, PMENU_OBJECT Source)
{
PMENU_ITEM MenuItem, NewMenuItem, Old = NULL;
DbgPrint("IntCloneMenuItems(1) = %d\n", Source->MenuItemCount);
if(!Source->MenuItemCount)
return FALSE;
DbgPrint("IntCloneMenuItems(2)\n");
ExAcquireFastMutexUnsafe(&Destination->MenuItemsLock);
ExAcquireFastMutexUnsafe(&Source->MenuItemsLock);
DbgPrint("IntCloneMenuItems(3)\n");
MenuItem = Source->MenuItemList;
while(MenuItem)
{DbgPrint("IntCloneMenuItems(%d)\n", Source->MenuItemCount + 1);
Old = NewMenuItem;
NewMenuItem = ExAllocatePool(PagedPool, sizeof(MENU_ITEM));
if(!NewMenuItem)
{
goto finish;
}
NewMenuItem->fType = MenuItem->fType;
NewMenuItem->fState = MenuItem->fState;
NewMenuItem->wID = MenuItem->wID;
NewMenuItem->hSubMenu = MenuItem->hSubMenu;
NewMenuItem->hbmpChecked = MenuItem->hbmpChecked;
NewMenuItem->hbmpUnchecked = MenuItem->hbmpUnchecked;
NewMenuItem->dwItemData = MenuItem->dwItemData;
NewMenuItem->dwTypeData = MenuItem->dwTypeData;
if((MENU_ITEM_TYPE(NewMenuItem->fType) == MF_STRING) &&
NewMenuItem->dwTypeData)
{
DbgPrint("Copy menu item %ws\n", (LPWSTR)MenuItem->dwTypeData);
NewMenuItem->dwTypeData = (LPWSTR)ExAllocatePool(PagedPool, (MenuItem->cch + 1) * sizeof(WCHAR));
if(!NewMenuItem->dwTypeData)
{
ExFreePool(NewMenuItem);
goto finish;
}
memcpy(NewMenuItem->dwTypeData, MenuItem->dwTypeData, (MenuItem->cch + 1) * sizeof(WCHAR));
}
NewMenuItem->cch = MenuItem->cch;
NewMenuItem->hbmpItem = MenuItem->hbmpItem;
Old->Next = NewMenuItem;
NewMenuItem->Next = NULL;
Source->MenuItemCount++;
MenuItem = MenuItem->Next;
}
finish:
ExReleaseFastMutexUnsafe(&Source->MenuItemsLock);
ExReleaseFastMutexUnsafe(&Destination->MenuItemsLock);
return TRUE;
}
PMENU_OBJECT FASTCALL PMENU_OBJECT FASTCALL
IntCloneMenu(PMENU_OBJECT Source) IntCloneMenu(PMENU_OBJECT Source)
{ {
DbgPrint("IntCloneMenu()\n"); HANDLE Handle;
if(!Source)
return NULL; return NULL;
PMENU_OBJECT MenuObject = (PMENU_OBJECT)ObmCreateObject(
PsGetWin32Process()->WindowStation->HandleTable, Handle,
otMenu, sizeof(MENU_OBJECT));
if(!MenuObject)
return NULL;
MenuObject->Self = Handle;
MenuObject->RtoL = Source->RtoL;
MenuObject->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */
MenuObject->MenuInfo.fMask = Source->MenuInfo.fMask;
MenuObject->MenuInfo.dwStyle = Source->MenuInfo.dwStyle;
MenuObject->MenuInfo.cyMax = Source->MenuInfo.cyMax;
MenuObject->MenuInfo.hbrBack = Source->MenuInfo.hbrBack;
MenuObject->MenuInfo.dwContextHelpID = Source->MenuInfo.dwContextHelpID;
MenuObject->MenuInfo.dwMenuData = Source->MenuInfo.dwMenuData;
MenuObject->MenuItemCount = 0;
MenuObject->MenuItemList = NULL;
ExInitializeFastMutex(&MenuObject->MenuItemsLock);
IntCloneMenuItems(MenuObject, Source);
return MenuObject;
} }
BOOL FASTCALL BOOL FASTCALL
@ -995,7 +1067,8 @@ NtUserCreateMenu(VOID)
return (HMENU)0; return (HMENU)0;
} }
IntCreateMenu(&Handle, FALSE); IntCreateMenu(&Handle);
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
return (HMENU)Handle; return (HMENU)Handle;
} }

View file

@ -1,4 +1,4 @@
/* $Id: misc.c,v 1.8 2003/08/21 16:04:26 weiden Exp $ /* $Id: misc.c,v 1.9 2003/08/21 20:29:43 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -138,12 +138,6 @@ NtUserCallTwoParam(
IntReleaseWindowObject(WindowObject); IntReleaseWindowObject(WindowObject);
return (DWORD)TRUE; return (DWORD)TRUE;
case TWOPARAM_ROUTINE_SETWINSTASYSMENU:
if(!Param1 || !Param2)
return (DWORD)FALSE;
/* FIXME clone menu and assign it to the window station */
return (DWORD)TRUE;
} }
DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam()\n Param1=0x%x Parm2=0x%x\n", DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam()\n Param1=0x%x Parm2=0x%x\n",
Routine, Param1, Param2); Routine, Param1, Param2);

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.99 2003/08/21 16:04:26 weiden Exp $ /* $Id: window.c,v 1.100 2003/08/21 20:29:44 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -306,9 +306,15 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert)
{ {
PMENU_OBJECT MenuObject, NewMenuObject; PMENU_OBJECT MenuObject, NewMenuObject;
PW32PROCESS W32Process; PW32PROCESS W32Process;
HMENU NewMenu;
if(bRevert) if(bRevert)
{ {
W32Process = PsGetWin32Process();
if(!W32Process->WindowStation)
return (HMENU)0;
if(WindowObject->SystemMenu) if(WindowObject->SystemMenu)
{ {
MenuObject = IntGetMenuObject(WindowObject->SystemMenu); MenuObject = IntGetMenuObject(WindowObject->SystemMenu);
@ -317,7 +323,7 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert)
IntDestroyMenuObject(MenuObject, FALSE, TRUE); IntDestroyMenuObject(MenuObject, FALSE, TRUE);
} }
} }
W32Process = PsGetWin32Process();
if(W32Process->WindowStation->SystemMenuTemplate) if(W32Process->WindowStation->SystemMenuTemplate)
{ {
/* clone system menu */ /* clone system menu */
@ -334,6 +340,24 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert)
} }
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
} }
else
{
NewMenu = IntLoadSysMenuTemplate();
if(!NewMenu)
return (HMENU)0;
MenuObject = IntGetMenuObject(NewMenu);
if(!MenuObject)
return (HMENU)0;
NewMenuObject = IntCloneMenu(MenuObject);
if(NewMenuObject)
{
WindowObject->SystemMenu = NewMenuObject->Self;
NewMenuObject->IsSystemMenu = TRUE;
IntReleaseMenuObject(NewMenuObject);
}
IntDestroyMenuObject(MenuObject, FALSE, TRUE);
}
return (HMENU)0; return (HMENU)0;
} }
else else