105 lines
2.6 KiB
C++
105 lines
2.6 KiB
C++
|
|
#include "Platform/Win32/Win32SystemInteractionHost.h"
|
||
|
|
|
||
|
|
#include "Internal/StringEncoding.h"
|
||
|
|
|
||
|
|
#include <windows.h>
|
||
|
|
#include <shellapi.h>
|
||
|
|
|
||
|
|
#include <cstring>
|
||
|
|
|
||
|
|
namespace XCEngine::UI::Editor::Host {
|
||
|
|
|
||
|
|
namespace {
|
||
|
|
|
||
|
|
bool IsPathAvailable(const std::filesystem::path& path) {
|
||
|
|
std::error_code errorCode = {};
|
||
|
|
return !path.empty() &&
|
||
|
|
std::filesystem::exists(path, errorCode) &&
|
||
|
|
!errorCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace
|
||
|
|
|
||
|
|
bool Win32SystemInteractionHost::CopyTextToClipboard(std::string_view text) {
|
||
|
|
if (text.empty()) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::wstring wideText =
|
||
|
|
App::Internal::Utf8ToWide(std::string(text));
|
||
|
|
const std::size_t byteCount =
|
||
|
|
(wideText.size() + 1u) * sizeof(wchar_t);
|
||
|
|
if (!OpenClipboard(nullptr)) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
struct ClipboardCloser final {
|
||
|
|
~ClipboardCloser() {
|
||
|
|
CloseClipboard();
|
||
|
|
}
|
||
|
|
} clipboardCloser = {};
|
||
|
|
|
||
|
|
if (!EmptyClipboard()) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
HGLOBAL handle = GlobalAlloc(GMEM_MOVEABLE, byteCount);
|
||
|
|
if (handle == nullptr) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
void* locked = GlobalLock(handle);
|
||
|
|
if (locked == nullptr) {
|
||
|
|
GlobalFree(handle);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
std::memcpy(locked, wideText.c_str(), byteCount);
|
||
|
|
GlobalUnlock(handle);
|
||
|
|
|
||
|
|
if (SetClipboardData(CF_UNICODETEXT, handle) == nullptr) {
|
||
|
|
GlobalFree(handle);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool Win32SystemInteractionHost::RevealPathInFileBrowser(
|
||
|
|
const std::filesystem::path& path,
|
||
|
|
bool selectTarget) {
|
||
|
|
if (!IsPathAvailable(path)) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
const std::filesystem::path targetPath = path.lexically_normal();
|
||
|
|
HINSTANCE result = nullptr;
|
||
|
|
if (selectTarget) {
|
||
|
|
const std::wstring parameters =
|
||
|
|
L"/select,\"" + targetPath.native() + L"\"";
|
||
|
|
const std::wstring workingDirectory =
|
||
|
|
targetPath.parent_path().native();
|
||
|
|
result = ShellExecuteW(
|
||
|
|
nullptr,
|
||
|
|
L"open",
|
||
|
|
L"explorer.exe",
|
||
|
|
parameters.c_str(),
|
||
|
|
workingDirectory.empty() ? nullptr : workingDirectory.c_str(),
|
||
|
|
SW_SHOWNORMAL);
|
||
|
|
} else {
|
||
|
|
const std::wstring workingDirectory =
|
||
|
|
targetPath.parent_path().native();
|
||
|
|
result = ShellExecuteW(
|
||
|
|
nullptr,
|
||
|
|
L"open",
|
||
|
|
targetPath.c_str(),
|
||
|
|
nullptr,
|
||
|
|
workingDirectory.empty() ? nullptr : workingDirectory.c_str(),
|
||
|
|
SW_SHOWNORMAL);
|
||
|
|
}
|
||
|
|
|
||
|
|
return reinterpret_cast<INT_PTR>(result) > 32;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace XCEngine::UI::Editor::Host
|