Util.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #pragma once
  2. // https://msdn.microsoft.com/en-us/magazine/mt763237
  3. inline std::wstring Utf8ToUtf16(std::string_view utf8)
  4. {
  5. if (utf8.empty())
  6. {
  7. return {};
  8. }
  9. constexpr DWORD kFlags = MB_ERR_INVALID_CHARS;
  10. const int utf8Length = static_cast<int>(utf8.length());
  11. const int utf16Length = MultiByteToWideChar(
  12. CP_UTF8,
  13. kFlags,
  14. utf8.data(),
  15. utf8Length,
  16. nullptr,
  17. 0
  18. );
  19. THROW_LAST_ERROR_IF(utf16Length == 0);
  20. std::wstring utf16(utf16Length, L'\0');
  21. const int result = MultiByteToWideChar(
  22. CP_UTF8,
  23. kFlags,
  24. utf8.data(),
  25. utf8Length,
  26. utf16.data(),
  27. utf16Length
  28. );
  29. THROW_LAST_ERROR_IF(result == 0);
  30. return utf16;
  31. }
  32. inline std::string Utf16ToUtf8(std::wstring_view utf16)
  33. {
  34. if (utf16.empty())
  35. {
  36. return {};
  37. }
  38. constexpr DWORD kFlags = WC_ERR_INVALID_CHARS;
  39. const int utf16Length = static_cast<int>(utf16.length());
  40. const int utf8Length = WideCharToMultiByte(
  41. CP_UTF8,
  42. kFlags,
  43. utf16.data(),
  44. utf16Length,
  45. nullptr,
  46. 0,
  47. nullptr, nullptr
  48. );
  49. THROW_LAST_ERROR_IF(utf8Length == 0);
  50. std::string utf8(utf8Length, '\0');
  51. const int result = WideCharToMultiByte(
  52. CP_UTF8,
  53. kFlags,
  54. utf16.data(),
  55. utf16Length,
  56. utf8.data(),
  57. utf8Length,
  58. nullptr, nullptr
  59. );
  60. THROW_LAST_ERROR_IF(result == 0);
  61. return utf8;
  62. }
  63. // https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/author-coclasses#add-helper-types-and-functions
  64. // License: see the https://github.com/MicrosoftDocs/windows-uwp/blob/docs/LICENSE-CODE file
  65. inline auto GetModuleFsPath(HMODULE hModule)
  66. {
  67. std::wstring path(MAX_PATH, L'\0');
  68. DWORD actualSize;
  69. while (1)
  70. {
  71. actualSize = GetModuleFileNameW(hModule, path.data(), static_cast<DWORD>(path.size()));
  72. if (static_cast<size_t>(actualSize) + 1 > path.size())
  73. path.resize(path.size() * 2);
  74. else
  75. break;
  76. }
  77. path.resize(actualSize);
  78. return std::filesystem::path(path);
  79. }
  80. inline auto GetKnownFolderFsPath(REFKNOWNFOLDERID rfid)
  81. {
  82. wil::unique_cotaskmem_string path;
  83. SHGetKnownFolderPath(rfid, 0, nullptr, &path);
  84. return std::filesystem::path(path.get()).concat(L"\\");
  85. }
  86. inline void CreateDirectoryIgnoreExist(const wchar_t* path)
  87. {
  88. if (!CreateDirectoryW(path, nullptr))
  89. {
  90. auto lastErr = GetLastError();
  91. if (lastErr != ERROR_ALREADY_EXISTS)
  92. THROW_WIN32(lastErr);
  93. }
  94. }
  95. inline void CreateShellLink(const wchar_t* linkPath, const wchar_t* target)
  96. {
  97. /*auto shellLink = wil::CoCreateInstance<IShellLinkW>(CLSID_ShellLink);
  98. THROW_IF_FAILED(shellLink->SetPath(target));
  99. auto persistFile = shellLink.query<IPersistFile>();
  100. THROW_IF_FAILED(persistFile->Save(linkPath, TRUE));*/
  101. }
  102. inline void SetClipboardText(std::wstring_view text,HWND m)
  103. {
  104. try
  105. {
  106. THROW_IF_WIN32_BOOL_FALSE(OpenClipboard(m));
  107. THROW_IF_WIN32_BOOL_FALSE(EmptyClipboard());
  108. auto hGlobal = GlobalAlloc(GMEM_MOVEABLE, (text.size() + 1) * sizeof(wchar_t));
  109. THROW_LAST_ERROR_IF_NULL(hGlobal);
  110. {
  111. wil::unique_hglobal_locked ptr(hGlobal);
  112. THROW_LAST_ERROR_IF_NULL(ptr.get());
  113. auto str = static_cast<wchar_t*>(ptr.get());
  114. auto len = text.copy(str, text.size());
  115. str[len] = 0;
  116. }
  117. SetClipboardData(CF_UNICODETEXT, hGlobal);
  118. }
  119. CATCH_LOG();
  120. CloseClipboard();
  121. }
  122. inline std::wstring GetClipboardText(HWND m)
  123. {
  124. std::wstring result;
  125. try
  126. {
  127. if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
  128. return result;
  129. THROW_IF_WIN32_BOOL_FALSE(OpenClipboard(m));
  130. auto hGlobal = GetClipboardData(CF_UNICODETEXT);
  131. THROW_LAST_ERROR_IF_NULL(hGlobal);
  132. wil::unique_hglobal_locked ptr(hGlobal);
  133. THROW_LAST_ERROR_IF_NULL(ptr.get());
  134. result = static_cast<wchar_t*>(ptr.get());
  135. }
  136. CATCH_LOG();
  137. CloseClipboard();
  138. return result;
  139. }
  140. inline bool IsUrlVaild(const wchar_t* urlStr)
  141. {
  142. try
  143. {
  144. /*if (*urlStr == 0)
  145. return false;
  146. skyr::url url{ std::wstring_view(urlStr) };
  147. if (url.empty())
  148. return false;
  149. if (url.hostname().empty())
  150. return false;
  151. return url.scheme() == "http" || url.scheme() == "https";*/
  152. }
  153. CATCH_LOG();
  154. return false;
  155. }
  156. inline std::wstring GetWindowString(HWND hWnd)
  157. {
  158. std::wstring str;
  159. int len = GetWindowTextLengthW(hWnd);
  160. if (len != 0)
  161. {
  162. str.resize(static_cast<size_t>(len) + 1);
  163. len = GetWindowTextW(hWnd, str.data(), len + 1);
  164. str.resize(static_cast<size_t>(len));
  165. }
  166. return str;
  167. }