mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
[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. svn path=/trunk/; revision=70744
This commit is contained in:
parent
81c6aeb2dd
commit
c95d274bf6
3 changed files with 68 additions and 13 deletions
|
@ -346,6 +346,43 @@ UserEmptyClipboardData(PWINSTATION_OBJECT pWinSta)
|
|||
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,6 +393,12 @@ UserClipboardFreeWindow(PWND pWindow)
|
|||
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)
|
||||
{
|
||||
|
@ -363,11 +406,6 @@ UserClipboardFreeWindow(PWND pWindow)
|
|||
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)
|
||||
pWinStaObj->spwndClipViewer = NULL;
|
||||
|
@ -500,13 +538,13 @@ UserCloseClipboard(VOID)
|
|||
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 @@ UserEmptyClipboard(VOID)
|
|||
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 @@ NtUserSetClipboardViewer(HWND hWndNewViewer)
|
|||
/* 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);
|
||||
|
|
|
@ -10,6 +10,9 @@ typedef struct _CLIP
|
|||
UINT APIENTRY
|
||||
UserEnumClipboardFormats(UINT uFormat);
|
||||
|
||||
VOID FASTCALL
|
||||
UserClipboardRelease(PWND pWindow);
|
||||
|
||||
VOID FASTCALL
|
||||
UserClipboardFreeWindow(PWND pWindow);
|
||||
|
||||
|
|
|
@ -424,10 +424,14 @@ static void IntSendDestroyMsg(HWND hWnd)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 @@ LRESULT co_UserFreeWindow(PWND Window,
|
|||
co_IntSendMessage(UserHMGetHandle(Window), WM_NCDESTROY, 0, 0);
|
||||
}
|
||||
|
||||
UserClipboardFreeWindow(Window);
|
||||
|
||||
DestroyTimersForWindow(ThreadData, Window);
|
||||
|
||||
/* Unregister hot keys */
|
||||
|
@ -665,8 +671,6 @@ LRESULT co_UserFreeWindow(PWND Window,
|
|||
|
||||
UserDereferenceObject(Window);
|
||||
|
||||
UserClipboardFreeWindow(Window);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue