fixed destroying child windows and some fixes on menus

svn path=/trunk/; revision=7099
This commit is contained in:
Thomas Bluemel
2003-12-17 19:56:13 +00:00
parent 7127873aac
commit 48cbf21922
4 changed files with 149 additions and 114 deletions
+1
View File
@@ -32,6 +32,7 @@ typedef struct _MENU_ITEM
typedef struct _MENU_OBJECT
{
HANDLE Self;
PW32PROCESS W32Process;
LIST_ENTRY ListEntry;
int MenuItemCount;
FAST_MUTEX MenuItemsLock;
+3 -3
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: object.c,v 1.7 2003/12/12 14:22:37 gvg Exp $
/* $Id: object.c,v 1.8 2003/12/17 19:56:13 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -113,7 +113,7 @@ ObmpGetObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
Current = Current->Flink;
if (Current == &(HandleTable->ListHead))
{
DPRINT1("Invalid handle\n");
DPRINT1("Invalid handle 0x%x\n", Handle);
return NULL;
}
}
@@ -479,7 +479,7 @@ ObmReferenceObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
if ((ObjectType != otUnknown) && (ObjectHeader->Type != ObjectType))
{
DPRINT1("Object type mismatch\n");
DPRINT1("Object type mismatch 0x%x 0x%x\n", ObjectType, ObjectHeader->Type);
return STATUS_UNSUCCESSFUL;
}
+33 -21
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.33 2003/11/23 12:31:53 weiden Exp $
/* $Id: menu.c,v 1.34 2003/12/17 19:56:13 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -162,11 +162,11 @@ IntFreeMenuItem(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem,
if(bRecurse && MenuItem->hSubMenu)
{
PMENU_OBJECT SubMenuObject;
SubMenuObject = (PMENU_OBJECT)IntGetWindowObject(
MenuItem->hSubMenu );
SubMenuObject = IntGetMenuObject(MenuItem->hSubMenu );
if(SubMenuObject)
{
IntDestroyMenuObject(SubMenuObject, bRecurse, TRUE);
IntReleaseMenuObject(SubMenuObject);
}
}
@@ -217,14 +217,11 @@ IntDeleteMenuItems(PMENU_OBJECT MenuObject, BOOL bRecurse)
}
BOOL FASTCALL
IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProcess)
IntDestroyMenuObject(PMENU_OBJECT MenuObject,
BOOL bRecurse, BOOL RemoveFromProcess)
{
PW32PROCESS W32Process;
if(MenuObject)
{
W32Process = PsGetWin32Process();
/* remove all menu items */
ExAcquireFastMutexUnsafe (&MenuObject->MenuItemsLock);
IntDeleteMenuItems(MenuObject, bRecurse); /* do not destroy submenus */
@@ -232,14 +229,12 @@ IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProc
if(RemoveFromProcess)
{
ExAcquireFastMutexUnsafe(&W32Process->MenuListLock);
ExAcquireFastMutexUnsafe(&MenuObject->W32Process->MenuListLock);
RemoveEntryList(&MenuObject->ListEntry);
ExReleaseFastMutexUnsafe(&W32Process->MenuListLock);
ExReleaseFastMutexUnsafe(&MenuObject->W32Process->MenuListLock);
}
IntReleaseMenuObject(MenuObject); // needed?
ObmCloseHandle(W32Process->WindowStation->HandleTable, MenuObject->Self);
ObmCloseHandle(MenuObject->W32Process->WindowStation->HandleTable, MenuObject->Self);
return TRUE;
}
@@ -261,8 +256,9 @@ IntCreateMenu(PHANDLE Handle)
*Handle = 0;
return NULL;
}
MenuObject->Self = *Handle;
MenuObject->W32Process = Win32Process;
MenuObject->RtoL = FALSE; /* default */
MenuObject->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */
MenuObject->MenuInfo.fMask = 0; /* not used */
@@ -277,9 +273,9 @@ IntCreateMenu(PHANDLE Handle)
ExInitializeFastMutex(&MenuObject->MenuItemsLock);
/* Insert menu item into process menu handle list */
ExAcquireFastMutexUnsafe (&Win32Process->MenuListLock);
InsertTailList (&Win32Process->MenuListHead, &MenuObject->ListEntry);
ExReleaseFastMutexUnsafe (&Win32Process->MenuListLock);
ExAcquireFastMutexUnsafe(&Win32Process->MenuListLock);
InsertTailList(&Win32Process->MenuListHead, &MenuObject->ListEntry);
ExReleaseFastMutexUnsafe(&Win32Process->MenuListLock);
return MenuObject;
}
@@ -356,17 +352,19 @@ IntCloneMenu(PMENU_OBJECT Source)
{
HANDLE Handle;
PMENU_OBJECT MenuObject;
PW32PROCESS Process = PsGetWin32Process();
if(!Source)
return NULL;
MenuObject = (PMENU_OBJECT)ObmCreateObject(
PsGetWin32Process()->WindowStation->HandleTable, Handle,
Process->WindowStation->HandleTable, &Handle,
otMenu, sizeof(MENU_OBJECT));
if(!MenuObject)
return NULL;
MenuObject->Self = Handle;
MenuObject->W32Process = Process;
MenuObject->RtoL = Source->RtoL;
MenuObject->MenuInfo.cbSize = sizeof(MENUINFO); /* not used */
MenuObject->MenuInfo.fMask = Source->MenuInfo.fMask;
@@ -379,6 +377,11 @@ IntCloneMenu(PMENU_OBJECT Source)
MenuObject->MenuItemCount = 0;
MenuObject->MenuItemList = NULL;
ExInitializeFastMutex(&MenuObject->MenuItemsLock);
/* Insert menu item into process menu handle list */
ExAcquireFastMutexUnsafe(&Process->MenuListLock);
InsertTailList(&Process->MenuListHead, &MenuObject->ListEntry);
ExReleaseFastMutexUnsafe(&Process->MenuListLock);
IntCloneMenuItems(MenuObject, Source);
@@ -1033,7 +1036,7 @@ IntCleanupMenus(struct _EPROCESS *Process, PW32PROCESS Win32Process)
PEPROCESS CurrentProcess;
PLIST_ENTRY LastHead = NULL;
PMENU_OBJECT MenuObject;
CurrentProcess = PsGetCurrentProcess();
if (CurrentProcess != Process)
{
@@ -1183,7 +1186,7 @@ BOOL STDCALL
NtUserDestroyMenu(
HMENU hMenu)
{
/* FIXME, check if menu belongs to the process */
BOOL Ret;
PMENU_OBJECT MenuObject = IntGetMenuObject(hMenu);
if(!MenuObject)
@@ -1191,8 +1194,17 @@ NtUserDestroyMenu(
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
return FALSE;
}
if(MenuObject->W32Process != PsGetWin32Process())
{
IntReleaseMenuObject(MenuObject);
SetLastWin32Error(ERROR_ACCESS_DENIED);
return FALSE;
}
return IntDestroyMenuObject(MenuObject, FALSE, TRUE);
Ret = IntDestroyMenuObject(MenuObject, FALSE, TRUE);
IntReleaseMenuObject(MenuObject);
return Ret;
}
+112 -90
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.165 2003/12/17 13:11:55 weiden Exp $
/* $Id: window.c,v 1.166 2003/12/17 19:56:13 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -245,6 +245,56 @@ IntWinListChildren(PWINDOW_OBJECT Window)
return (NumChildren > 0) ? List : NULL;
}
/***********************************************************************
* IntSendDestroyMsg
*/
static void IntSendDestroyMsg(HWND Wnd)
{
#if 0 /* FIXME */
GUITHREADINFO info;
if (GetGUIThreadInfo(GetCurrentThreadId(), &info))
{
if (Wnd == info.hwndCaret)
{
DestroyCaret();
}
}
#endif
/*
* Send the WM_DESTROY to the window.
*/
IntSendMessage(Wnd, WM_DESTROY, 0, 0, TRUE);
/*
* This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
* make sure that the window still exists when we come back.
*/
#if 0 /* FIXME */
if (IsWindow(Wnd))
{
HWND* pWndArray;
int i;
if (!(pWndArray = WIN_ListChildren( hwnd ))) return;
/* start from the end (FIXME: is this needed?) */
for (i = 0; pWndArray[i]; i++) ;
while (--i >= 0)
{
if (IsWindow( pWndArray[i] )) WIN_SendDestroyMsg( pWndArray[i] );
}
HeapFree(GetProcessHeap(), 0, pWndArray);
}
else
{
DPRINT("destroyed itself while in WM_DESTROY!\n");
}
#endif
}
/***********************************************************************
* IntDestroyWindow
*
@@ -258,12 +308,18 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
HWND *Children;
HWND *ChildHandle;
PWINDOW_OBJECT Child;
PMENU_OBJECT Menu;
if (! IntWndBelongsToThread(Window, ThreadData))
{
DPRINT1("Window doesn't belong to current thread\n");
return 0;
}
if(SendMessages)
{
/* Send destroy messages */
IntSendDestroyMsg(Window->Self);
}
/* free child windows */
Children = IntWinListChildren(Window);
@@ -274,10 +330,15 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
Child = IntGetProcessWindowObject(ProcessData, *ChildHandle);
if (NULL != Child)
{
if (IntWndBelongsToThread(Child, ThreadData))
IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
if(IntWndBelongsToThread(Child, ThreadData))
{
IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
}
else
IntSendMessage(Child->Self, WM_DESTROY, 0, 0, TRUE);
{
IntSendDestroyMsg(Child->Self);
IntDestroyWindow(Child, ProcessData, Child->OwnerThread->Win32Thread, FALSE);
}
IntReleaseWindowObject(Child);
}
}
@@ -285,7 +346,7 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
}
if (SendMessages)
{
{
/*
* Clear the update region to make sure no WM_PAINT messages will be
* generated for this window while processing the WM_NCDESTROY.
@@ -325,22 +386,23 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
/* free resources associated with the window */
TIMER_RemoveWindowTimers(Window->Self);
#endif
#if 0 /* FIXME */
if (0 == (Window->Style & WS_CHILD))
if (!(Window->Style & WS_CHILD) && Window->IDMenu
&& (Menu = IntGetMenuObject((HMENU)Window->IDMenu)))
{
HMENU Menu = (HMENU) NtUserSetWindowLongW(Window->Self, GWL_ID, 0);
if (NULL != Menu)
{
DestroyMenu(Menu);
}
IntDestroyMenuObject(Menu, TRUE, TRUE);
Window->IDMenu = 0;
IntReleaseMenuObject(Menu);
}
if (Window->hSysMenu)
{
DestroyMenu(Window->hSysMenu);
Window->hSysMenu = 0;
}
#endif
if(Window->SystemMenu
&& (Menu = IntGetMenuObject(Window->SystemMenu)))
{
IntDestroyMenuObject(Menu, TRUE, TRUE);
Window->SystemMenu = (HMENU)0;
IntReleaseMenuObject(Menu);
}
DceFreeWindowDCE(Window); /* Always do this to catch orphaned DCs */
#if 0 /* FIXME */
WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW);
@@ -477,6 +539,8 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu)
if(MenuObject)
{
IntDestroyMenuObject(MenuObject, FALSE, TRUE);
WindowObject->SystemMenu = (HMENU)0;
IntReleaseMenuObject(MenuObject);
}
}
@@ -515,6 +579,7 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu)
//IntReleaseMenuObject(NewMenuObject);
}
IntDestroyMenuObject(MenuObject, FALSE, TRUE);
IntReleaseMenuObject(MenuObject);
}
if(RetMenu)
return ret;
@@ -523,7 +588,10 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu)
}
else
{
return IntGetMenuObject((HMENU)WindowObject->SystemMenu);
if(WindowObject->SystemMenu)
return IntGetMenuObject((HMENU)WindowObject->SystemMenu);
else
return NULL;
}
}
@@ -714,58 +782,6 @@ IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
return !IntIsWindow(hWndOldParent) ? NULL : WndOldParent;
}
/***********************************************************************
* IntSendDestroyMsg
*/
static void IntSendDestroyMsg(HWND Wnd)
{
#if 0 /* FIXME */
GUITHREADINFO info;
if (GetGUIThreadInfo(GetCurrentThreadId(), &info))
{
if (Wnd == info.hwndCaret)
{
DestroyCaret();
}
}
#endif
/*
* Send the WM_DESTROY to the window.
*/
IntSendMessage(Wnd, WM_DESTROY, 0, 0, TRUE);
/*
* This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
* make sure that the window still exists when we come back.
*/
#if 0 /* FIXME */
if (IsWindow(Wnd))
{
HWND* pWndArray;
int i;
if (!(pWndArray = WIN_ListChildren( hwnd ))) return;
/* start from the end (FIXME: is this needed?) */
for (i = 0; pWndArray[i]; i++) ;
while (--i >= 0)
{
if (IsWindow( pWndArray[i] )) WIN_SendDestroyMsg( pWndArray[i] );
}
HeapFree(GetProcessHeap(), 0, pWndArray);
}
else
{
DPRINT("destroyed itself while in WM_DESTROY!\n");
}
#endif
}
BOOL FASTCALL
IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject)
{
@@ -780,9 +796,14 @@ IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject)
}
}
WindowObject->SystemMenu = MenuObject->Self;
if(MenuObject) /* FIXME check window style, propably return FALSE ? */
if(MenuObject)
{
/* FIXME check window style, propably return FALSE ? */
WindowObject->SystemMenu = MenuObject->Self;
MenuObject->IsSystemMenu = TRUE;
}
else
WindowObject->SystemMenu = (HMENU)0;
return TRUE;
}
@@ -1137,15 +1158,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
WindowObject->Style = dwStyle & ~WS_VISIBLE;
DPRINT("1: Style is now %d\n", WindowObject->Style);
SystemMenu = IntGetSystemMenu(WindowObject, TRUE, TRUE);
if(SystemMenu)
{
WindowObject->SystemMenu = SystemMenu->Self;
IntReleaseMenuObject(SystemMenu);
}
else
WindowObject->SystemMenu = (HANDLE)0;
WindowObject->SystemMenu = (HMENU)0;
WindowObject->ContextHelpId = 0;
WindowObject->IDMenu = (UINT)hMenu;
WindowObject->Instance = hInstance;
@@ -1203,7 +1216,18 @@ NtUserCreateWindowEx(DWORD dwExStyle,
/* FIXME: Note the window needs a size. */
}
}
/* create system menu */
if((WindowObject->Style & WS_SYSMENU) && (WindowObject->Style & WS_CAPTION))
{
SystemMenu = IntGetSystemMenu(WindowObject, TRUE, TRUE);
if(SystemMenu)
{
WindowObject->SystemMenu = SystemMenu->Self;
IntReleaseMenuObject(SystemMenu);
}
}
/* Insert the window into the thread's window list. */
ExAcquireFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
InsertTailList (&PsGetWin32Thread()->WindowListHead,
@@ -1581,9 +1605,6 @@ NtUserDestroyWindow(HWND Wnd)
}
#endif
/* Send destroy messages */
IntSendDestroyMsg(Wnd);
if (!IntIsWindow(Wnd))
{
return TRUE;
@@ -1594,7 +1615,8 @@ NtUserDestroyWindow(HWND Wnd)
/* Destroy the window storage */
IntDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
IntReleaseWindowObject(Window);
return TRUE;
}