aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-01-28 22:56:28 +0800
committercrupest <crupest@outlook.com>2022-01-28 22:56:28 +0800
commite7da93f75ba57fa4ab1ae1fd8053266ed09f92d8 (patch)
tree33f5017ebed5227f2066029237a736f53f7adcf9
parentfb992c554110ddd28c18b2cbed79eee8e10cd4a9 (diff)
downloadcru-e7da93f75ba57fa4ab1ae1fd8053266ed09f92d8.tar.gz
cru-e7da93f75ba57fa4ab1ae1fd8053266ed09f92d8.tar.bz2
cru-e7da93f75ba57fa4ab1ae1fd8053266ed09f92d8.zip
...
-rw-r--r--include/cru/common/platform/win/Exception.hpp2
-rw-r--r--include/cru/win/gui/Base.hpp1
-rw-r--r--include/cru/win/gui/Clipboard.hpp24
-rw-r--r--include/cru/win/gui/UiApplication.hpp1
-rw-r--r--src/common/platform/win/Exception.cpp8
-rw-r--r--src/win/gui/CMakeLists.txt4
-rw-r--r--src/win/gui/Clipboard.cpp82
-rw-r--r--src/win/gui/GodWindow.cpp2
-rw-r--r--src/win/gui/UiApplication.cpp8
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