Files
FlaxEngine/Source/Engine/Platform/Windows/WindowsClipboard.cpp
2024-02-26 19:00:48 +01:00

169 lines
4.0 KiB
C++

// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#if PLATFORM_WINDOWS
#include "WindowsClipboard.h"
#include "Engine/Core/Collections/Array.h"
#include "../Win32/IncludeWindowsHeaders.h"
typedef struct _DROPFILES
{
DWORD pFiles;
POINT pt;
BOOL fNC;
BOOL fWide;
} DROPFILES, *LPDROPFILES;
void WindowsClipboard::Clear()
{
OpenClipboard(nullptr);
EmptyClipboard();
CloseClipboard();
}
void WindowsClipboard::SetText(const StringView& text)
{
const int32 sizeWithoutNull = text.Length() * sizeof(Char);
const HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, sizeWithoutNull + sizeof(Char));
Char* pMem = static_cast<Char*>(GlobalLock(hMem));
Platform::MemoryCopy(pMem, text.GetText(), sizeWithoutNull);
Platform::MemorySet(pMem + text.Length(), sizeof(Char), 0);
GlobalUnlock(hMem);
OpenClipboard(nullptr);
EmptyClipboard();
SetClipboardData(CF_UNICODETEXT, hMem);
CloseClipboard();
}
void WindowsClipboard::SetRawData(const Span<byte>& data)
{
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, data.Length());
Platform::MemoryCopy(GlobalLock(hMem), data.Get(), data.Length());
GlobalUnlock(hMem);
OpenClipboard(nullptr);
EmptyClipboard();
SetClipboardData(CF_PENDATA, hMem);
CloseClipboard();
}
void WindowsClipboard::SetFiles(const Array<String>& files)
{
int32 size = sizeof(DROPFILES);
for (int32 i = 0; i < files.Count(); i++)
{
size += (files[i].Length() + 1) * sizeof(Char);
}
size += 2 * sizeof(Char);
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, size);
DROPFILES* data = (DROPFILES*)GlobalLock(hMem);
ZeroMemory(data, size);
data->pFiles = sizeof(DROPFILES);
data->fWide = TRUE;
LPWSTR ptr = (LPWSTR)(data + 1);
for (int32 i = 0; i < files.Count(); i++)
{
Platform::MemoryCopy(ptr, files[i].Get(), (files[i].Length() + 1) * sizeof(Char));
ptr += files[i].Length() + 1;
}
*ptr++ = 0;
*ptr = 0;
GlobalUnlock(hMem);
OpenClipboard(nullptr);
EmptyClipboard();
SetClipboardData(CF_HDROP, hMem);
CloseClipboard();
}
String WindowsClipboard::GetText()
{
String result;
OpenClipboard(nullptr);
HANDLE hMem = GetClipboardData(CF_UNICODETEXT);
if (hMem)
{
Char* data = static_cast<Char*>(GlobalLock(hMem));
result = data;
GlobalUnlock(data);
}
else
{
hMem = GetClipboardData(CF_TEXT);
if (hMem)
{
char* data = static_cast<char*>(GlobalLock(hMem));
result = data;
GlobalUnlock(data);
}
}
CloseClipboard();
return result;
}
Array<byte> WindowsClipboard::GetRawData()
{
Array<byte> result;
OpenClipboard(nullptr);
HANDLE hMem = GetClipboardData(CF_PENDATA);
if (hMem)
{
auto data = GlobalLock(hMem);
auto size = static_cast<int32>(GlobalSize(hMem));
if (size > 0)
{
result.Set(static_cast<byte*>(data), size);
}
GlobalUnlock(data);
}
CloseClipboard();
return result;
}
Array<String> WindowsClipboard::GetFiles()
{
Array<String> result;
OpenClipboard(nullptr);
HANDLE hMem = GetClipboardData(CF_HDROP);
if (hMem)
{
auto data = (DROPFILES*)GlobalLock(hMem);
auto size = static_cast<int32>(GlobalSize(hMem));
if (size > 0)
{
if (data->fWide)
{
Char* ptr = (Char*)(data + 1);
while (*ptr)
{
int32 length = StringUtils::Length(ptr);
result.Add(String(ptr, length));
ptr += length + 1;
}
}
else
{
char* ptr = (char*)(data + 1);
while (*ptr)
{
int32 length = StringUtils::Length(ptr);
result.Add(String(ptr, length));
ptr += length + 1;
}
}
}
GlobalUnlock(data);
}
CloseClipboard();
return result;
}
#endif