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_SENDSTYLECHANGING (8)
#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
{
@ -119,5 +120,7 @@ NTSTATUS STDCALL
User32SendSTYLECHANGINGMessageForKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS STDCALL
User32SendSTYLECHANGEDMessageForKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS STDCALL
User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength);
#endif /* __INCLUDE_USER32_CALLBACK_H */

View file

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

View file

@ -111,6 +111,8 @@ Init(VOID)
(PVOID)User32SendSTYLECHANGINGMessageForKernel;
NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_SENDSTYLECHANGED] =
(PVOID)User32SendSTYLECHANGEDMessageForKernel;
NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_LOADSYSMENUTEMPLATE] =
(PVOID)User32LoadSysMenuTemplateForKernel;
/* Allocate an index for user32 thread local data. */
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
* PROJECT: ReactOS user32.dll
@ -67,29 +67,13 @@ CreateWindowStationW(LPWSTR lpwinsta,
ACCESS_MASK dwDesiredAccess,
LPSECURITY_ATTRIBUTES lpsa)
{
HWINSTA res;
UNICODE_STRING WindowStationName;
HMENU SysMenuTemplate;
HMODULE hUser32;
RtlInitUnicodeString(&WindowStationName, lpwinsta);
res = NtUserCreateWindowStation(&WindowStationName,
return NtUserCreateWindowStation(&WindowStationName,
dwDesiredAccess,
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
* 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
* FILE: lib/user32/windows/menu.c
@ -36,6 +36,7 @@
#include <window.h>
#include <strpool.h>
#include <user32/callback.h>
#include "user32/regcontrol.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
MenuInit(VOID)
{
@ -811,7 +823,6 @@ InsertMenuItemW(
(MENU_ITEM_TYPE(mi.fType) == MF_STRING) && mi.dwTypeData)
{
len = lstrlenW(lpmii->dwTypeData);
mi.dwTypeData = RtlAllocateHeap(hHeap, 0, (len + 1) * sizeof(WCHAR));
if(!mi.dwTypeData)
{

View file

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

View file

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

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

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.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
* PROJECT: ReactOS kernel
@ -225,8 +225,8 @@ IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProc
if(MenuObject)
{
if(RemoveFromProcess)
W32Process = PsGetWin32Process();
W32Process = PsGetWin32Process();
/* remove all menu items */
ExAcquireFastMutexUnsafe (&MenuObject->MenuItemsLock);
IntDeleteMenuItems(MenuObject, bRecurse); /* do not destroy submenus */
@ -249,21 +249,14 @@ IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProc
}
PMENU_OBJECT FASTCALL
IntCreateMenu(PHANDLE Handle, BOOL AsSysMenuTemplate)
IntCreateMenu(PHANDLE Handle)
{
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)
{
*Handle = 0;
@ -283,23 +276,102 @@ IntCreateMenu(PHANDLE Handle, BOOL AsSysMenuTemplate)
MenuObject->MenuItemCount = 0;
MenuObject->MenuItemList = NULL;
ExInitializeFastMutex(&MenuObject->MenuItemsLock);
if(!AsSysMenuTemplate)
{
/* Insert menu item into process menu handle list */
ExAcquireFastMutexUnsafe (&Win32Process->MenuListLock);
InsertTailList (&Win32Process->MenuListHead, &MenuObject->ListEntry);
ExReleaseFastMutexUnsafe (&Win32Process->MenuListLock);
/* Insert menu item into process menu handle list */
ExAcquireFastMutexUnsafe (&Win32Process->MenuListLock);
InsertTailList (&Win32Process->MenuListHead, &MenuObject->ListEntry);
ExReleaseFastMutexUnsafe (&Win32Process->MenuListLock);
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;
}
return MenuObject;
finish:
ExReleaseFastMutexUnsafe(&Source->MenuItemsLock);
ExReleaseFastMutexUnsafe(&Destination->MenuItemsLock);
return TRUE;
}
PMENU_OBJECT FASTCALL
IntCloneMenu(PMENU_OBJECT Source)
{
DbgPrint("IntCloneMenu()\n");
return NULL;
HANDLE Handle;
if(!Source)
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
@ -981,12 +1053,12 @@ NtUserCreateMenu(VOID)
{
PWINSTATION_OBJECT WinStaObject;
HANDLE Handle;
NTSTATUS Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
KernelMode,
0,
&WinStaObject);
if (!NT_SUCCESS(Status))
{
DPRINT("Validation of window station handle (0x%X) failed\n",
@ -995,7 +1067,8 @@ NtUserCreateMenu(VOID)
return (HMENU)0;
}
IntCreateMenu(&Handle, FALSE);
IntCreateMenu(&Handle);
ObDereferenceObject(WinStaObject);
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
* PROJECT: ReactOS kernel
@ -137,12 +137,6 @@ NtUserCallTwoParam(
IntReleaseWindowObject(WindowObject);
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",

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.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
* PROJECT: ReactOS kernel
@ -306,9 +306,15 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert)
{
PMENU_OBJECT MenuObject, NewMenuObject;
PW32PROCESS W32Process;
HMENU NewMenu;
if(bRevert)
{
W32Process = PsGetWin32Process();
if(!W32Process->WindowStation)
return (HMENU)0;
if(WindowObject->SystemMenu)
{
MenuObject = IntGetMenuObject(WindowObject->SystemMenu);
@ -317,7 +323,7 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert)
IntDestroyMenuObject(MenuObject, FALSE, TRUE);
}
}
W32Process = PsGetWin32Process();
if(W32Process->WindowStation->SystemMenuTemplate)
{
/* clone system menu */
@ -334,6 +340,24 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert)
}
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;
}
else