diff options
author | crupest <crupest@outlook.com> | 2022-01-28 22:56:28 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-01-28 22:56:28 +0800 |
commit | e7da93f75ba57fa4ab1ae1fd8053266ed09f92d8 (patch) | |
tree | 33f5017ebed5227f2066029237a736f53f7adcf9 | |
parent | fb992c554110ddd28c18b2cbed79eee8e10cd4a9 (diff) | |
download | cru-e7da93f75ba57fa4ab1ae1fd8053266ed09f92d8.tar.gz cru-e7da93f75ba57fa4ab1ae1fd8053266ed09f92d8.tar.bz2 cru-e7da93f75ba57fa4ab1ae1fd8053266ed09f92d8.zip |
...
-rw-r--r-- | include/cru/common/platform/win/Exception.hpp | 2 | ||||
-rw-r--r-- | include/cru/win/gui/Base.hpp | 1 | ||||
-rw-r--r-- | include/cru/win/gui/Clipboard.hpp | 24 | ||||
-rw-r--r-- | include/cru/win/gui/UiApplication.hpp | 1 | ||||
-rw-r--r-- | src/common/platform/win/Exception.cpp | 8 | ||||
-rw-r--r-- | src/win/gui/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/win/gui/Clipboard.cpp | 82 | ||||
-rw-r--r-- | src/win/gui/GodWindow.cpp | 2 | ||||
-rw-r--r-- | src/win/gui/UiApplication.cpp | 8 |
9 files changed, 114 insertions, 18 deletions
diff --git a/include/cru/common/platform/win/Exception.hpp b/include/cru/common/platform/win/Exception.hpp index 0774327f..4e332b4f 100644 --- a/include/cru/common/platform/win/Exception.hpp +++ b/include/cru/common/platform/win/Exception.hpp @@ -38,9 +38,7 @@ class CRU_BASE_API Win32Error : public platform::PlatformException { public: // ::GetLastError is automatically called to get the error code. // The same as Win32Error(::GetLastError(), message) - [[deprecated]] explicit Win32Error(std::string_view message); explicit Win32Error(String message); - [[deprecated]] Win32Error(DWORD error_code, std::string_view message); Win32Error(DWORD error_code, String message); CRU_DEFAULT_COPY(Win32Error) diff --git a/include/cru/win/gui/Base.hpp b/include/cru/win/gui/Base.hpp index e6807710..2a0d0247 100644 --- a/include/cru/win/gui/Base.hpp +++ b/include/cru/win/gui/Base.hpp @@ -23,4 +23,5 @@ class WindowManager; class WinNativeWindow; class WinUiApplication; class WinInputMethodContext; +class WinClipboard; } // namespace cru::platform::gui::win diff --git a/include/cru/win/gui/Clipboard.hpp b/include/cru/win/gui/Clipboard.hpp new file mode 100644 index 00000000..63d4906a --- /dev/null +++ b/include/cru/win/gui/Clipboard.hpp @@ -0,0 +1,24 @@ +#pragma once +#include "Resource.hpp" +#include "cru/common/Base.hpp" +#include "cru/platform/gui/Clipboard.hpp" +#include "cru/win/gui/Base.hpp" + +namespace cru::platform::gui::win { +class WinClipboard : public WinNativeResource, public virtual IClipboard { + public: + explicit WinClipboard(WinUiApplication* application); + + CRU_DELETE_COPY(WinClipboard) + CRU_DELETE_MOVE(WinClipboard) + + ~WinClipboard() override; + + public: + String GetText() override; + void SetText(String text) override; + + private: + WinUiApplication* application_; +}; +} // namespace cru::platform::gui::win diff --git a/include/cru/win/gui/UiApplication.hpp b/include/cru/win/gui/UiApplication.hpp index a13dc932..1280e7a6 100644 --- a/include/cru/win/gui/UiApplication.hpp +++ b/include/cru/win/gui/UiApplication.hpp @@ -80,6 +80,7 @@ class CRU_WIN_GUI_API WinUiApplication : public WinNativeResource, std::unique_ptr<WindowManager> window_manager_; std::unique_ptr<WinCursorManager> cursor_manager_; + std::unique_ptr<WinClipboard> clipboard_; std::vector<std::function<void()>> quit_handlers_; }; diff --git a/src/common/platform/win/Exception.cpp b/src/common/platform/win/Exception.cpp index def12123..70cfcb3c 100644 --- a/src/common/platform/win/Exception.cpp +++ b/src/common/platform/win/Exception.cpp @@ -29,17 +29,9 @@ inline String Win32MakeMessage(DWORD error_code, String message) { message.WinCStr()); } -Win32Error::Win32Error(std::string_view message) - : Win32Error(::GetLastError(), message) {} - Win32Error::Win32Error(String message) : Win32Error(::GetLastError(), message) {} -Win32Error::Win32Error(DWORD error_code, std::string_view message) - : PlatformException(Win32MakeMessage( - error_code, String::FromUtf8(message.data(), message.size()))), - error_code_(error_code) {} - Win32Error::Win32Error(DWORD error_code, String message) : PlatformException(Win32MakeMessage(error_code, message)), error_code_(error_code) {} diff --git a/src/win/gui/CMakeLists.txt b/src/win/gui/CMakeLists.txt index b9d2862f..9e26f190 100644 --- a/src/win/gui/CMakeLists.txt +++ b/src/win/gui/CMakeLists.txt @@ -1,7 +1,5 @@ add_library(cru_win_gui SHARED - TimerManager.hpp - WindowManager.hpp - + Clipboard.cpp Cursor.cpp GodWindow.cpp InputMethod.cpp diff --git a/src/win/gui/Clipboard.cpp b/src/win/gui/Clipboard.cpp new file mode 100644 index 00000000..62db4ed8 --- /dev/null +++ b/src/win/gui/Clipboard.cpp @@ -0,0 +1,82 @@ +#include "cru/win/gui/Clipboard.hpp" +#include <winuser.h> +#include "cru/common/Logger.hpp" +#include "cru/win/gui/GodWindow.hpp" +#include "cru/win/gui/UiApplication.hpp" + +namespace cru::platform::gui::win { +WinClipboard::WinClipboard(WinUiApplication* application) + : application_(application) {} + +WinClipboard::~WinClipboard() {} + +String WinClipboard::GetText() { + auto god_window = application_->GetGodWindow(); + + if (!::OpenClipboard(god_window->GetHandle())) { + log::Warn(u"Failed to open clipboard."); + return {}; + } + + if (!::IsClipboardFormatAvailable(CF_UNICODETEXT)) { + log::Warn(u"Clipboard format for text is not available."); + return {}; + } + + auto handle = ::GetClipboardData(CF_UNICODETEXT); + + if (handle == nullptr) { + log::Warn(u"Failed to get clipboard data."); + return {}; + } + + auto ptr = ::GlobalLock(handle); + if (ptr == nullptr) { + log::Warn(u"Failed to lock clipboard data."); + ::CloseClipboard(); + return {}; + } + + String result(static_cast<wchar_t*>(ptr)); + + ::GlobalUnlock(handle); + ::CloseClipboard(); + + return result; +} + +void WinClipboard::SetText(String text) { + auto god_window = application_->GetGodWindow(); + + if (!::OpenClipboard(god_window->GetHandle())) { + log::Warn(u"Failed to open clipboard."); + return; + } + + auto handle = GlobalAlloc(GMEM_MOVEABLE, (text.size() + 1) * sizeof(wchar_t)); + + if (handle == nullptr) { + log::Warn(u"Failed to allocate clipboard data."); + ::CloseClipboard(); + return; + } + + auto ptr = ::GlobalLock(handle); + if (ptr == nullptr) { + log::Warn(u"Failed to lock clipboard data."); + ::GlobalFree(handle); + ::CloseClipboard(); + return; + } + + std::memcpy(ptr, text.c_str(), (text.size() + 1) * sizeof(wchar_t)); + + ::GlobalUnlock(handle); + + if (::SetClipboardData(CF_UNICODETEXT, handle) == nullptr) { + log::Warn(u"Failed to set clipboard data."); + } + + ::CloseClipboard(); +} +} // namespace cru::platform::gui::win diff --git a/src/win/gui/GodWindow.cpp b/src/win/gui/GodWindow.cpp index 7bce83a3..31974339 100644 --- a/src/win/gui/GodWindow.cpp +++ b/src/win/gui/GodWindow.cpp @@ -37,7 +37,7 @@ GodWindow::GodWindow(WinUiApplication* application) { HWND_MESSAGE, nullptr, h_instance, nullptr); if (hwnd_ == nullptr) - throw Win32Error(::GetLastError(), "Failed to create god window."); + throw Win32Error(::GetLastError(), u"Failed to create god window."); } GodWindow::~GodWindow() { diff --git a/src/win/gui/UiApplication.cpp b/src/win/gui/UiApplication.cpp index dadcfc75..6cacc8b2 100644 --- a/src/win/gui/UiApplication.cpp +++ b/src/win/gui/UiApplication.cpp @@ -7,6 +7,8 @@ #include "cru/win/DebugLogger.hpp" #include "cru/win/StdOutLogger.hpp" #include "cru/win/graphics/direct/Factory.hpp" +#include "cru/win/gui/Base.hpp" +#include "cru/win/gui/Clipboard.hpp" #include "cru/win/gui/Cursor.hpp" #include "cru/win/gui/Exception.hpp" #include "cru/win/gui/GodWindow.hpp" @@ -43,6 +45,7 @@ WinUiApplication::WinUiApplication() { timer_manager_ = std::make_unique<TimerManager>(god_window_.get()); window_manager_ = std::make_unique<WindowManager>(this); cursor_manager_ = std::make_unique<WinCursorManager>(); + clipboard_ = std::make_unique<WinClipboard>(this); } WinUiApplication::~WinUiApplication() { instance = nullptr; } @@ -112,9 +115,6 @@ ICursorManager* WinUiApplication::GetCursorManager() { return cursor_manager_.get(); } -IClipboard* WinUiApplication::GetClipboard() { - // TODO: Implement this. - return nullptr; -} +IClipboard* WinUiApplication::GetClipboard() { return clipboard_.get(); } } // namespace cru::platform::gui::win |