Skip to content

Commit 29a10a4

Browse files
committed
Rework clipboard handling and add SharedUtil::MakeGlobalUnlockGuard
1 parent 44d0fad commit 29a10a4

File tree

4 files changed

+440
-189
lines changed

4 files changed

+440
-189
lines changed

Client/gui/CGUI_Impl.cpp

Lines changed: 134 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "StdInc.h"
1313
#include "GuiCleanup.h"
1414
#include "CEGUIExceptions.h"
15+
#include <SharedUtil.Misc.h>
1516

1617
using std::list;
1718

@@ -813,24 +814,22 @@ bool CGUI_Impl::Event_KeyDown(const CEGUI::EventArgs& Args)
813814
// If we got something to copy
814815
if (strTemp.length() > 0)
815816
{
816-
// Convert it to Unicode
817-
std::wstring strUTF = MbUTF8ToUTF16(strTemp.c_str());
818-
819-
// Open and empty the clipboard
820-
OpenClipboard(NULL);
821-
EmptyClipboard();
822-
823-
// Allocate the clipboard buffer and copy the data
824-
HGLOBAL hBuf = GlobalAlloc(GMEM_DDESHARE, strUTF.length() * sizeof(wchar_t) + sizeof(wchar_t));
825-
wchar_t* buf = reinterpret_cast<wchar_t*>(GlobalLock(hBuf));
826-
wcscpy(buf, strUTF.c_str());
827-
GlobalUnlock(hBuf);
828-
829-
// Copy the data into the clipboard
830-
SetClipboardData(CF_UNICODETEXT, hBuf);
817+
SString clipboardText;
818+
try
819+
{
820+
clipboardText = UTF16ToMbUTF8(MbUTF8ToUTF16(strTemp.c_str()));
821+
}
822+
catch (const std::exception&)
823+
{
824+
clipboardText.clear();
825+
}
826+
catch (...)
827+
{
828+
clipboardText.clear();
829+
}
831830

832-
// Close the clipboard
833-
CloseClipboard();
831+
if (!clipboardText.empty())
832+
SharedUtil::SetClipboardText(clipboardText);
834833
}
835834
}
836835

