From 2b69fbaf70f6a05269d96b2703acfe49ef7f03a1 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 29 Jun 2024 09:36:53 +1000 Subject: Ensure clipboard is closed even if exception occurs while clipboard open. --- win32/ScintillaWin.cxx | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 31d1d826f..748560a10 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -2749,6 +2749,27 @@ bool OpenClipboardRetry(HWND hwnd) noexcept { return false; } +// Ensure every successful OpenClipboard is followed by a CloseClipboard. +class Clipboard { + bool opened = false; +public: + Clipboard(HWND hwnd) noexcept : opened(::OpenClipboardRetry(hwnd)) { + } + // Deleted so Clipboard objects can not be copied. + Clipboard(const Clipboard &) = delete; + Clipboard(Clipboard &&) = delete; + Clipboard &operator=(const Clipboard &) = delete; + Clipboard &operator=(Clipboard &&) = delete; + ~Clipboard() noexcept { + if (opened) { + ::CloseClipboard(); + } + } + constexpr operator bool() const noexcept { + return opened; + } +}; + bool IsValidFormatEtc(const FORMATETC *pFE) noexcept { return pFE->ptd == nullptr && (pFE->dwAspect & DVASPECT_CONTENT) != 0 && @@ -2764,7 +2785,8 @@ bool SupportedFormat(const FORMATETC *pFE) noexcept { } void ScintillaWin::Paste() { - if (!::OpenClipboardRetry(MainHWND())) { + Clipboard clipboard(MainHWND()); + if (!clipboard) { return; } UndoGroup ug(pdoc); @@ -2790,7 +2812,6 @@ void ScintillaWin::Paste() { InsertPasteShape(putf.c_str(), putf.length(), pasteShape); memUSelection.Unlock(); } - ::CloseClipboard(); Redraw(); } @@ -3254,7 +3275,8 @@ void ScintillaWin::CopyToGlobal(GlobalMemory &gmUnicode, const SelectionText &se } void ScintillaWin::CopyToClipboard(const SelectionText &selectedText) { - if (!::OpenClipboardRetry(MainHWND())) { + Clipboard clipboard(MainHWND()); + if (!clipboard) { return; } ::EmptyClipboard(); @@ -3280,8 +3302,6 @@ void ScintillaWin::CopyToClipboard(const SelectionText &selectedText) { ::SetClipboardData(cfLineSelect, 0); ::SetClipboardData(cfVSLineTag, 0); } - - ::CloseClipboard(); } void ScintillaWin::ScrollMessage(WPARAM wParam) { -- cgit v1.2.3