Collection of DPF-based plugins for packaging
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
5.4KB

  1. //
  2. // ██████ ██  ██  ██████  ██████
  3. // ██      ██  ██ ██    ██ ██       ** Classy Header-Only Classes **
  4. // ██  ███████ ██  ██ ██
  5. // ██  ██   ██ ██  ██ ██ https://github.com/Tracktion/choc
  6. //  ██████ ██  ██  ██████   ██████
  7. //
  8. // CHOC is (C)2022 Tracktion Corporation, and is offered under the terms of the ISC license:
  9. //
  10. // Permission to use, copy, modify, and/or distribute this software for any purpose with or
  11. // without fee is hereby granted, provided that the above copyright notice and this permission
  12. // notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  13. // WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  14. // AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  15. // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  16. // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  17. // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18. #ifndef CHOC_DESKTOPWINDOW_HEADER_INCLUDED
  19. #define CHOC_DESKTOPWINDOW_HEADER_INCLUDED
  20. #include "choc_Platform.h"
  21. //==============================================================================
  22. // _ _ _ _
  23. // __| | ___ | |_ __ _ (_)| | ___
  24. // / _` | / _ \| __| / _` || || |/ __|
  25. // | (_| || __/| |_ | (_| || || |\__ \ _ _ _
  26. // \__,_| \___| \__| \__,_||_||_||___/(_)(_)(_)
  27. //
  28. // Code beyond this point is implementation detail...
  29. //
  30. //==============================================================================
  31. #undef WIN32_LEAN_AND_MEAN
  32. #define WIN32_LEAN_AND_MEAN
  33. #undef NOMINMAX
  34. #define NOMINMAX
  35. #define Rectangle Rectangle_renamed_to_avoid_name_collisions
  36. #include <windows.h>
  37. #undef Rectangle
  38. START_NAMESPACE_DISTRHO
  39. struct HWNDHolder
  40. {
  41. HWNDHolder() = default;
  42. HWNDHolder (HWND h) : hwnd (h) {}
  43. HWNDHolder (const HWNDHolder&) = delete;
  44. HWNDHolder& operator= (const HWNDHolder&) = delete;
  45. HWNDHolder (HWNDHolder&& other) : hwnd (other.hwnd) { other.hwnd = {}; }
  46. HWNDHolder& operator= (HWNDHolder&& other) { reset(); hwnd = other.hwnd; other.hwnd = {}; return *this; }
  47. ~HWNDHolder() { reset(); }
  48. operator HWND() const { return hwnd; }
  49. operator void*() const { return (void*) hwnd; }
  50. void reset() { if (IsWindow (hwnd)) DestroyWindow (hwnd); hwnd = {}; }
  51. HWND hwnd = {};
  52. };
  53. struct WindowClass
  54. {
  55. WindowClass (std::wstring name, WNDPROC wndProc)
  56. {
  57. name += std::to_wstring (static_cast<uint32_t> (GetTickCount()));
  58. moduleHandle = GetModuleHandle (nullptr);
  59. auto icon = (HICON) LoadImage (moduleHandle, IDI_APPLICATION, IMAGE_ICON,
  60. GetSystemMetrics (SM_CXSMICON),
  61. GetSystemMetrics (SM_CYSMICON),
  62. LR_DEFAULTCOLOR);
  63. WNDCLASSEXW wc;
  64. ZeroMemory (&wc, sizeof(wc));
  65. wc.cbSize = sizeof(wc);
  66. wc.style = CS_OWNDC;
  67. wc.hInstance = moduleHandle;
  68. wc.lpszClassName = name.c_str();
  69. wc.hIcon = icon;
  70. wc.hIconSm = icon;
  71. wc.lpfnWndProc = wndProc;
  72. classAtom = (LPCWSTR) (uintptr_t) RegisterClassExW (&wc);
  73. DISTRHO_SAFE_ASSERT (classAtom != 0);
  74. }
  75. ~WindowClass()
  76. {
  77. UnregisterClassW (classAtom, moduleHandle);
  78. }
  79. HWNDHolder createWindow (DWORD style, int w, int h, void* userData)
  80. {
  81. if (auto hwnd = CreateWindowW (classAtom, L"", style, CW_USEDEFAULT, CW_USEDEFAULT,
  82. w, h, nullptr, nullptr, moduleHandle, nullptr))
  83. {
  84. SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) userData);
  85. return hwnd;
  86. }
  87. return {};
  88. }
  89. auto getClassName() const { return classAtom; }
  90. HINSTANCE moduleHandle = {};
  91. LPCWSTR classAtom = {};
  92. };
  93. static std::string createUTF8FromUTF16 (const std::wstring& utf16)
  94. {
  95. if (! utf16.empty())
  96. {
  97. auto numWideChars = static_cast<int> (utf16.size());
  98. auto resultSize = WideCharToMultiByte (CP_UTF8, WC_ERR_INVALID_CHARS, utf16.data(), numWideChars, nullptr, 0, nullptr, nullptr);
  99. if (resultSize > 0)
  100. {
  101. std::string result;
  102. result.resize (static_cast<size_t> (resultSize));
  103. if (WideCharToMultiByte (CP_UTF8, WC_ERR_INVALID_CHARS, utf16.data(), numWideChars, result.data(), resultSize, nullptr, nullptr) > 0)
  104. return result;
  105. }
  106. }
  107. return {};
  108. }
  109. static std::wstring createUTF16StringFromUTF8 (std::string_view utf8)
  110. {
  111. if (! utf8.empty())
  112. {
  113. auto numUTF8Bytes = static_cast<int> (utf8.size());
  114. auto resultSize = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, utf8.data(), numUTF8Bytes, nullptr, 0);
  115. if (resultSize > 0)
  116. {
  117. std::wstring result;
  118. result.resize (static_cast<size_t> (resultSize));
  119. if (MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, utf8.data(), numUTF8Bytes, result.data(), resultSize) > 0)
  120. return result;
  121. }
  122. }
  123. return {};
  124. }
  125. END_NAMESPACE_DISTRHO
  126. #endif // CHOC_DESKTOPWINDOW_HEADER_INCLUDED