From d3e2ba0afb720f9ab91a2264927ea5a232c4eef6 Mon Sep 17 00:00:00 2001 From: Jian Liang Date: Fri, 30 Aug 2013 09:41:44 +0800 Subject: Fix QOleDropTarget object leak 1) call Release() to nativeExtra->dropTraget in QWidgetPrivate::unregisterOleDnd() to prevent leak 2) call RevokeDragDrop() in QWidgetPrivate::setParent_sys() when the old window handle is to be destroyed and the current widget has already registered an ole drop target object to prevent leak Change-Id: I767f4e0ea3e6cb5f14d72ba88e1f8f1bc8c0dc3c Reviewed-by: Friedemann Kleint --- src/gui/kernel/qwidget_win.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index e39b3cf..9419226 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -666,8 +666,20 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) setWindowIcon_sys(true); setWindowTitle_helper(extra->topextra->caption); } - if (old_winid) + if (old_winid) { +#ifndef QT_NO_DRAGANDDROP + if (extra && extra->dropTarget) { + // NOTE: It is possible that the current widget has already registered an ole drop target + // without Qt::WA_DropSiteRegistered being set. In this case we have to call RevokeDragDrop() + // to drop the reference count of the ole drop target object held by windows to prevent leak + // and re-register the old drop target object to the new window handle if possible + RevokeDragDrop(old_winid); + if (q->internalWinId()) + RegisterDragDrop(q->internalWinId(), extra->dropTarget); + } +#endif // !QT_NO_DRAGANDDROP DestroyWindow(old_winid); + } if (q->testAttribute(Qt::WA_AcceptDrops) || dropSiteWasRegistered || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))) @@ -1815,6 +1827,8 @@ void QWidgetPrivate::unregisterOleDnd(QWidget *widget, QOleDropTarget *dropTarge #ifndef Q_OS_WINCE CoLockObjectExternal(nativeExtra->dropTarget, false, true); #endif + nativeExtra->dropTarget->releaseQt(); + nativeExtra->dropTarget->Release(); RevokeDragDrop(nativeParent->internalWinId()); nativeExtra->dropTarget = 0; } -- cgit v0.12