Fix window destruction on thread termination

svn path=/trunk/; revision=6400
This commit is contained in:
Gé van Geldorp 2003-10-22 13:34:25 +00:00
parent 4baf0a9002
commit b597738dd3
4 changed files with 38 additions and 31 deletions

View file

@ -3,7 +3,10 @@
/* Ported from WINE by Jason Filby */
typedef struct tagDCE *PDCE;
#include <user32/wininternal.h>
#include <include/window.h>
typedef HANDLE HDCE;
@ -31,8 +34,7 @@ typedef struct tagDCE
DCE_TYPE type;
DWORD DCXFlags;
HANDLE Self;
} DCE, *PDCE;
} DCE; /* PDCE already declared at top of file */
#define DCEOBJ_AllocDCE() \
((HDCE) GDIOBJ_AllocObj (sizeof (DCE), GDI_OBJECT_TYPE_DCE, (GDICLEANUPPROC) DCE_InternalDelete))
@ -50,6 +52,6 @@ BOOL FASTCALL DCE_InvalidateDCE(HWND, const PRECTL);
BOOL FASTCALL DCE_InternalDelete(PDCE dce);
HWND FASTCALL IntWindowFromDC(HDC hDc);
PDCE FASTCALL DceFreeDCE(PDCE dce);
void FASTCALL DceFreeWindowDCE(HWND hwnd);
void FASTCALL DceFreeWindowDCE(PWINDOW_OBJECT Window);
#endif

View file

@ -3,6 +3,7 @@
struct _PROPERTY;
struct _WINDOW_OBJECT;
typedef struct _WINDOW_OBJECT *PWINDOW_OBJECT;
#include <windows.h>
#include <ddk/ntddk.h>
@ -92,7 +93,7 @@ typedef struct _WINDOW_OBJECT
PETHREAD OwnerThread;
HWND hWndOwner; /* handle to the owner window (wine doesn't use pointer, for unk. reason)*/
HWND hWndLastPopup; /* handle to last active popup window (wine doesn't use pointer, for unk. reason)*/
} WINDOW_OBJECT, *PWINDOW_OBJECT;
} WINDOW_OBJECT; /* PWINDOW_OBJECT already declared at top of file */
/* Window flags. */
#define WINDOWOBJECT_NEED_SIZE (0x00000001)

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: windc.c,v 1.33 2003/10/20 17:57:05 gvg Exp $
/* $Id: windc.c,v 1.34 2003/10/22 13:34:25 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -637,22 +637,21 @@ DceFreeDCE(PDCE dce)
* Remove owned DCE and reset unreleased cache DCEs.
*/
void FASTCALL
DceFreeWindowDCE(HWND hwnd)
DceFreeWindowDCE(PWINDOW_OBJECT Window)
{
DCE *pDCE;
PWINDOW_OBJECT pWnd = IntGetWindowObject(hwnd);
pDCE = FirstDce;
while (pDCE)
{
if (pDCE->hwndCurrent == hwnd)
if (pDCE->hwndCurrent == Window->Self)
{
if (pDCE == pWnd->Dce) /* owned or Class DCE*/
if (pDCE == Window->Dce) /* owned or Class DCE*/
{
if (pWnd->Class->style & CS_OWNDC) /* owned DCE*/
if (Window->Class->style & CS_OWNDC) /* owned DCE*/
{
pDCE = DceFreeDCE(pDCE);
pWnd->Dce = NULL;
Window->Dce = NULL;
continue;
}
else if (pDCE->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) /* Class DCE*/
@ -672,7 +671,7 @@ DceFreeWindowDCE(HWND hwnd)
* We should change this to DPRINT when ReactOS is more stable
* (for 1.0?).
*/
DPRINT1("[%p] GetDC() without ReleaseDC()!\n", hwnd);
DPRINT1("[%p] GetDC() without ReleaseDC()!\n", Window->Self);
DceReleaseDC(pDCE);
}
@ -683,8 +682,6 @@ DceFreeWindowDCE(HWND hwnd)
}
pDCE = pDCE->next;
}
IntReleaseWindowObject(pWnd);
}
/* 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: window.c,v 1.115 2003/10/18 10:35:52 navaraf Exp $
/* $Id: window.c,v 1.116 2003/10/22 13:34:25 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -101,6 +101,26 @@ inline BOOL IntIsDesktopWindow(PWINDOW_OBJECT Wnd)
}
static PWINDOW_OBJECT FASTCALL
IntGetProcessWindowObject(PW32PROCESS ProcessData, HWND hWnd)
{
PWINDOW_OBJECT WindowObject;
NTSTATUS Status;
Status =
ObmReferenceObjectByHandle(ProcessData->WindowStation->
HandleTable,
hWnd,
otWindow,
(PVOID*)&WindowObject);
if (!NT_SUCCESS(Status))
{
return(NULL);
}
return(WindowObject);
}
static BOOL BuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsigned *NumChildren)
{
unsigned Index;
@ -172,7 +192,7 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
}
for (Index = NumChildren; 0 < Index; Index--)
{
Child = IntGetWindowObject(Children[Index - 1]);
Child = IntGetProcessWindowObject(ProcessData, Children[Index - 1]);
if (NULL != Child)
{
if (IntWndBelongsToThread(Child, ThreadData))
@ -243,7 +263,7 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
Window->hSysMenu = 0;
}
#endif
DceFreeWindowDCE(Window->Self); /* Always do this to catch orphaned DCs */
DceFreeWindowDCE(Window); /* Always do this to catch orphaned DCs */
#if 0 /* FIXME */
WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW);
CLASS_RemoveWindow(Window->Class);
@ -540,20 +560,7 @@ IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu)
PWINDOW_OBJECT FASTCALL
IntGetWindowObject(HWND hWnd)
{
PWINDOW_OBJECT WindowObject;
NTSTATUS Status;
Status =
ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->
HandleTable,
hWnd,
otWindow,
(PVOID*)&WindowObject);
if (!NT_SUCCESS(Status))
{
return(NULL);
}
return(WindowObject);
return IntGetProcessWindowObject(PsGetWin32Process(), hWnd);
}