#pragma once // https://msdn.microsoft.com/en-us/magazine/mt763237 inline std::wstring Utf8ToUtf16(std::string_view utf8) { if (utf8.empty()) { return {}; } constexpr DWORD kFlags = MB_ERR_INVALID_CHARS; const int utf8Length = static_cast(utf8.length()); const int utf16Length = MultiByteToWideChar( CP_UTF8, kFlags, utf8.data(), utf8Length, nullptr, 0 ); THROW_LAST_ERROR_IF(utf16Length == 0); std::wstring utf16(utf16Length, L'\0'); const int result = MultiByteToWideChar( CP_UTF8, kFlags, utf8.data(), utf8Length, utf16.data(), utf16Length ); THROW_LAST_ERROR_IF(result == 0); return utf16; } inline std::string Utf16ToUtf8(std::wstring_view utf16) { if (utf16.empty()) { return {}; } constexpr DWORD kFlags = WC_ERR_INVALID_CHARS; const int utf16Length = static_cast(utf16.length()); const int utf8Length = WideCharToMultiByte( CP_UTF8, kFlags, utf16.data(), utf16Length, nullptr, 0, nullptr, nullptr ); THROW_LAST_ERROR_IF(utf8Length == 0); std::string utf8(utf8Length, '\0'); const int result = WideCharToMultiByte( CP_UTF8, kFlags, utf16.data(), utf16Length, utf8.data(), utf8Length, nullptr, nullptr ); THROW_LAST_ERROR_IF(result == 0); return utf8; } // https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/author-coclasses#add-helper-types-and-functions // License: see the https://github.com/MicrosoftDocs/windows-uwp/blob/docs/LICENSE-CODE file inline auto GetModuleFsPath(HMODULE hModule) { std::wstring path(MAX_PATH, L'\0'); DWORD actualSize; while (1) { actualSize = GetModuleFileNameW(hModule, path.data(), static_cast(path.size())); if (static_cast(actualSize) + 1 > path.size()) path.resize(path.size() * 2); else break; } path.resize(actualSize); return std::filesystem::path(path); } inline auto GetKnownFolderFsPath(REFKNOWNFOLDERID rfid) { wil::unique_cotaskmem_string path; SHGetKnownFolderPath(rfid, 0, nullptr, &path); return std::filesystem::path(path.get()).concat(L"\\"); } inline void CreateDirectoryIgnoreExist(const wchar_t* path) { if (!CreateDirectoryW(path, nullptr)) { auto lastErr = GetLastError(); if (lastErr != ERROR_ALREADY_EXISTS) THROW_WIN32(lastErr); } } inline void CreateShellLink(const wchar_t* linkPath, const wchar_t* target) { /*auto shellLink = wil::CoCreateInstance(CLSID_ShellLink); THROW_IF_FAILED(shellLink->SetPath(target)); auto persistFile = shellLink.query(); THROW_IF_FAILED(persistFile->Save(linkPath, TRUE));*/ } inline void SetClipboardText(std::wstring_view text,HWND m) { try { THROW_IF_WIN32_BOOL_FALSE(OpenClipboard(m)); THROW_IF_WIN32_BOOL_FALSE(EmptyClipboard()); auto hGlobal = GlobalAlloc(GMEM_MOVEABLE, (text.size() + 1) * sizeof(wchar_t)); THROW_LAST_ERROR_IF_NULL(hGlobal); { wil::unique_hglobal_locked ptr(hGlobal); THROW_LAST_ERROR_IF_NULL(ptr.get()); auto str = static_cast(ptr.get()); auto len = text.copy(str, text.size()); str[len] = 0; } SetClipboardData(CF_UNICODETEXT, hGlobal); } CATCH_LOG(); CloseClipboard(); } inline std::wstring GetClipboardText(HWND m) { std::wstring result; try { if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) return result; THROW_IF_WIN32_BOOL_FALSE(OpenClipboard(m)); auto hGlobal = GetClipboardData(CF_UNICODETEXT); THROW_LAST_ERROR_IF_NULL(hGlobal); wil::unique_hglobal_locked ptr(hGlobal); THROW_LAST_ERROR_IF_NULL(ptr.get()); result = static_cast(ptr.get()); } CATCH_LOG(); CloseClipboard(); return result; } inline bool IsUrlVaild(const wchar_t* urlStr) { try { /*if (*urlStr == 0) return false; skyr::url url{ std::wstring_view(urlStr) }; if (url.empty()) return false; if (url.hostname().empty()) return false; return url.scheme() == "http" || url.scheme() == "https";*/ } CATCH_LOG(); return false; } inline std::wstring GetWindowString(HWND hWnd) { std::wstring str; int len = GetWindowTextLengthW(hWnd); if (len != 0) { str.resize(static_cast(len) + 1); len = GetWindowTextW(hWnd, str.data(), len + 1); str.resize(static_cast(len)); } return str; }