@@ -845,158 +844,150 @@ bool CGUI_Impl::Event_KeyDown(const CEGUI::EventArgs& Args)
845844
CEGUI::Window* Wnd = reinterpret_cast<CEGUI::Window*>(KeyboardArgs.window);
846845
if (Wnd->getType() == "CGUI/Editbox" || Wnd->getType() == "CGUI/MultiLineEditbox")
847846
{
848-
// Open the clipboard
849-
OpenClipboard(NULL);
847+
SString clipboardUtf8 = SharedUtil::GetClipboardText();
848+
std::wstring strClipboardText;
849+
try
850+
{
851+
strClipboardText = MbUTF8ToUTF16(clipboardUtf8);
852+
}
853+
catch (const std::exception&)
854+
{
855+
strClipboardText.clear();
856+
}
857+
catch (...)
858+
{
859+
strClipboardText.clear();
860+
}
850861

851-
// Get the clipboard's data and lock it
852-
HANDLE hClipData = GetClipboardData(CF_UNICODETEXT);
853-
const wchar_t* ClipboardBuffer = nullptr;
854-
if (hClipData)
855-
ClipboardBuffer = static_cast<const wchar_t*>(GlobalLock(hClipData));
862+
if (clipboardUtf8.empty() && strClipboardText.empty())
863+
break;
856864

857-
// Check to make sure we have valid data.
858-
if (ClipboardBuffer)
859-
{
860-
size_t iSelectionStart, iSelectionLength, iMaxLength, iCaratIndex;
861-
CEGUI::String strEditText;
862-
bool bReplaceNewLines = true;
863-
bool bIsBoxFull = false;
865+
size_t iSelectionStart, iSelectionLength, iMaxLength, iCaratIndex;
866+
CEGUI::String strEditText;
867+
bool bReplaceNewLines = true;
868+
bool bIsBoxFull = false;
864869

865-
if (Wnd->getType() == "CGUI/Editbox")
870+
if (Wnd->getType() == "CGUI/Editbox")
871+
{
872+
// Turn our event window into an editbox
873+
CEGUI::Editbox* WndEdit = reinterpret_cast<CEGUI::Editbox*>(Wnd);
874+
// Don't paste if we're read only
875+
if (WndEdit->isReadOnly())
866876
{
867-
// Turn our event window into an editbox
868-
CEGUI::Editbox* WndEdit = reinterpret_cast<CEGUI::Editbox*>(Wnd);
869-
// Don't paste if we're read only
870-
if (WndEdit->isReadOnly())
871-
{
872-
if (hClipData)
873-
GlobalUnlock(hClipData);
874-
CloseClipboard();
875-
return true;
876-
}
877-
strEditText = WndEdit->getText();
878-
iSelectionStart = WndEdit->getSelectionStartIndex();
879-
iSelectionLength = WndEdit->getSelectionLength();
880-
iMaxLength = WndEdit->getMaxTextLength();
881-
iCaratIndex = WndEdit->getCaratIndex();
877+
return true;
882878
}
883-
else
879+
strEditText = WndEdit->getText();
880+
iSelectionStart = WndEdit->getSelectionStartIndex();
881+
iSelectionLength = WndEdit->getSelectionLength();
882+
iMaxLength = WndEdit->getMaxTextLength();
883+
iCaratIndex = WndEdit->getCaratIndex();
884+
}
885+
else
886+
{
887+
CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast<CEGUI::MultiLineEditbox*>(Wnd);
888+
// Don't paste if we're read only
889+
if (WndEdit->isReadOnly())
884890
{
885-
CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast<CEGUI::MultiLineEditbox*>(Wnd);
886-
// Don't paste if we're read only
887-
if (WndEdit->isReadOnly())
888-
{
889-
if (hClipData)
890-
GlobalUnlock(hClipData);
891-
CloseClipboard();
892-
return true;
893-
}
894-
895-
strEditText = WndEdit->getText();
896-
iSelectionStart = WndEdit->getSelectionStartIndex();
897-
iSelectionLength = WndEdit->getSelectionLength();
898-
iMaxLength = WndEdit->getMaxTextLength();
899-
iCaratIndex = WndEdit->getCaratIndex();
900-
bReplaceNewLines = false;
901-
902-
// Plus one character, because there is always an extra '\n' in
903-
// MultiLineEditbox's text data and it causes MaxLength limit to
904-
// be exceeded during pasting the text
905-
iMaxLength += 1;
891+
return true;
906892
}
907893

908-
std::wstring strClipboardText = ClipboardBuffer;
909-
size_t iNewlineIndex;
894+
strEditText = WndEdit->getText();
895+
iSelectionStart = WndEdit->getSelectionStartIndex();
896+
iSelectionLength = WndEdit->getSelectionLength();
897+
iMaxLength = WndEdit->getMaxTextLength();
898+
iCaratIndex = WndEdit->getCaratIndex();
899+
bReplaceNewLines = false;
900+
901+
// Plus one character, because there is always an extra '\n' in
902+
// MultiLineEditbox's text data and it causes MaxLength limit to
903+
// be exceeded during pasting the text
904+
iMaxLength += 1;
905+
}
906+
907+
size_t iNewlineIndex;
910908

911-
// Remove the newlines inserting spaces instead
912-
if (bReplaceNewLines)
909+
// Remove the newlines inserting spaces instead
910+
if (bReplaceNewLines)
911+
{
912+
do
913913
{
914-
do
914+
iNewlineIndex = strClipboardText.find('\n');
915+
if (iNewlineIndex != SString::npos)
915916
{
916-
iNewlineIndex = strClipboardText.find('\n');
917-
if (iNewlineIndex != SString::npos)
917+
if (iNewlineIndex > 0 && strClipboardText[iNewlineIndex - 1] == '\r')
918918
{
919-
if (iNewlineIndex > 0 && strClipboardText[iNewlineIndex - 1] == '\r')
920-
{
921-
// \r\n
922-
strClipboardText[iNewlineIndex - 1] = ' ';
923-
strClipboardText.replace(iNewlineIndex, strClipboardText.length() - iNewlineIndex, strClipboardText.c_str(),
924-
iNewlineIndex + 1, strClipboardText.length() - iNewlineIndex - 1);
925-
}
926-
else
927-
{
928-
strClipboardText[iNewlineIndex] = ' ';
929-
}
919+
// \r\n
920+
strClipboardText[iNewlineIndex - 1] = ' ';
921+
strClipboardText.replace(iNewlineIndex, strClipboardText.length() - iNewlineIndex, strClipboardText.c_str(),
922+
iNewlineIndex + 1, strClipboardText.length() - iNewlineIndex - 1);
930923
}
931-
} while (iNewlineIndex != SString::npos);
932-
}
924+
else
925+
{
926+
strClipboardText[iNewlineIndex] = ' ';
927+
}
928+
}
929+
} while (iNewlineIndex != SString::npos);
930+
}
933931

