mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
fixed destroying child windows and some fixes on menus
svn path=/trunk/; revision=7099
This commit is contained in:
@@ -32,6 +32,7 @@ typedef struct _MENU_ITEM
|
||||
typedef struct _MENU_OBJECT
|
||||
{
|
||||
HANDLE Self;
|
||||
PW32PROCESS W32Process;
|
||||
LIST_ENTRY ListEntry;
|
||||
int MenuItemCount;
|
||||
FAST_MUTEX MenuItemsLock;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user