diff options
-rw-r--r-- | include/cru/platform/native/native_window.hpp | 6 | ||||
-rw-r--r-- | include/cru/win/native/native_window.hpp | 2 | ||||
-rw-r--r-- | src/win/native/native_window.cpp | 49 |
3 files changed, 56 insertions, 1 deletions
diff --git a/include/cru/platform/native/native_window.hpp b/include/cru/platform/native/native_window.hpp index d4e608b4..8a067a4c 100644 --- a/include/cru/platform/native/native_window.hpp +++ b/include/cru/platform/native/native_window.hpp @@ -1,9 +1,11 @@ #pragma once #include "../native_resource.hpp" +#include "cru/common/event.hpp" + #include "../graphic_base.hpp" #include "basic_types.hpp" -#include "cru/common/event.hpp" +#include "cursor.hpp" #include "native_event.hpp" namespace cru::platform::graph { @@ -62,6 +64,8 @@ class NativeWindow : public NativeResource { virtual bool CaptureMouse() = 0; virtual bool ReleaseMouse() = 0; + virtual void SetCursor(std::shared_ptr<Cursor> cursor) = 0; + virtual void Repaint() = 0; virtual graph::Painter* BeginPaint() = 0; diff --git a/include/cru/win/native/native_window.hpp b/include/cru/win/native/native_window.hpp index ccbdff40..cba5cc3e 100644 --- a/include/cru/win/native/native_window.hpp +++ b/include/cru/win/native/native_window.hpp @@ -56,6 +56,8 @@ class WinNativeWindow : public NativeWindow { void Repaint() override; graph::Painter* BeginPaint() override; + void SetCursor(std::shared_ptr<Cursor> cursor) override; + IEvent<std::nullptr_t>* DestroyEvent() override { return &destroy_event_; } IEvent<std::nullptr_t>* PaintEvent() override { return &paint_event_; } IEvent<Size>* ResizeEvent() override { return &resize_event_; } diff --git a/src/win/native/native_window.cpp b/src/win/native/native_window.cpp index f301f955..bda84ea9 100644 --- a/src/win/native/native_window.cpp +++ b/src/win/native/native_window.cpp @@ -1,6 +1,9 @@ #include "cru/win/native/native_window.hpp" +#include "cru/common/format.hpp" +#include "cru/platform/debug.hpp" #include "cru/win/graph/direct/graph_factory.hpp" +#include "cru/win/native/cursor.hpp" #include "cru/win/native/exception.hpp" #include "cru/win/native/ui_application.hpp" #include "cru/win/native/window_class.hpp" @@ -160,6 +163,52 @@ graph::Painter* WinNativeWindow::BeginPaint() { return new WindowD2DPainter(this); } +void WinNativeWindow::SetCursor(std::shared_ptr<Cursor> cursor) { + if (!IsValid()) return; + assert(cursor); + WinCursor* c = static_cast<WinCursor*>(cursor.get()); + + auto outputError = [] { + DebugMessage(util::Format(util::Format( + L"Failed to set cursor. Last error code: {}.", ::GetLastError()))); + }; + + if (!::SetWindowLongPtrW(hwnd_, GCLP_HCURSOR, + reinterpret_cast<LONG_PTR>(c->GetHandle()))) { + outputError(); + return; + } + + ::POINT point; + if (!::GetCursorPos(&point)) { + outputError(); + return; + } + + ::RECT rect; + if (!::GetClientRect(hwnd_, &rect)) { + outputError(); + return; + } + + ::POINT lefttop{rect.left, rect.top}; + ::POINT rightbottom{rect.right, rect.bottom}; + if (!::ClientToScreen(hwnd_, &lefttop)) { + outputError(); + return; + } + + if (!::ClientToScreen(hwnd_, &rightbottom)) { + outputError(); + return; + } + + if (point.x >= lefttop.x && point.y >= lefttop.y && + point.x <= rightbottom.x && point.y <= rightbottom.y) { + ::SetCursor(c->GetHandle()); + } +} + bool WinNativeWindow::HandleNativeWindowMessage(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param, LRESULT* result) { |