934-
// Put the editbox's data into a string and insert the data if it has not reached it's maximum text length
935-
std::wstring tmp = MbUTF8ToUTF16(strEditText.c_str());
936-
if ((strClipboardText.length() + tmp.length() - iSelectionLength) <= iMaxLength)
932+
// Put the editbox's data into a string and insert the data if it has not reached it's maximum text length
933+
std::wstring tmp = MbUTF8ToUTF16(strEditText.c_str());
934+
if ((strClipboardText.length() + tmp.length() - iSelectionLength) <= iMaxLength)
935+
{
936+
// Are there characters selected?
937+
size_t sizeCaratIndex = 0;
938+
if (iSelectionLength > 0)
937939
{
938-
// Are there characters selected?
939-
size_t sizeCaratIndex = 0;
940-
if (iSelectionLength > 0)
941-
{
942-
// Replace what's selected with the pasted buffer and set the new carat index
943-
tmp.replace(iSelectionStart, iSelectionLength, strClipboardText.c_str(), strClipboardText.length());
944-
sizeCaratIndex = iSelectionStart + strClipboardText.length();
945-
}
946-
else
947-
{
948-
// If not, insert the clipboard buffer where we were and set the new carat index
949-
tmp.insert(iSelectionStart, strClipboardText.c_str(), strClipboardText.length());
950-
sizeCaratIndex = iCaratIndex + strClipboardText.length();
951-
}
940+
// Replace what's selected with the pasted buffer and set the new carat index
941+
tmp.replace(iSelectionStart, iSelectionLength, strClipboardText.c_str(), strClipboardText.length());
942+
sizeCaratIndex = iSelectionStart + strClipboardText.length();
943+
}
944+
else
945+
{
946+
// If not, insert the clipboard buffer where we were and set the new carat index
947+
tmp.insert(iSelectionStart, strClipboardText.c_str(), strClipboardText.length());
948+
sizeCaratIndex = iCaratIndex + strClipboardText.length();
949+
}
952950

953-
// Set the new text and move the carat at the end of what we pasted
954-
CEGUI::String strText((CEGUI::utf8*)UTF16ToMbUTF8(tmp).c_str());
955-
strEditText = strText;
956-
iCaratIndex = sizeCaratIndex;
951+
// Set the new text and move the carat at the end of what we pasted
952+
CEGUI::String strText((CEGUI::utf8*)UTF16ToMbUTF8(tmp).c_str());
953+
strEditText = strText;
954+
iCaratIndex = sizeCaratIndex;
955+
}
956+
else
957+
{
958+
bIsBoxFull = true;
959+
}
960+
if (bIsBoxFull)
961+
{
962+
// Fire an event if the editbox is full
963+
if (Wnd->getType() == "CGUI/Editbox")
964+
{
965+
CEGUI::Editbox* WndEdit = reinterpret_cast<CEGUI::Editbox*>(Wnd);
966+
CEGUI::WindowEventArgs args(WndEdit);
967+
WndEdit->fireEvent(CEGUI::Editbox::EventEditboxFull, args);
957968
}
958969
else
959970
{
960-
bIsBoxFull = true;
971+
CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast<CEGUI::MultiLineEditbox*>(Wnd);
972+
CEGUI::WindowEventArgs args(WndEdit);
973+
WndEdit->fireEvent(CEGUI::Editbox::EventEditboxFull, args);
961974
}
962-
if (bIsBoxFull)
975+
}
976+
else
977+
{
978+
if (Wnd->getType() == "CGUI/Editbox")
963979
{
964-
// Fire an event if the editbox is full
965-
if (Wnd->getType() == "CGUI/Editbox")
966-
{
967-
CEGUI::Editbox* WndEdit = reinterpret_cast<CEGUI::Editbox*>(Wnd);
968-
CEGUI::WindowEventArgs args(WndEdit);
969-
WndEdit->fireEvent(CEGUI::Editbox::EventEditboxFull, args);
970-
}
971-
else
972-
{
973-
CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast<CEGUI::MultiLineEditbox*>(Wnd);
974-
CEGUI::WindowEventArgs args(WndEdit);
975-
WndEdit->fireEvent(CEGUI::Editbox::EventEditboxFull, args);
976-
}
980+
CEGUI::Editbox* WndEdit = reinterpret_cast<CEGUI::Editbox*>(Wnd);
981+
WndEdit->setText(strEditText);
982+
WndEdit->setCaratIndex(iCaratIndex);
977983
}
978984
else
979985
{
980-
if (Wnd->getType() == "CGUI/Editbox")
981-
{
982-
CEGUI::Editbox* WndEdit = reinterpret_cast<CEGUI::Editbox*>(Wnd);
983-
WndEdit->setText(strEditText);
984-
WndEdit->setCaratIndex(iCaratIndex);
985-
}
986-
else
987-
{
988-
CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast<CEGUI::MultiLineEditbox*>(Wnd);
989-
WndEdit->setText(strEditText);
990-
WndEdit->setCaratIndex(iCaratIndex);
991-
}
986+
CEGUI::MultiLineEditbox* WndEdit = reinterpret_cast<CEGUI::MultiLineEditbox*>(Wnd);
987+
WndEdit->setText(strEditText);
988+
WndEdit->setCaratIndex(iCaratIndex);
992989
}
993990
}
994-
995-
if (hClipData)
996-
GlobalUnlock(hClipData);
997-
998-
// Close the clipboard
999-
CloseClipboard();
1000991
}
1001992
}
1002993

Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <game/CWeapon.h>
2828
#include <game/CWeaponStat.h>
2929
#include <game/CWeaponStatManager.h>
30+
#include <SharedUtil.Misc.h>
3031
#include <game/CBuildingRemoval.h>
3132
#include <game/TaskBasic.h>
3233
#include <enums/VehicleType.h>
@@ -288,23 +289,7 @@ bool CStaticFunctionDefinitions::OutputChatBox(const char* szText, unsigned char
288289

289290
bool CStaticFunctionDefinitions::SetClipboard(SString& strText)
290291
{
291-
std::wstring strUTF = MbUTF8ToUTF16(strText);
292-
293-
// Open and empty the clipboard
294-
OpenClipboard(NULL);
295-
EmptyClipboard();
296-
297-
// Allocate the clipboard buffer and copy the data
298-
HGLOBAL hBuf = GlobalAlloc(GMEM_DDESHARE, strUTF.length() * sizeof(wchar_t) + sizeof(wchar_t));
299-
wchar_t* buf = reinterpret_cast<wchar_t*>(GlobalLock(hBuf));
300-
wcscpy(buf, strUTF.c_str());
301-
GlobalUnlock(hBuf);
302-
303-
// Copy the data into the clipboard
304-
SetClipboardData(CF_UNICODETEXT, hBuf);
305-
306-
// Close the clipboard
307-
CloseClipboard();
292+
SharedUtil::SetClipboardText(strText);
308293
return true;
309294
}
310295

0 commit comments

Comments
 (0)