Author: hbelusca
Date: Sun Feb 14 18:41:49 2016
New Revision: 70744
URL: http://svn.reactos.org/svn/reactos?rev=70744&view=rev
Log:
[WIN32K:NTUSER]
- Cleanup window clipboard data while the window still exists and is not dereferenced.
- When a window is about to be destroyed (just before we send the WM_DESTROY message), if it is the current clipboard owner, make it release the clipboard. The WM_RENDERALLFORMATS message is then sent, and if needed, one WM_DRAWCLIPBOARD message.
- Send a WM_DRAWCLIPBOARD message when SetClipboardViewer is called.
WM_DRAWCLIPBOARD messages are sent as notifications to the corresponding windows.
Modified:
trunk/reactos/win32ss/user/ntuser/clipboard.c
trunk/reactos/win32ss/user/ntuser/clipboard.h
trunk/reactos/win32ss/user/ntuser/window.c
Modified: trunk/reactos/win32ss/user/ntuser/clipboard.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/clipbo…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/clipboard.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/clipboard.c [iso-8859-1] Sun Feb 14 18:41:49 2016
@@ -346,6 +346,43 @@
pWinSta->cNumClipFormats = 0;
}
+/* UserClipboardRelease is called from IntSendDestroyMsg in window.c */
+VOID FASTCALL
+UserClipboardRelease(PWND pWindow)
+{
+ PWINSTATION_OBJECT pWinStaObj;
+
+ pWinStaObj = IntGetWinStaForCbAccess();
+ if (!pWinStaObj)
+ return;
+
+ co_IntSendMessage(pWinStaObj->spwndClipOwner->head.h, WM_RENDERALLFORMATS, 0, 0);
+
+ /* If the window being destroyed is the current clipboard owner... */
+ if (pWindow == pWinStaObj->spwndClipOwner)
+ {
+ /* ... make it release the clipboard */
+ pWinStaObj->spwndClipOwner = NULL;
+ }
+
+ if (pWinStaObj->fClipboardChanged)
+ {
+ /* Add synthesized formats - they are rendered later */
+ IntAddSynthesizedFormats(pWinStaObj);
+
+ /* Notify viewer windows in chain */
+ pWinStaObj->fClipboardChanged = FALSE;
+ if (pWinStaObj->spwndClipViewer)
+ {
+ TRACE("Clipboard: sending WM_DRAWCLIPBOARD to %p\n", pWinStaObj->spwndClipViewer->head.h);
+ // For 32-bit applications this message is sent as a notification
+ co_IntSendMessageNoWait(pWinStaObj->spwndClipViewer->head.h, WM_DRAWCLIPBOARD, 0, 0);
+ }
+ }
+
+ ObDereferenceObject(pWinStaObj);
+}
+
/* UserClipboardFreeWindow is called from co_UserFreeWindow in window.c */
VOID FASTCALL
UserClipboardFreeWindow(PWND pWindow)
@@ -356,17 +393,18 @@
if (!pWinStaObj)
return;
+ if (pWindow == pWinStaObj->spwndClipOwner)
+ {
+ /* The owner window was destroyed */
+ pWinStaObj->spwndClipOwner = NULL;
+ }
+
/* Check if clipboard is not locked by this window, if yes, unlock it */
if (pWindow == pWinStaObj->spwndClipOpen)
{
/* The window that opens the clipboard was destroyed */
pWinStaObj->spwndClipOpen = NULL;
pWinStaObj->ptiClipLock = NULL;
- }
- if (pWindow == pWinStaObj->spwndClipOwner)
- {
- /* The owner window was destroyed */
- pWinStaObj->spwndClipOwner = NULL;
}
/* Remove window from window chain */
if (pWindow == pWinStaObj->spwndClipViewer)
@@ -500,13 +538,13 @@
IntAddSynthesizedFormats(pWinStaObj);
/* Notify viewer windows in chain */
+ pWinStaObj->fClipboardChanged = FALSE;
if (pWinStaObj->spwndClipViewer)
{
TRACE("Clipboard: sending WM_DRAWCLIPBOARD to %p\n", pWinStaObj->spwndClipViewer->head.h);
- co_IntSendMessage(pWinStaObj->spwndClipViewer->head.h, WM_DRAWCLIPBOARD, 0, 0);
+ // For 32-bit applications this message is sent as a notification
+ co_IntSendMessageNoWait(pWinStaObj->spwndClipViewer->head.h, WM_DRAWCLIPBOARD, 0, 0);
}
-
- pWinStaObj->fClipboardChanged = FALSE;
}
cleanup:
@@ -629,6 +667,7 @@
if (pWinStaObj->spwndClipOwner)
{
TRACE("Clipboard: WM_DESTROYCLIPBOARD to %p\n", pWinStaObj->spwndClipOwner->head.h);
+ // For 32-bit applications this message is sent as a notification
co_IntSendMessageNoWait(pWinStaObj->spwndClipOwner->head.h, WM_DESTROYCLIPBOARD, 0, 0);
}
@@ -1053,6 +1092,15 @@
/* Set new viewer window */
pWinStaObj->spwndClipViewer = pWindow;
+ /* Notify viewer windows in chain */
+ pWinStaObj->fClipboardChanged = FALSE;
+ if (pWinStaObj->spwndClipViewer)
+ {
+ TRACE("Clipboard: sending WM_DRAWCLIPBOARD to %p\n", pWinStaObj->spwndClipViewer->head.h);
+ // For 32-bit applications this message is sent as a notification
+ co_IntSendMessageNoWait(pWinStaObj->spwndClipViewer->head.h, WM_DRAWCLIPBOARD, 0, 0);
+ }
+
cleanup:
if (pWinStaObj)
ObDereferenceObject(pWinStaObj);
Modified: trunk/reactos/win32ss/user/ntuser/clipboard.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/clipbo…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/clipboard.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/clipboard.h [iso-8859-1] Sun Feb 14 18:41:49 2016
@@ -9,6 +9,9 @@
UINT APIENTRY
UserEnumClipboardFormats(UINT uFormat);
+
+VOID FASTCALL
+UserClipboardRelease(PWND pWindow);
VOID FASTCALL
UserClipboardFreeWindow(PWND pWindow);
Modified: trunk/reactos/win32ss/user/ntuser/window.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/window…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] Sun Feb 14 18:41:49 2016
@@ -424,10 +424,14 @@
}
}
- /*
- * Send the WM_DESTROY to the window.
- */
-
+ /* If the window being destroyed is the current clipboard owner... */
+ if (ti->ppi->prpwinsta != NULL && Window == ti->ppi->prpwinsta->spwndClipOwner)
+ {
+ /* ... make it release the clipboard */
+ UserClipboardRelease(Window);
+ }
+
+ /* Send the WM_DESTROY to the window */
co_IntSendMessage(hWnd, WM_DESTROY, 0, 0);
/*
@@ -554,6 +558,8 @@
co_IntSendMessage(UserHMGetHandle(Window), WM_NCDESTROY, 0, 0);
}
+ UserClipboardFreeWindow(Window);
+
DestroyTimersForWindow(ThreadData, Window);
/* Unregister hot keys */
@@ -664,8 +670,6 @@
UserFreeWindowInfo(Window->head.pti, Window);
UserDereferenceObject(Window);
-
- UserClipboardFreeWindow(Window);
return 0;
}
Author: hbelusca
Date: Sun Feb 14 18:26:23 2016
New Revision: 70743
URL: http://svn.reactos.org/svn/reactos?rev=70743&view=rev
Log:
[WIN32K]: Some whitespace fixes.
Modified:
trunk/reactos/win32ss/user/ntuser/window.c
Modified: trunk/reactos/win32ss/user/ntuser/window.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/window…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] Sun Feb 14 18:26:23 2016
@@ -394,8 +394,9 @@
if (Window)
{
- /* Look whether the focus is within the tree of windows we will
- * be destroying.
+ /*
+ * Look whether the focus is within the tree of windows
+ * we will be destroying.
*/
// Rule #1
if ( ti->MessageQueue->spwndActive == Window || // Fixes CORE-106 RegSvr32 exit and return focus to CMD.
@@ -433,7 +434,6 @@
* This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
* make sure that the window still exists when we come back.
*/
-
if (IntIsWindow(hWnd))
{
HWND* pWndArray;
@@ -480,13 +480,12 @@
}
/***********************************************************************
- * IntDestroyWindow
+ * co_UserFreeWindow
*
* Destroy storage associated to a window. "Internals" p.358
*
- * This is the "functional" DestroyWindows function ei. all stuff
- * done in CreateWindow is undone here and not in DestroyWindow:-P
-
+ * This is the "functional" DestroyWindows function i.e. all stuff
+ * done in CreateWindow is undone here and not in DestroyWindow :-P
*/
LRESULT co_UserFreeWindow(PWND Window,
PPROCESSINFO ProcessData,
@@ -503,7 +502,7 @@
if(Window->state2 & WNDS2_INDESTROY)
{
- TRACE("Tried to call IntDestroyWindow() twice\n");
+ TRACE("Tried to call co_UserFreeWindow() twice\n");
return 0;
}
Window->state2 |= WNDS2_INDESTROY;
@@ -513,7 +512,7 @@
/* remove the window already at this point from the thread window list so we
don't get into trouble when destroying the thread windows while we're still
- in IntDestroyWindow() */
+ in co_UserFreeWindow() */
RemoveEntryList(&Window->ThreadListEntry);
BelongsToThreadData = IntWndBelongsToThread(Window, ThreadData);
@@ -528,7 +527,7 @@
{
if ((Child = IntGetWindowObject(*ChildHandle)))
{
- if(!IntWndBelongsToThread(Child, ThreadData))
+ if (!IntWndBelongsToThread(Child, ThreadData))
{
/* send WM_DESTROY messages to windows not belonging to the same thread */
co_IntSendMessage( UserHMGetHandle(Child), WM_ASYNC_DESTROYWINDOW, 0, 0 );
@@ -542,7 +541,7 @@
ExFreePoolWithTag(Children, USERTAG_WINDOWLIST);
}
- if(SendMessages)
+ if (SendMessages)
{
/*
* Clear the update region to make sure no WM_PAINT messages will be
@@ -551,7 +550,7 @@
co_UserRedrawWindow(Window, NULL, 0,
RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
- if(BelongsToThreadData)
+ if (BelongsToThreadData)
co_IntSendMessage(UserHMGetHandle(Window), WM_NCDESTROY, 0, 0);
}
@@ -570,7 +569,7 @@
/* don't remove the WINDOWSTATUS_DESTROYING bit */
/* reset shell window handles */
- if(ThreadData->rpdesk)
+ if (ThreadData->rpdesk)
{
if (Window->head.h == ThreadData->rpdesk->rpwinstaParent->ShellWindow)
ThreadData->rpdesk->rpwinstaParent->ShellWindow = NULL;
@@ -617,8 +616,8 @@
Window->IDMenu = 0;
}
- if(Window->SystemMenu
- && (Menu = UserGetMenuObject(Window->SystemMenu)))
+ if (Window->SystemMenu
+ && (Menu = UserGetMenuObject(Window->SystemMenu)))
{
IntDestroyMenuObject(Menu, TRUE);
Window->SystemMenu = (HMENU)0;
@@ -653,7 +652,7 @@
Window->head.pti->ppi);
Window->pcls = NULL;
- if(Window->hrgnClip)
+ if (Window->hrgnClip)
{
IntGdiSetRegionOwner(Window->hrgnClip, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(Window->hrgnClip);
@@ -2674,7 +2673,6 @@
IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
/* Send destroy messages */
-
IntSendDestroyMsg(UserHMGetHandle(Window));
if (!IntIsWindow(UserHMGetHandle(Window)))