Fix Encoding "Convert to..." regression
Fix incorrect Clipboard handling. This commit fixes possibly #9426 Fix #15324, fix #15271, fix #3054, close #15346
This commit is contained in:
parent
53d87d4f62
commit
3c3e7cdadd
|
@ -858,7 +858,6 @@ bool str2Clipboard(const generic_string &str2cpy, HWND hwnd)
|
|||
if (!::OpenClipboard(hwnd))
|
||||
{
|
||||
::GlobalFree(hglbCopy);
|
||||
::CloseClipboard();
|
||||
return false;
|
||||
}
|
||||
if (!::EmptyClipboard())
|
||||
|
@ -869,9 +868,8 @@ bool str2Clipboard(const generic_string &str2cpy, HWND hwnd)
|
|||
}
|
||||
// Lock the handle and copy the text to the buffer.
|
||||
TCHAR *pStr = (TCHAR *)::GlobalLock(hglbCopy);
|
||||
if (pStr == NULL)
|
||||
if (!pStr)
|
||||
{
|
||||
::GlobalUnlock(hglbCopy);
|
||||
::GlobalFree(hglbCopy);
|
||||
::CloseClipboard();
|
||||
return false;
|
||||
|
@ -880,7 +878,7 @@ bool str2Clipboard(const generic_string &str2cpy, HWND hwnd)
|
|||
::GlobalUnlock(hglbCopy);
|
||||
// Place the handle on the clipboard.
|
||||
unsigned int clipBoardFormat = CF_UNICODETEXT;
|
||||
if (::SetClipboardData(clipBoardFormat, hglbCopy) == NULL)
|
||||
if (!::SetClipboardData(clipBoardFormat, hglbCopy))
|
||||
{
|
||||
::GlobalFree(hglbCopy);
|
||||
::CloseClipboard();
|
||||
|
|
|
@ -2870,19 +2870,29 @@ void Notepad_plus::pasteToMarkedLines()
|
|||
{
|
||||
std::lock_guard<std::mutex> lock(mark_mutex);
|
||||
|
||||
int clipFormat;
|
||||
clipFormat = CF_UNICODETEXT;
|
||||
unsigned int clipFormat = CF_UNICODETEXT;
|
||||
|
||||
BOOL canPaste = ::IsClipboardFormatAvailable(clipFormat);
|
||||
if (!canPaste)
|
||||
if (!::IsClipboardFormatAvailable(clipFormat))
|
||||
return;
|
||||
|
||||
intptr_t lastLine = _pEditView->lastZeroBasedLineNumber();
|
||||
|
||||
::OpenClipboard(_pPublicInterface->getHSelf());
|
||||
if (!::OpenClipboard(_pPublicInterface->getHSelf()))
|
||||
return;
|
||||
|
||||
HANDLE clipboardData = ::GetClipboardData(clipFormat);
|
||||
::GlobalSize(clipboardData);
|
||||
if (!clipboardData)
|
||||
{
|
||||
::CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
LPVOID clipboardDataPtr = ::GlobalLock(clipboardData);
|
||||
if (!clipboardDataPtr) return;
|
||||
if (!clipboardDataPtr)
|
||||
{
|
||||
::CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
generic_string clipboardStr = (const TCHAR *)clipboardDataPtr;
|
||||
|
||||
|
|
|
@ -427,51 +427,70 @@ void Notepad_plus::command(int id)
|
|||
char *pBinText = new char[textLen + 1];
|
||||
_pEditView->getSelectedText(pBinText, textLen + 1);
|
||||
|
||||
// Open the clipboard, and empty it.
|
||||
if (!OpenClipboard(NULL))
|
||||
// Open the clipboard and empty it.
|
||||
if (!::OpenClipboard(NULL))
|
||||
return;
|
||||
EmptyClipboard();
|
||||
if (!::EmptyClipboard())
|
||||
{
|
||||
::CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate a global memory object for the text.
|
||||
HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (textLen + 1) * sizeof(unsigned char));
|
||||
if (hglbCopy == NULL)
|
||||
HGLOBAL hglbCopy = ::GlobalAlloc(GMEM_MOVEABLE, (textLen + 1) * sizeof(unsigned char));
|
||||
if (!hglbCopy)
|
||||
{
|
||||
CloseClipboard();
|
||||
::CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
// Lock the handle and copy the text to the buffer.
|
||||
unsigned char *lpucharCopy = (unsigned char *)GlobalLock(hglbCopy);
|
||||
unsigned char *lpucharCopy = (unsigned char *)::GlobalLock(hglbCopy);
|
||||
if (!lpucharCopy)
|
||||
{
|
||||
::GlobalFree(hglbCopy);
|
||||
::CloseClipboard();
|
||||
return;
|
||||
}
|
||||
memcpy(lpucharCopy, pBinText, textLen * sizeof(unsigned char));
|
||||
lpucharCopy[textLen] = 0; // null character
|
||||
|
||||
delete[] pBinText;
|
||||
|
||||
GlobalUnlock(hglbCopy);
|
||||
::GlobalUnlock(hglbCopy);
|
||||
|
||||
// Place the handle on the clipboard.
|
||||
SetClipboardData(CF_TEXT, hglbCopy);
|
||||
|
||||
if (!::SetClipboardData(CF_TEXT, hglbCopy))
|
||||
{
|
||||
::GlobalFree(hglbCopy);
|
||||
::CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate a global memory object for the text length.
|
||||
HGLOBAL hglbLenCopy = GlobalAlloc(GMEM_MOVEABLE, sizeof(unsigned long));
|
||||
if (hglbLenCopy == NULL)
|
||||
HGLOBAL hglbLenCopy = ::GlobalAlloc(GMEM_MOVEABLE, sizeof(unsigned long));
|
||||
if (!hglbLenCopy)
|
||||
{
|
||||
CloseClipboard();
|
||||
::CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
// Lock the handle and copy the text to the buffer.
|
||||
unsigned long *lpLenCopy = (unsigned long *)GlobalLock(hglbLenCopy);
|
||||
unsigned long *lpLenCopy = (unsigned long *)::GlobalLock(hglbLenCopy);
|
||||
if (!lpLenCopy)
|
||||
{
|
||||
::CloseClipboard();
|
||||
return;
|
||||
}
|
||||
*lpLenCopy = static_cast<unsigned long>(textLen);
|
||||
|
||||
GlobalUnlock(hglbLenCopy);
|
||||
::GlobalUnlock(hglbLenCopy);
|
||||
|
||||
// Place the handle on the clipboard.
|
||||
UINT cf_nppTextLen = RegisterClipboardFormat(CF_NPPTEXTLEN);
|
||||
SetClipboardData(cf_nppTextLen, hglbLenCopy);
|
||||
UINT cf_nppTextLen = ::RegisterClipboardFormat(CF_NPPTEXTLEN);
|
||||
::SetClipboardData(cf_nppTextLen, hglbLenCopy);
|
||||
|
||||
CloseClipboard();
|
||||
::CloseClipboard();
|
||||
|
||||
if (id == IDM_EDIT_CUT_BINARY)
|
||||
_pEditView->execute(SCI_REPLACESEL, 0, reinterpret_cast<LPARAM>(""));
|
||||
|
@ -3122,44 +3141,95 @@ void Notepad_plus::command(int id)
|
|||
|
||||
if (idEncoding != -1)
|
||||
{
|
||||
// Save the current clipboard content
|
||||
::OpenClipboard(_pPublicInterface->getHSelf());
|
||||
HANDLE clipboardData = ::GetClipboardData(CF_TEXT);
|
||||
LPVOID clipboardData2 = NULL;
|
||||
if (clipboardData != NULL)
|
||||
// try to save the current clipboard CF_TEXT content 1st
|
||||
HGLOBAL hglbClipboardCopy = NULL;
|
||||
if (::OpenClipboard(_pPublicInterface->getHSelf()))
|
||||
{
|
||||
int len = static_cast<int32_t>(::GlobalSize(clipboardData));
|
||||
LPVOID clipboardDataPtr = ::GlobalLock(clipboardData);
|
||||
|
||||
HANDLE allocClipboardData = ::GlobalAlloc(GMEM_MOVEABLE, len);
|
||||
clipboardData2 = ::GlobalLock(allocClipboardData);
|
||||
|
||||
::memcpy(clipboardData2, clipboardDataPtr, len);
|
||||
::GlobalUnlock(clipboardData);
|
||||
::GlobalUnlock(allocClipboardData);
|
||||
HANDLE hClipboardData = ::GetClipboardData(CF_TEXT);
|
||||
if (hClipboardData) // NULL if there is no previous CF_TEXT data in
|
||||
{
|
||||
LPVOID pClipboardData = ::GlobalLock(hClipboardData);
|
||||
if (pClipboardData)
|
||||
{
|
||||
size_t clipboardDataSize = ::GlobalSize(pClipboardData);
|
||||
hglbClipboardCopy = ::GlobalAlloc(GMEM_MOVEABLE, clipboardDataSize);
|
||||
if (hglbClipboardCopy)
|
||||
{
|
||||
LPVOID pClipboardCopy = ::GlobalLock(hglbClipboardCopy);
|
||||
if (pClipboardCopy)
|
||||
{
|
||||
::memcpy(pClipboardCopy, pClipboardData, clipboardDataSize);
|
||||
::GlobalUnlock(hglbClipboardCopy);
|
||||
}
|
||||
else
|
||||
{
|
||||
::GlobalFree(hglbClipboardCopy);
|
||||
hglbClipboardCopy = NULL;
|
||||
}
|
||||
}
|
||||
::GlobalUnlock(hClipboardData);
|
||||
}
|
||||
}
|
||||
::CloseClipboard();
|
||||
}
|
||||
|
||||
_pEditView->saveCurrentPos();
|
||||
|
||||
bool bPreviousCHPanelTrackingState = true;
|
||||
if (_pClipboardHistoryPanel)
|
||||
bPreviousCHPanelTrackingState = _pClipboardHistoryPanel->trackClipboardOps(false); // we do not want to track & show the next Clipboard op
|
||||
|
||||
// Cut all text
|
||||
size_t docLen = _pEditView->getCurrentDocLen();
|
||||
_pEditView->execute(SCI_COPYRANGE, 0, docLen);
|
||||
_pEditView->execute(SCI_CLEARALL);
|
||||
|
||||
if (_pClipboardHistoryPanel)
|
||||
_pClipboardHistoryPanel->trackClipboardOps(bPreviousCHPanelTrackingState); // restore
|
||||
|
||||
// Change to the proper buffer, save buffer status
|
||||
|
||||
::SendMessage(_pPublicInterface->getHSelf(), WM_COMMAND, idEncoding, 0);
|
||||
|
||||
// Paste the texte, restore buffer status
|
||||
// Paste the text, restore buffer status
|
||||
_pEditView->execute(SCI_PASTE);
|
||||
_pEditView->restoreCurrentPosPreStep();
|
||||
|
||||
// Restore the previous clipboard data
|
||||
::OpenClipboard(_pPublicInterface->getHSelf());
|
||||
::EmptyClipboard();
|
||||
::SetClipboardData(CF_TEXT, clipboardData2);
|
||||
::CloseClipboard();
|
||||
// Restore the previous Clipboard data if any
|
||||
if (hglbClipboardCopy)
|
||||
{
|
||||
bool bAllOk = false;
|
||||
if (::OpenClipboard(_pPublicInterface->getHSelf()))
|
||||
{
|
||||
LPVOID pClipboardCopy = ::GlobalLock(hglbClipboardCopy);
|
||||
if (pClipboardCopy)
|
||||
{
|
||||
if (::EmptyClipboard())
|
||||
{
|
||||
if (::SetClipboardData(CF_TEXT, pClipboardCopy))
|
||||
bAllOk = true;
|
||||
}
|
||||
::GlobalUnlock(hglbClipboardCopy);
|
||||
}
|
||||
::CloseClipboard();
|
||||
}
|
||||
if (!bAllOk)
|
||||
{
|
||||
// when we failed to pass the data back to the Clipboard,
|
||||
// we have to free our copy here otherwise there will be memory leak
|
||||
::GlobalFree(hglbClipboardCopy);
|
||||
hglbClipboardCopy = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no previous Clipboard data, clear the ones used by the Scintilla's conversion
|
||||
if (::OpenClipboard(_pPublicInterface->getHSelf()))
|
||||
{
|
||||
::EmptyClipboard();
|
||||
::CloseClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
//Do not free anything, EmptyClipboard does that
|
||||
_pEditView->execute(SCI_EMPTYUNDOBUFFER);
|
||||
|
|
|
@ -4591,68 +4591,77 @@ bool ScintillaEditView::pasteToMultiSelection() const
|
|||
|
||||
// "MSDEVColumnSelect" is column format from Scintilla
|
||||
CLIPFORMAT cfColumnSelect = static_cast<CLIPFORMAT>(::RegisterClipboardFormat(TEXT("MSDEVColumnSelect")));
|
||||
if (IsClipboardFormatAvailable(cfColumnSelect) && OpenClipboard(NULL))
|
||||
if (!::IsClipboardFormatAvailable(cfColumnSelect) || !::OpenClipboard(NULL))
|
||||
return false;
|
||||
|
||||
HANDLE clipboardData = ::GetClipboardData(CF_UNICODETEXT);
|
||||
if (!clipboardData)
|
||||
{
|
||||
HANDLE clipboardData = ::GetClipboardData(CF_UNICODETEXT);
|
||||
::GlobalSize(clipboardData);
|
||||
LPVOID clipboardDataPtr = ::GlobalLock(clipboardData);
|
||||
if (clipboardDataPtr)
|
||||
{
|
||||
wstring clipboardStr = (const TCHAR*)clipboardDataPtr;
|
||||
::GlobalUnlock(clipboardData);
|
||||
::CloseClipboard();
|
||||
|
||||
vector<wstring> clipboardStrings;
|
||||
stringSplit(clipboardStr, getEOLString(), clipboardStrings);
|
||||
clipboardStrings.erase(clipboardStrings.cend() - 1); // remove the last empty string
|
||||
size_t nbClipboardStr = clipboardStrings.size();
|
||||
|
||||
if (nbSelections >= nbClipboardStr) // enough holes for every insertion, keep holes empty if there are some left
|
||||
{
|
||||
execute(SCI_BEGINUNDOACTION);
|
||||
for (size_t i = 0; i < nbClipboardStr; ++i)
|
||||
{
|
||||
LRESULT posStart = execute(SCI_GETSELECTIONNSTART, i);
|
||||
LRESULT posEnd = execute(SCI_GETSELECTIONNEND, i);
|
||||
replaceTarget(clipboardStrings[i].c_str(), posStart, posEnd);
|
||||
posStart += clipboardStrings[i].length();
|
||||
execute(SCI_SETSELECTIONNSTART, i, posStart);
|
||||
execute(SCI_SETSELECTIONNEND, i, posStart);
|
||||
}
|
||||
execute(SCI_ENDUNDOACTION);
|
||||
return true;
|
||||
}
|
||||
else if (nbSelections < nbClipboardStr) // not enough holes for insertion, every hole has several insertions
|
||||
{
|
||||
size_t nbStr2takeFromClipboard = nbClipboardStr / nbSelections;
|
||||
|
||||
execute(SCI_BEGINUNDOACTION);
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < nbSelections; ++i)
|
||||
{
|
||||
LRESULT posStart = execute(SCI_GETSELECTIONNSTART, i);
|
||||
LRESULT posEnd = execute(SCI_GETSELECTIONNEND, i);
|
||||
wstring severalStr;
|
||||
wstring eol = getEOLString();
|
||||
for (size_t k = 0; k < nbStr2takeFromClipboard && j < nbClipboardStr; ++k)
|
||||
{
|
||||
severalStr += clipboardStrings[j];
|
||||
severalStr += eol;
|
||||
++j;
|
||||
}
|
||||
|
||||
// remove the latest added EOL
|
||||
severalStr.erase(severalStr.length() - eol.length());
|
||||
|
||||
replaceTarget(severalStr.c_str(), posStart, posEnd);
|
||||
posStart += severalStr.length();
|
||||
execute(SCI_SETSELECTIONNSTART, i, posStart);
|
||||
execute(SCI_SETSELECTIONNEND, i, posStart);
|
||||
}
|
||||
execute(SCI_ENDUNDOACTION);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
::CloseClipboard();
|
||||
return false;
|
||||
}
|
||||
|
||||
LPVOID clipboardDataPtr = ::GlobalLock(clipboardData);
|
||||
if (!clipboardDataPtr)
|
||||
{
|
||||
::CloseClipboard();
|
||||
return false;
|
||||
}
|
||||
|
||||
wstring clipboardStr = static_cast<const TCHAR*>(clipboardDataPtr);
|
||||
::GlobalUnlock(clipboardData);
|
||||
::CloseClipboard();
|
||||
|
||||
vector<wstring> clipboardStrings;
|
||||
stringSplit(clipboardStr, getEOLString(), clipboardStrings);
|
||||
clipboardStrings.erase(clipboardStrings.cend() - 1); // remove the last empty string
|
||||
size_t nbClipboardStr = clipboardStrings.size();
|
||||
|
||||
if (nbSelections >= nbClipboardStr) // enough holes for every insertion, keep holes empty if there are some left
|
||||
{
|
||||
execute(SCI_BEGINUNDOACTION);
|
||||
for (size_t i = 0; i < nbClipboardStr; ++i)
|
||||
{
|
||||
LRESULT posStart = execute(SCI_GETSELECTIONNSTART, i);
|
||||
LRESULT posEnd = execute(SCI_GETSELECTIONNEND, i);
|
||||
replaceTarget(clipboardStrings[i].c_str(), posStart, posEnd);
|
||||
posStart += clipboardStrings[i].length();
|
||||
execute(SCI_SETSELECTIONNSTART, i, posStart);
|
||||
execute(SCI_SETSELECTIONNEND, i, posStart);
|
||||
}
|
||||
execute(SCI_ENDUNDOACTION);
|
||||
return true;
|
||||
}
|
||||
else if (nbSelections < nbClipboardStr) // not enough holes for insertion, every hole has several insertions
|
||||
{
|
||||
size_t nbStr2takeFromClipboard = nbClipboardStr / nbSelections;
|
||||
|
||||
execute(SCI_BEGINUNDOACTION);
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < nbSelections; ++i)
|
||||
{
|
||||
LRESULT posStart = execute(SCI_GETSELECTIONNSTART, i);
|
||||
LRESULT posEnd = execute(SCI_GETSELECTIONNEND, i);
|
||||
wstring severalStr;
|
||||
wstring eol = getEOLString();
|
||||
for (size_t k = 0; k < nbStr2takeFromClipboard && j < nbClipboardStr; ++k)
|
||||
{
|
||||
severalStr += clipboardStrings[j];
|
||||
severalStr += eol;
|
||||
++j;
|
||||
}
|
||||
|
||||
// remove the latest added EOL
|
||||
severalStr.erase(severalStr.length() - eol.length());
|
||||
|
||||
replaceTarget(severalStr.c_str(), posStart, posEnd);
|
||||
posStart += severalStr.length();
|
||||
execute(SCI_SETSELECTIONNSTART, i, posStart);
|
||||
execute(SCI_SETSELECTIONNEND, i, posStart);
|
||||
}
|
||||
execute(SCI_ENDUNDOACTION);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1734,22 +1734,26 @@ bool StringDlg::isAllowed([[maybe_unused]] const generic_string & txt)
|
|||
|
||||
void StringDlg::HandlePaste(HWND hEdit)
|
||||
{
|
||||
if (OpenClipboard(hEdit))
|
||||
if (!::OpenClipboard(hEdit))
|
||||
return;
|
||||
|
||||
HANDLE hClipboardData = ::GetClipboardData(CF_UNICODETEXT);
|
||||
if (!hClipboardData)
|
||||
{
|
||||
HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
|
||||
if (NULL != hClipboardData)
|
||||
{
|
||||
LPTSTR pszText = static_cast<LPTSTR>(GlobalLock(hClipboardData));
|
||||
if (NULL != pszText && isAllowed(pszText))
|
||||
{
|
||||
SendMessage(hEdit, EM_REPLACESEL, TRUE, reinterpret_cast<LPARAM>(pszText));
|
||||
}
|
||||
|
||||
GlobalUnlock(hClipboardData);
|
||||
}
|
||||
|
||||
CloseClipboard();
|
||||
::CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
LPTSTR pszText = static_cast<LPTSTR>(::GlobalLock(hClipboardData));
|
||||
if (pszText)
|
||||
{
|
||||
if (isAllowed(pszText))
|
||||
::SendMessage(hEdit, EM_REPLACESEL, TRUE, reinterpret_cast<LPARAM>(pszText));
|
||||
|
||||
::GlobalUnlock(hClipboardData);
|
||||
}
|
||||
|
||||
::CloseClipboard();
|
||||
}
|
||||
|
||||
void StylerDlg::move2CtrlRight(HWND hwndDlg, int ctrlID, HWND handle2Move, int handle2MoveWidth, int handle2MoveHeight)
|
||||
|
|
|
@ -230,18 +230,21 @@ intptr_t CALLBACK ClipboardHistoryPanel::run_dlgProc(UINT message, WPARAM wParam
|
|||
::SendMessage(_hwndNextCbViewer, message, wParam, lParam);
|
||||
return TRUE;
|
||||
|
||||
case WM_DRAWCLIPBOARD :
|
||||
case WM_DRAWCLIPBOARD:
|
||||
{
|
||||
ClipboardDataInfo clipboardData = getClipboadData();
|
||||
if (clipboardData._data.size())
|
||||
if (_isTrackingClipboardOps)
|
||||
{
|
||||
addToClipboadHistory(clipboardData);
|
||||
ClipboardDataInfo clipboardData = getClipboadData();
|
||||
if (clipboardData._data.size())
|
||||
{
|
||||
addToClipboadHistory(clipboardData);
|
||||
}
|
||||
}
|
||||
if (_hwndNextCbViewer)
|
||||
::SendMessage(_hwndNextCbViewer, message, wParam, lParam);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
case WM_DESTROY:
|
||||
::ChangeClipboardChain(_hSelf, _hwndNextCbViewer);
|
||||
break;
|
||||
|
|
|
@ -77,6 +77,12 @@ public:
|
|||
|
||||
void drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
|
||||
bool trackClipboardOps(bool bTrack) {
|
||||
bool bPreviousState = _isTrackingClipboardOps;
|
||||
_isTrackingClipboardOps = bTrack;
|
||||
return bPreviousState;
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
@ -86,6 +92,6 @@ private:
|
|||
HWND _hwndNextCbViewer = nullptr;
|
||||
int _lbBgColor = -1;
|
||||
int _lbFgColor= -1;
|
||||
|
||||
bool _isTrackingClipboardOps = true; // false when we do not want to track & show some Clipboard operations
|
||||
};
|
||||
|
||||
|
|
|
@ -879,31 +879,39 @@ void EditingSubDlg::changeLineHiliteMode(bool enableSlider)
|
|||
|
||||
bool hasOnlyNumSpaceInClipboard()
|
||||
{
|
||||
int clipFormat;
|
||||
clipFormat = CF_UNICODETEXT;
|
||||
unsigned int clipFormat = CF_UNICODETEXT;
|
||||
|
||||
BOOL canPaste = ::IsClipboardFormatAvailable(clipFormat);
|
||||
if (!canPaste)
|
||||
if (!::IsClipboardFormatAvailable(clipFormat))
|
||||
return false;
|
||||
|
||||
if (!::OpenClipboard(NULL))
|
||||
return false;
|
||||
|
||||
::OpenClipboard(NULL);
|
||||
HANDLE clipboardData = ::GetClipboardData(clipFormat);
|
||||
if (!clipboardData)
|
||||
{
|
||||
::CloseClipboard();
|
||||
return false;
|
||||
}
|
||||
|
||||
::GlobalSize(clipboardData);
|
||||
const wchar_t* clipboardDataPtr = (const wchar_t*)::GlobalLock(clipboardData);
|
||||
if (!clipboardDataPtr) return false;
|
||||
if (!clipboardDataPtr)
|
||||
{
|
||||
::CloseClipboard();
|
||||
return false;
|
||||
}
|
||||
|
||||
wstring clipboardDataString = clipboardDataPtr;
|
||||
|
||||
::GlobalUnlock(clipboardData);
|
||||
::CloseClipboard();
|
||||
|
||||
for (wchar_t c: clipboardDataString)
|
||||
{
|
||||
if (c != ' ' && (c < '0' || c > '9'))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue