aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/common/logger.hpp5
-rw-r--r--include/cru/platform/native/cursor.hpp6
-rw-r--r--include/cru/platform/native/event.hpp (renamed from include/cru/platform/native/native_event.hpp)3
-rw-r--r--include/cru/platform/native/ui_application.hpp21
-rw-r--r--include/cru/platform/native/window.hpp (renamed from include/cru/platform/native/native_window.hpp)11
-rw-r--r--include/cru/win/graph/direct/factory.hpp3
-rw-r--r--include/cru/win/native/cursor.hpp26
-rw-r--r--include/cru/win/native/god_window.hpp12
-rw-r--r--include/cru/win/native/resource.hpp23
-rw-r--r--include/cru/win/native/ui_application.hpp55
-rw-r--r--include/cru/win/native/window.hpp (renamed from include/cru/win/native/native_window.hpp)38
-rw-r--r--include/cru/win/native/window_class.hpp13
-rw-r--r--include/cru/win/native/window_native_message_event_args.hpp11
-rw-r--r--include/cru/win/native/window_render_target.hpp17
-rw-r--r--src/platform/native/CMakeLists.txt4
-rw-r--r--src/win/debug_logger.hpp4
-rw-r--r--src/win/graph/direct/factory.cpp3
-rw-r--r--src/win/native/CMakeLists.txt5
-rw-r--r--src/win/native/cursor.cpp20
-rw-r--r--src/win/native/dpi_util.hpp1
-rw-r--r--src/win/native/god_window.cpp10
-rw-r--r--src/win/native/timer.hpp10
-rw-r--r--src/win/native/ui_application.cpp72
-rw-r--r--src/win/native/window.cpp (renamed from src/win/native/native_window.cpp)74
-rw-r--r--src/win/native/window_class.cpp6
-rw-r--r--src/win/native/window_d2d_painter.cpp8
-rw-r--r--src/win/native/window_d2d_painter.hpp10
-rw-r--r--src/win/native/window_manager.cpp6
-rw-r--r--src/win/native/window_manager.hpp17
-rw-r--r--src/win/native/window_render_target.cpp11
30 files changed, 261 insertions, 244 deletions
diff --git a/include/cru/common/logger.hpp b/include/cru/common/logger.hpp
index 08765499..61d97422 100644
--- a/include/cru/common/logger.hpp
+++ b/include/cru/common/logger.hpp
@@ -28,6 +28,11 @@ class StdioLogSource : public virtual ILogSource {
~StdioLogSource() override = default;
void Write(LogLevel level, const std::string_view& s) override {
+ // TODO: Emmm... Since it is buggy to use narrow char in UTF-8 on Windows. I
+ // think this implementation might be broken. (However, I didn't test it.)
+ // Maybe, I should detect Windows and use wide char (And I didn't test this
+ // either) or other more complicated implementation. Currently, I settled
+ // with this.
if (level == LogLevel::Error) {
std::cerr << s;
} else {
diff --git a/include/cru/platform/native/cursor.hpp b/include/cru/platform/native/cursor.hpp
index 961dff34..cb8b7ed2 100644
--- a/include/cru/platform/native/cursor.hpp
+++ b/include/cru/platform/native/cursor.hpp
@@ -1,18 +1,18 @@
#pragma once
-#include "../native_resource.hpp"
+#include "../resource.hpp"
#include <memory>
namespace cru::platform::native {
-struct ICursor : public virtual INativeResource {};
+struct ICursor : virtual INativeResource {};
enum class SystemCursorType {
Arrow,
Hand,
};
-struct ICursorManager : public virtual INativeResource {
+struct ICursorManager : virtual INativeResource {
virtual std::shared_ptr<ICursor> GetSystemCursor(SystemCursorType type) = 0;
// TODO: Add method to create cursor.
diff --git a/include/cru/platform/native/native_event.hpp b/include/cru/platform/native/event.hpp
index dcd7a336..48e9cfca 100644
--- a/include/cru/platform/native/native_event.hpp
+++ b/include/cru/platform/native/event.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "../graphic_base.hpp"
+#include "../graph_base.hpp"
#include "basic_types.hpp"
namespace cru::platform::native {
@@ -12,5 +12,4 @@ struct NativeMouseButtonEventArgs {
enum class FocusChangeType { Gain, Lost };
enum class MouseEnterLeaveType { Enter, Leave };
-
} // namespace cru::platform::native
diff --git a/include/cru/platform/native/ui_application.hpp b/include/cru/platform/native/ui_application.hpp
index 6d2ab659..c1f10d15 100644
--- a/include/cru/platform/native/ui_application.hpp
+++ b/include/cru/platform/native/ui_application.hpp
@@ -1,30 +1,21 @@
#pragma once
-#include "../native_resource.hpp"
+#include "../resource.hpp"
#include <chrono>
#include <functional>
#include <vector>
+namespace cru::platform::graph {
+struct IGraphFactory;
+}
+
namespace cru::platform::native {
struct INativeWindow;
struct ICursorManager;
// The entry point of a ui application.
-// It will call IGraphFactory::CreateInstance during its creation
-// and set graph factory to be auto deleted. If you want to keep
-// the graph factory then you should manually set it to false after
-// creating the ui application.
struct IUiApplication : public virtual INativeResource {
public:
- // Create a platform-specific instance and save it as the global instance.
- // Do not create the instance twice. Implements should assert for that.
- // After creating, get the instance by GetInstance.
- static IUiApplication* CreateInstance();
-
- // Get the global instance. If it is not created, then return nullptr.
- static IUiApplication* GetInstance();
-
- public:
// Block current thread and run the message loop. Return the exit code when
// message loop gets a quit message (possibly posted by method RequestQuit).
virtual int Run() = 0;
@@ -44,6 +35,8 @@ struct IUiApplication : public virtual INativeResource {
virtual std::vector<INativeWindow*> GetAllWindow() = 0;
virtual INativeWindow* CreateWindow(INativeWindow* parent) = 0;
+ virtual cru::platform::graph::IGraphFactory* GetGraphFactory() = 0;
+
virtual ICursorManager* GetCursorManager() = 0;
};
} // namespace cru::platform::native
diff --git a/include/cru/platform/native/native_window.hpp b/include/cru/platform/native/window.hpp
index cd2459e0..bfaf170b 100644
--- a/include/cru/platform/native/native_window.hpp
+++ b/include/cru/platform/native/window.hpp
@@ -1,12 +1,11 @@
#pragma once
-#include "../native_resource.hpp"
+#include "../resource.hpp"
-#include "cru/common/event.hpp"
-
-#include "../graphic_base.hpp"
+#include "../graph_base.hpp"
#include "basic_types.hpp"
+#include "cru/common/event.hpp"
#include "cursor.hpp"
-#include "native_event.hpp"
+#include "event.hpp"
namespace cru::platform::graph {
struct IPainter;
@@ -21,7 +20,7 @@ namespace cru::platform::native {
// Close or closed by the user, which leads to an invalid instance. You can
// check the validity by IsValid. When you call perform native operations on the
// invalid instance, there is no effect.
-struct INativeWindow : public virtual INativeResource {
+struct INativeWindow : virtual INativeResource {
// Return if the window is still valid, that is, hasn't been closed or
// destroyed.
virtual bool IsValid() = 0;
diff --git a/include/cru/win/graph/direct/factory.hpp b/include/cru/win/graph/direct/factory.hpp
index ae4eeb3a..4c106f54 100644
--- a/include/cru/win/graph/direct/factory.hpp
+++ b/include/cru/win/graph/direct/factory.hpp
@@ -5,10 +5,9 @@
namespace cru::platform::graph::win::direct {
class DirectGraphFactory : public DirectResource, public virtual IGraphFactory {
- private:
+ public:
DirectGraphFactory();
- public:
CRU_DELETE_COPY(DirectGraphFactory)
CRU_DELETE_MOVE(DirectGraphFactory)
diff --git a/include/cru/win/native/cursor.hpp b/include/cru/win/native/cursor.hpp
index 3ef480ea..e5728b1c 100644
--- a/include/cru/win/native/cursor.hpp
+++ b/include/cru/win/native/cursor.hpp
@@ -1,32 +1,30 @@
#pragma once
-#include <memory>
-#include "../win_pre_config.hpp"
+#include "resource.hpp"
-#include "cru/common/base.hpp"
#include "cru/platform/native/cursor.hpp"
-#include "cru/win/native/platform_id.hpp"
+
+#include <memory>
namespace cru::platform::native::win {
-class WinCursor : public Cursor {
+class WinCursor : public WinNativeResource, public virtual ICursor {
public:
- WinCursor(HCURSOR handle, bool auto_delete);
+ WinCursor(HCURSOR handle, bool auto_destroy);
CRU_DELETE_COPY(WinCursor)
CRU_DELETE_MOVE(WinCursor)
~WinCursor() override;
- CRU_PLATFORMID_IMPLEMENT_WIN
-
public:
HCURSOR GetHandle() const { return handle_; }
private:
HCURSOR handle_;
- bool auto_delete_;
+ bool auto_destroy_;
};
-class WinCursorManager : public CursorManager {
+class WinCursorManager : public WinNativeResource,
+ public virtual ICursorManager {
public:
WinCursorManager();
@@ -35,13 +33,11 @@ class WinCursorManager : public CursorManager {
~WinCursorManager() override = default;
- CRU_PLATFORMID_IMPLEMENT_WIN
-
public:
- std::shared_ptr<WinCursor> GetSystemWinCursor(SystemCursor type);
+ std::shared_ptr<WinCursor> GetSystemWinCursor(SystemCursorType type);
- std::shared_ptr<Cursor> GetSystemCursor(SystemCursor type) override {
- return std::static_pointer_cast<Cursor>(GetSystemWinCursor(type));
+ std::shared_ptr<ICursor> GetSystemCursor(SystemCursorType type) override {
+ return std::static_pointer_cast<ICursor>(GetSystemWinCursor(type));
}
private:
diff --git a/include/cru/win/native/god_window.hpp b/include/cru/win/native/god_window.hpp
index 9fd20caa..3cf97e0b 100644
--- a/include/cru/win/native/god_window.hpp
+++ b/include/cru/win/native/god_window.hpp
@@ -12,10 +12,10 @@ class WindowClass;
class GodWindow : public Object {
public:
explicit GodWindow(WinUiApplication* application);
- GodWindow(const GodWindow& other) = delete;
- GodWindow(GodWindow&& other) = delete;
- GodWindow& operator=(const GodWindow& other) = delete;
- GodWindow& operator=(GodWindow&& other) = delete;
+
+ CRU_DELETE_COPY(GodWindow)
+ CRU_DELETE_MOVE(GodWindow)
+
~GodWindow() override;
HWND GetHandle() const { return hwnd_; }
@@ -26,7 +26,7 @@ class GodWindow : public Object {
private:
WinUiApplication* application_;
- std::shared_ptr<WindowClass> god_window_class_;
+ std::unique_ptr<WindowClass> god_window_class_;
HWND hwnd_;
};
-} // namespace cru::win::native \ No newline at end of file
+} // namespace cru::platform::native::win
diff --git a/include/cru/win/native/resource.hpp b/include/cru/win/native/resource.hpp
new file mode 100644
index 00000000..2c76fe6b
--- /dev/null
+++ b/include/cru/win/native/resource.hpp
@@ -0,0 +1,23 @@
+#pragma once
+#include "../win_pre_config.hpp"
+
+#include "cru/platform/resource.hpp"
+
+namespace cru::platform::native::win {
+class WinNativeResource : public Object, public virtual INativeResource {
+ public:
+ static constexpr std::string_view k_platform_id = "Windows";
+
+ protected:
+ WinNativeResource() = default;
+
+ public:
+ CRU_DELETE_COPY(WinNativeResource)
+ CRU_DELETE_MOVE(WinNativeResource)
+
+ ~WinNativeResource() override = default;
+
+ public:
+ std::string_view GetPlatformId() const final { return k_platform_id; }
+};
+} // namespace cru::platform::native::win
diff --git a/include/cru/win/native/ui_application.hpp b/include/cru/win/native/ui_application.hpp
index 94c4b1eb..65bdc9e4 100644
--- a/include/cru/win/native/ui_application.hpp
+++ b/include/cru/win/native/ui_application.hpp
@@ -1,39 +1,40 @@
#pragma once
-#include "../win_pre_config.hpp"
+#include "resource.hpp"
#include "cru/platform/native/ui_application.hpp"
-#include "platform_id.hpp"
-#include "cursor.hpp"
-
#include <memory>
+namespace cru::platform::graph::win::direct {
+class DirectGraphFactory;
+}
+
namespace cru::platform::native::win {
class GodWindow;
class TimerManager;
class WindowManager;
+class WinCursorManager;
-class WinUiApplication : public UiApplication {
- friend UiApplication* UiApplication::CreateInstance();
-
+class WinUiApplication : public WinNativeResource,
+ public virtual IUiApplication {
public:
- static WinUiApplication* GetInstance();
+ static WinUiApplication* GetInstance() { return instance; }
+
+ private:
+ static WinUiApplication* instance;
private:
- explicit WinUiApplication(HINSTANCE h_instance);
+ WinUiApplication();
public:
- WinUiApplication(const WinUiApplication&) = delete;
- WinUiApplication(WinUiApplication&&) = delete;
- WinUiApplication& operator=(const WinUiApplication&) = delete;
- WinUiApplication& operator=(WinUiApplication&&) = delete;
- ~WinUiApplication() override;
+ CRU_DELETE_COPY(WinUiApplication)
+ CRU_DELETE_MOVE(WinUiApplication)
- CRU_PLATFORMID_IMPLEMENT_WIN
+ ~WinUiApplication() override;
public:
int Run() override;
- void Quit(int quit_code) override;
+ void RequestQuit(int quit_code) override;
void AddOnQuitHandler(const std::function<void()>& handler) override;
@@ -47,25 +48,29 @@ class WinUiApplication : public UiApplication {
std::vector<INativeWindow*> GetAllWindow() override;
INativeWindow* CreateWindow(INativeWindow* parent) override;
- WinCursorManager* GetCursorManager() override;
+ cru::platform::graph::IGraphFactory* GetGraphFactory() override;
+
+ cru::platform::graph::win::direct::DirectGraphFactory* GetDirectFactory() {
+ return graph_factory_.get();
+ }
- bool IsAutoDelete() const { return auto_delete_; }
- void SetAutoDelete(bool value) { auto_delete_ = value; }
+ ICursorManager* GetCursorManager() override;
- HINSTANCE GetInstanceHandle() const { return h_instance_; }
+ HINSTANCE GetInstanceHandle() const { return instance_handle_; }
GodWindow* GetGodWindow() const { return god_window_.get(); }
TimerManager* GetTimerManager() const { return timer_manager_.get(); }
WindowManager* GetWindowManager() const { return window_manager_.get(); }
private:
- bool auto_delete_ = false;
+ HINSTANCE instance_handle_;
- HINSTANCE h_instance_;
+ std::unique_ptr<cru::platform::graph::win::direct::DirectGraphFactory>
+ graph_factory_;
- std::shared_ptr<GodWindow> god_window_;
- std::shared_ptr<TimerManager> timer_manager_;
- std::shared_ptr<WindowManager> window_manager_;
+ std::unique_ptr<GodWindow> god_window_;
+ std::unique_ptr<TimerManager> timer_manager_;
+ std::unique_ptr<WindowManager> window_manager_;
std::unique_ptr<WinCursorManager> cursor_manager_;
diff --git a/include/cru/win/native/native_window.hpp b/include/cru/win/native/window.hpp
index 16b14dbf..9752682f 100644
--- a/include/cru/win/native/native_window.hpp
+++ b/include/cru/win/native/window.hpp
@@ -1,30 +1,28 @@
#pragma once
-#include "../win_pre_config.hpp"
+#include "resource.hpp"
-#include "cru/platform/native/native_window.hpp"
-#include "platform_id.hpp"
+#include "cru/platform/native/window.hpp"
#include "window_native_message_event_args.hpp"
#include <memory>
namespace cru::platform::native::win {
class WinUiApplication;
+class WinCursor;
class WindowClass;
class WindowManager;
class WindowRenderTarget;
-class WinNativeWindow : public INativeWindow {
+class WinNativeWindow : public WinNativeResource, public virtual INativeWindow {
public:
WinNativeWindow(WinUiApplication* application,
- std::shared_ptr<WindowClass> window_class, DWORD window_style,
+ WindowClass* window_class, DWORD window_style,
WinNativeWindow* parent);
- WinNativeWindow(const WinNativeWindow& other) = delete;
- WinNativeWindow(WinNativeWindow&& other) = delete;
- WinNativeWindow& operator=(const WinNativeWindow& other) = delete;
- WinNativeWindow& operator=(WinNativeWindow&& other) = delete;
- ~WinNativeWindow() override;
- CRU_PLATFORMID_IMPLEMENT_WIN
+ CRU_DELETE_COPY(WinNativeWindow)
+ CRU_DELETE_MOVE(WinNativeWindow)
+
+ ~WinNativeWindow() override;
public:
bool IsValid() override;
@@ -53,16 +51,16 @@ class WinNativeWindow : public INativeWindow {
bool CaptureMouse() override;
bool ReleaseMouse() override;
- void Repaint() override;
- graph::Painter* BeginPaint() override;
+ void RequestRepaint() override;
+ std::unique_ptr<graph::IPainter> BeginPaint() override;
- void SetCursor(std::shared_ptr<Cursor> cursor) override;
+ void SetCursor(std::shared_ptr<ICursor> 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_; }
- IEvent<bool>* FocusEvent() override { return &focus_event_; }
- IEvent<bool>* MouseEnterLeaveEvent() override {
+ IEvent<FocusChangeType>* FocusEvent() override { return &focus_event_; }
+ IEvent<MouseEnterLeaveType>* MouseEnterLeaveEvent() override {
return &mouse_enter_leave_event_;
}
IEvent<Point>* MouseMoveEvent() override { return &mouse_move_event_; }
@@ -128,13 +126,15 @@ class WinNativeWindow : public INativeWindow {
bool has_focus_ = false;
bool is_mouse_in_ = false;
- std::shared_ptr<WindowRenderTarget> window_render_target_;
+ std::unique_ptr<WindowRenderTarget> window_render_target_;
+
+ std::shared_ptr<WinCursor> cursor_;
Event<std::nullptr_t> destroy_event_;
Event<std::nullptr_t> paint_event_;
Event<Size> resize_event_;
- Event<bool> focus_event_;
- Event<bool> mouse_enter_leave_event_;
+ Event<FocusChangeType> focus_event_;
+ Event<MouseEnterLeaveType> mouse_enter_leave_event_;
Event<Point> mouse_move_event_;
Event<platform::native::NativeMouseButtonEventArgs> mouse_down_event_;
Event<platform::native::NativeMouseButtonEventArgs> mouse_up_event_;
diff --git a/include/cru/win/native/window_class.hpp b/include/cru/win/native/window_class.hpp
index fec3b32e..fd5102a5 100644
--- a/include/cru/win/native/window_class.hpp
+++ b/include/cru/win/native/window_class.hpp
@@ -8,12 +8,11 @@
namespace cru::platform::native::win {
class WindowClass : public Object {
public:
- WindowClass(const std::wstring& name, WNDPROC window_proc,
- HINSTANCE h_instance);
- WindowClass(const WindowClass& other) = delete;
- WindowClass(WindowClass&& other) = delete;
- WindowClass& operator=(const WindowClass& other) = delete;
- WindowClass& operator=(WindowClass&& other) = delete;
+ WindowClass(std::wstring name, WNDPROC window_proc, HINSTANCE h_instance);
+
+ CRU_DELETE_COPY(WindowClass)
+ CRU_DELETE_MOVE(WindowClass)
+
~WindowClass() override = default;
const wchar_t* GetName() const { return name_.c_str(); }
@@ -24,4 +23,4 @@ class WindowClass : public Object {
std::wstring name_;
ATOM atom_;
};
-} // namespace cru::win::native
+} // namespace cru::platform::native::win
diff --git a/include/cru/win/native/window_native_message_event_args.hpp b/include/cru/win/native/window_native_message_event_args.hpp
index 4cf744f2..18de1f46 100644
--- a/include/cru/win/native/window_native_message_event_args.hpp
+++ b/include/cru/win/native/window_native_message_event_args.hpp
@@ -15,13 +15,8 @@ class WindowNativeMessageEventArgs : public Object {
public:
WindowNativeMessageEventArgs(const WindowNativeMessage& message)
: message_(message) {}
- WindowNativeMessageEventArgs(const WindowNativeMessageEventArgs& other) =
- default;
- WindowNativeMessageEventArgs(WindowNativeMessageEventArgs&& other) = default;
- WindowNativeMessageEventArgs& operator=(
- const WindowNativeMessageEventArgs& other) = default;
- WindowNativeMessageEventArgs& operator=(
- WindowNativeMessageEventArgs&& other) = default;
+ CRU_DEFAULT_COPY(WindowNativeMessageEventArgs)
+ CRU_DEFAULT_MOVE(WindowNativeMessageEventArgs)
~WindowNativeMessageEventArgs() override = default;
WindowNativeMessage GetWindowMessage() const { return message_; }
@@ -42,4 +37,4 @@ class WindowNativeMessageEventArgs : public Object {
LRESULT result_;
bool handled_ = false;
};
-} // namespace cru::win::native
+} // namespace cru::platform::native::win
diff --git a/include/cru/win/native/window_render_target.hpp b/include/cru/win/native/window_render_target.hpp
index bde47f4f..248bfc25 100644
--- a/include/cru/win/native/window_render_target.hpp
+++ b/include/cru/win/native/window_render_target.hpp
@@ -4,22 +4,23 @@
#include "cru/common/base.hpp"
namespace cru::platform::graph::win::direct {
-struct IDirectFactory;
+class DirectGraphFactory;
}
namespace cru::platform::native::win {
// Represents a window render target.
class WindowRenderTarget : public Object {
public:
- WindowRenderTarget(graph::win::direct::IDirectFactory* factory, HWND hwnd);
- WindowRenderTarget(const WindowRenderTarget& other) = delete;
- WindowRenderTarget(WindowRenderTarget&& other) = delete;
- WindowRenderTarget& operator=(const WindowRenderTarget& other) = delete;
- WindowRenderTarget& operator=(WindowRenderTarget&& other) = delete;
+ WindowRenderTarget(graph::win::direct::DirectGraphFactory* factory,
+ HWND hwnd);
+
+ CRU_DELETE_COPY(WindowRenderTarget)
+ CRU_DELETE_MOVE(WindowRenderTarget)
+
~WindowRenderTarget() override = default;
public:
- graph::win::direct::IDirectFactory* GetWinNativeFactory() const {
+ graph::win::direct::DirectGraphFactory* GetDirectFactory() const {
return factory_;
}
@@ -39,7 +40,7 @@ class WindowRenderTarget : public Object {
void CreateTargetBitmap();
private:
- graph::win::direct::IDirectFactory* factory_;
+ graph::win::direct::DirectGraphFactory* factory_;
Microsoft::WRL::ComPtr<IDXGISwapChain1> dxgi_swap_chain_;
Microsoft::WRL::ComPtr<ID2D1Bitmap1> target_bitmap_;
};
diff --git a/src/platform/native/CMakeLists.txt b/src/platform/native/CMakeLists.txt
index bc7c4a63..be3e73a5 100644
--- a/src/platform/native/CMakeLists.txt
+++ b/src/platform/native/CMakeLists.txt
@@ -3,8 +3,8 @@ add_library(cru_platform_native INTERFACE)
target_sources(cru_platform_native INTERFACE
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/basic_types.hpp
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/cursor.hpp
- ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/native_event.hpp
- ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/native_window.hpp
+ ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/event.hpp
+ ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/window.hpp
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/ui_application.hpp
)
target_link_libraries(cru_platform_native INTERFACE cru_platform_graph)
diff --git a/src/win/debug_logger.hpp b/src/win/debug_logger.hpp
index 53c4859b..c5321828 100644
--- a/src/win/debug_logger.hpp
+++ b/src/win/debug_logger.hpp
@@ -1,6 +1,7 @@
#include "cru/win/win_pre_config.hpp"
#include "cru/common/logger.hpp"
+#include "cru/win/string.hpp"
namespace cru::platform::win {
@@ -14,7 +15,8 @@ class WinDebugLoggerSource : public ::cru::log::ILogSource {
~WinDebugLoggerSource() = default;
void Write(::cru::log::LogLevel level, const std::string_view& s) override {
- ::OutputDebugStringA(s.data());
+ const std::wstring&& ws = ToUtf16String(s);
+ ::OutputDebugStringW(ws.data());
}
};
} // namespace cru::platform::win
diff --git a/src/win/graph/direct/factory.cpp b/src/win/graph/direct/factory.cpp
index 7882c3ee..1fff9fa9 100644
--- a/src/win/graph/direct/factory.cpp
+++ b/src/win/graph/direct/factory.cpp
@@ -12,6 +12,9 @@
namespace cru::platform::graph::win::direct {
DirectGraphFactory::DirectGraphFactory() {
+ // TODO! Detect repeated creation. Because I don't think we can create two d2d
+ // and dwrite factory so we need to prevent the "probably dangerous" behavior.
+
UINT creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifdef CRU_DEBUG
diff --git a/src/win/native/CMakeLists.txt b/src/win/native/CMakeLists.txt
index 0e7e5b4e..979b54df 100644
--- a/src/win/native/CMakeLists.txt
+++ b/src/win/native/CMakeLists.txt
@@ -9,9 +9,9 @@ add_library(cru_win_native STATIC
cursor.cpp
god_window.cpp
- native_window.cpp
timer.cpp
ui_application.cpp
+ window.cpp
window_class.cpp
window_d2d_painter.cpp
window_manager.cpp
@@ -21,8 +21,9 @@ target_sources(cru_win_native PUBLIC
${CRU_WIN_NATIVE_INCLUDE_DIR}/cursor.hpp
${CRU_WIN_NATIVE_INCLUDE_DIR}/exception.hpp
${CRU_WIN_NATIVE_INCLUDE_DIR}/god_window.hpp
- ${CRU_WIN_NATIVE_INCLUDE_DIR}/native_window.hpp
+ ${CRU_WIN_NATIVE_INCLUDE_DIR}/resource.hpp
${CRU_WIN_NATIVE_INCLUDE_DIR}/ui_application.hpp
+ ${CRU_WIN_NATIVE_INCLUDE_DIR}/window.hpp
${CRU_WIN_NATIVE_INCLUDE_DIR}/window_class.hpp
${CRU_WIN_NATIVE_INCLUDE_DIR}/window_native_message_event_args.hpp
${CRU_WIN_NATIVE_INCLUDE_DIR}/window_render_target.hpp
diff --git a/src/win/native/cursor.cpp b/src/win/native/cursor.cpp
index a0f9dd6c..096f3fdf 100644
--- a/src/win/native/cursor.cpp
+++ b/src/win/native/cursor.cpp
@@ -1,22 +1,22 @@
#include "cru/win/native/cursor.hpp"
-#include "cru/common/format.hpp"
#include "cru/common/logger.hpp"
#include "cru/win/native/exception.hpp"
#include <stdexcept>
namespace cru::platform::native::win {
-WinCursor::WinCursor(HCURSOR handle, bool auto_delete) {
+WinCursor::WinCursor(HCURSOR handle, bool auto_destroy) {
handle_ = handle;
- auto_delete_ = auto_delete;
+ auto_destroy_ = auto_destroy;
}
WinCursor::~WinCursor() {
- if (auto_delete_) {
+ if (auto_destroy_) {
if (!::DestroyCursor(handle_)) {
- // This is not a fetal error but might still need notice.
- log::Warn(L"Failed to destroy a cursor. Last error code: {}",
+ // This is not a fetal error but might still need notice because it may
+ // cause leak.
+ log::Warn("Failed to destroy a cursor. Last error code: {}",
::GetLastError());
}
}
@@ -27,7 +27,7 @@ WinCursor* LoadWinCursor(const wchar_t* name) {
const auto handle = static_cast<HCURSOR>(::LoadImageW(
NULL, name, IMAGE_CURSOR, SM_CYCURSOR, SM_CYCURSOR, LR_SHARED));
if (handle == NULL) {
- throw Win32Error(::GetLastError(), "Failed to get system cursor.");
+ throw Win32Error(::GetLastError(), "Failed to load system cursor.");
}
return new WinCursor(handle, false);
}
@@ -38,11 +38,11 @@ WinCursorManager::WinCursorManager()
sys_hand_(LoadWinCursor(IDC_HAND)) {}
std::shared_ptr<WinCursor> WinCursorManager::GetSystemWinCursor(
- SystemCursor type) {
+ SystemCursorType type) {
switch (type) {
- case SystemCursor::Arrow:
+ case SystemCursorType::Arrow:
return sys_arrow_;
- case SystemCursor::Hand:
+ case SystemCursorType::Hand:
return sys_hand_;
default:
throw std::runtime_error("Unknown system cursor value.");
diff --git a/src/win/native/dpi_util.hpp b/src/win/native/dpi_util.hpp
index a642fd79..0ebcd7e2 100644
--- a/src/win/native/dpi_util.hpp
+++ b/src/win/native/dpi_util.hpp
@@ -1,5 +1,4 @@
#pragma once
-
#include "cru/platform/native/basic_types.hpp"
// The dpi awareness needs to be implemented in the future. Currently we use 96
diff --git a/src/win/native/god_window.cpp b/src/win/native/god_window.cpp
index 5f1d7b53..be54f698 100644
--- a/src/win/native/god_window.cpp
+++ b/src/win/native/god_window.cpp
@@ -1,5 +1,6 @@
#include "cru/win/native/god_window.hpp"
+#include "cru/common/logger.hpp"
#include "cru/win/native/exception.hpp"
#include "cru/win/native/ui_application.hpp"
#include "cru/win/native/window_class.hpp"
@@ -30,7 +31,7 @@ GodWindow::GodWindow(WinUiApplication* application) {
const auto h_instance = application->GetInstanceHandle();
- god_window_class_ = std::make_shared<WindowClass>(god_window_class_name,
+ god_window_class_ = std::make_unique<WindowClass>(god_window_class_name,
GodWndProc, h_instance);
hwnd_ = CreateWindowEx(0, god_window_class_name, L"", 0, CW_USEDEFAULT,
@@ -41,7 +42,12 @@ GodWindow::GodWindow(WinUiApplication* application) {
throw Win32Error(::GetLastError(), "Failed to create god window.");
}
-GodWindow::~GodWindow() { ::DestroyWindow(hwnd_); }
+GodWindow::~GodWindow() {
+ if (!::DestroyWindow(hwnd_)) {
+ // Although this could be "safely" ignore.
+ log::Warn("Failed to destroy god window.");
+ }
+}
bool GodWindow::HandleGodWindowMessage(HWND hwnd, UINT msg, WPARAM w_param,
LPARAM l_param, LRESULT* result) {
diff --git a/src/win/native/timer.hpp b/src/win/native/timer.hpp
index 08749768..10658cf1 100644
--- a/src/win/native/timer.hpp
+++ b/src/win/native/timer.hpp
@@ -15,10 +15,10 @@ using TimerAction = std::function<void()>;
class TimerManager : public Object {
public:
TimerManager(GodWindow* god_window);
- TimerManager(const TimerManager& other) = delete;
- TimerManager(TimerManager&& other) = delete;
- TimerManager& operator=(const TimerManager& other) = delete;
- TimerManager& operator=(TimerManager&& other) = delete;
+
+ CRU_DELETE_COPY(TimerManager)
+ CRU_DELETE_MOVE(TimerManager)
+
~TimerManager() override = default;
UINT_PTR CreateTimer(UINT milliseconds, bool loop, const TimerAction& action);
@@ -31,4 +31,4 @@ class TimerManager : public Object {
std::map<UINT_PTR, std::pair<bool, TimerAction>> map_{};
UINT_PTR current_count_ = 0;
};
-} // namespace cru::win::native
+} // namespace cru::platform::native::win
diff --git a/src/win/native/ui_application.cpp b/src/win/native/ui_application.cpp
index 0bbe9c03..f3a7f1dc 100644
--- a/src/win/native/ui_application.cpp
+++ b/src/win/native/ui_application.cpp
@@ -2,58 +2,39 @@
#include "../debug_logger.hpp"
#include "cru/common/logger.hpp"
-#include "cru/win/graph/direct/graph_factory.hpp"
+#include "cru/platform/check.hpp"
+#include "cru/win/graph/direct/factory.hpp"
+#include "cru/win/native/cursor.hpp"
#include "cru/win/native/exception.hpp"
#include "cru/win/native/god_window.hpp"
-#include "cru/win/native/native_window.hpp"
+#include "cru/win/native/window.hpp"
#include "god_window_message.hpp"
#include "timer.hpp"
#include "window_manager.hpp"
-#include <VersionHelpers.h>
#include <cassert>
namespace cru::platform::native::win {
-namespace {
-WinUiApplication* instance = nullptr;
-}
-} // namespace cru::platform::native::win
-
-namespace cru::platform::native {
-UiApplication* UiApplication::CreateInstance() {
- auto& i =
- ::cru::platform::native::win::instance; // avoid long namespace prefix
- assert(i == nullptr);
- i = new win::WinUiApplication(::GetModuleHandleW(nullptr));
- return i;
-}
+WinUiApplication* WinUiApplication::instance = nullptr;
-UiApplication* UiApplication::GetInstance() {
- return ::cru::platform::native::win::instance;
-}
-} // namespace cru::platform::native
-
-namespace cru::platform::native::win {
-WinUiApplication* WinUiApplication::GetInstance() { return instance; }
+WinUiApplication::WinUiApplication() {
+ if (instance) {
+ throw new std::runtime_error(
+ "Already created an instance of WinUiApplication");
+ }
-WinUiApplication::WinUiApplication(HINSTANCE h_instance)
- : h_instance_(h_instance) {
- assert(instance == nullptr);
+ instance = this;
log::Logger::GetInstance()->AddSource(
- new ::cru::platform::win::WinDebugLoggerSource());
-
- if (!::IsWindows8OrGreater())
- throw std::runtime_error("Must run on Windows 8 or later.");
-
- const auto graph_factory = graph::GraphFactory::CreateInstance();
- graph_factory->SetAutoDelete(true);
+ std::make_unique<::cru::platform::win::WinDebugLoggerSource>());
- god_window_ = std::make_shared<GodWindow>(this);
- timer_manager_ = std::make_shared<TimerManager>(god_window_.get());
- window_manager_ = std::make_shared<WindowManager>(this);
+ graph_factory_ =
+ std::make_unique<cru::platform::graph::win::direct::DirectGraphFactory>();
- cursor_manager_.reset(new WinCursorManager());
+ god_window_ = std::make_unique<GodWindow>(this);
+ timer_manager_ = std::make_unique<TimerManager>(god_window_.get());
+ window_manager_ = std::make_unique<WindowManager>(this);
+ cursor_manager_ = std::make_unique<WinCursorManager>();
}
WinUiApplication::~WinUiApplication() { instance = nullptr; }
@@ -67,12 +48,10 @@ int WinUiApplication::Run() {
for (const auto& handler : quit_handlers_) handler();
- if (auto_delete_) delete this;
-
return static_cast<int>(msg.wParam);
}
-void WinUiApplication::Quit(const int quit_code) {
+void WinUiApplication::RequestQuit(const int quit_code) {
::PostQuitMessage(quit_code);
}
@@ -84,8 +63,8 @@ void WinUiApplication::InvokeLater(const std::function<void()>& action) {
// copy the action to a safe place
auto p_action_copy = new std::function<void()>(action);
- if (PostMessageW(GetGodWindow()->GetHandle(), invoke_later_message_id,
- reinterpret_cast<WPARAM>(p_action_copy), 0) == 0)
+ if (::PostMessageW(GetGodWindow()->GetHandle(), invoke_later_message_id,
+ reinterpret_cast<WPARAM>(p_action_copy), 0) == 0)
throw Win32Error(::GetLastError(), "InvokeLater failed to post message.");
}
@@ -119,14 +98,17 @@ std::vector<INativeWindow*> WinUiApplication::GetAllWindow() {
INativeWindow* WinUiApplication::CreateWindow(INativeWindow* parent) {
WinNativeWindow* p = nullptr;
if (parent != nullptr) {
- p = dynamic_cast<WinNativeWindow*>(parent);
- assert(p);
+ p = CheckPlatform<WinNativeWindow>(parent, GetPlatformId());
}
return new WinNativeWindow(this, window_manager_->GetGeneralWindowClass(),
WS_OVERLAPPEDWINDOW, p);
}
-WinCursorManager* WinUiApplication::GetCursorManager() {
+cru::platform::graph::IGraphFactory* WinUiApplication::GetGraphFactory() {
+ return graph_factory_.get();
+}
+
+ICursorManager* WinUiApplication::GetCursorManager() {
return cursor_manager_.get();
}
} // namespace cru::platform::native::win
diff --git a/src/win/native/native_window.cpp b/src/win/native/window.cpp
index 684511b9..517426ff 100644
--- a/src/win/native/native_window.cpp
+++ b/src/win/native/window.cpp
@@ -1,8 +1,8 @@
-#include "cru/win/native/native_window.hpp"
+#include "cru/win/native/window.hpp"
#include "cru/common/format.hpp"
#include "cru/common/logger.hpp"
-#include "cru/win/graph/direct/graph_factory.hpp"
+#include "cru/platform/check.hpp"
#include "cru/win/native/cursor.hpp"
#include "cru/win/native/exception.hpp"
#include "cru/win/native/ui_application.hpp"
@@ -12,8 +12,8 @@
#include "window_d2d_painter.hpp"
#include "window_manager.hpp"
-#include <cassert>
#include <windowsx.h>
+#include <cassert>
namespace cru::platform::native::win {
inline Point PiToDip(const POINT& pi_point) {
@@ -21,14 +21,14 @@ inline Point PiToDip(const POINT& pi_point) {
}
WinNativeWindow::WinNativeWindow(WinUiApplication* application,
- std::shared_ptr<WindowClass> window_class,
- DWORD window_style, WinNativeWindow* parent) {
+ WindowClass* window_class, DWORD window_style,
+ WinNativeWindow* parent)
+ : application_(application), parent_window_(parent) {
assert(application); // application can't be null.
- assert(parent == nullptr ||
- parent->IsValid()); // Parent window is not valid.
- application_ = application;
- parent_window_ = parent;
+ if (parent != nullptr && !parent->IsValid()) {
+ throw new std::runtime_error("Can't use a invalid window as parent.");
+ }
const auto window_manager = application->GetWindowManager();
@@ -43,8 +43,8 @@ WinNativeWindow::WinNativeWindow(WinUiApplication* application,
window_manager->RegisterWindow(hwnd_, this);
- window_render_target_.reset(new WindowRenderTarget(
- graph::win::direct::DirectGraphFactory::GetInstance(), hwnd_));
+ window_render_target_ = std::make_unique<WindowRenderTarget>(
+ application->GetDirectFactory(), hwnd_);
}
WinNativeWindow::~WinNativeWindow() {
@@ -150,7 +150,7 @@ bool WinNativeWindow::ReleaseMouse() {
return false;
}
-void WinNativeWindow::Repaint() {
+void WinNativeWindow::RequestRepaint() {
if (IsValid()) {
if (!::InvalidateRect(hwnd_, nullptr, FALSE))
throw Win32Error(::GetLastError(), "Failed to invalidate window.");
@@ -159,52 +159,64 @@ void WinNativeWindow::Repaint() {
}
}
-graph::Painter* WinNativeWindow::BeginPaint() {
- return new WindowD2DPainter(this);
+std::unique_ptr<graph::IPainter> WinNativeWindow::BeginPaint() {
+ return std::make_unique<WindowD2DPainter>(this);
}
-void WinNativeWindow::SetCursor(std::shared_ptr<Cursor> cursor) {
+void WinNativeWindow::SetCursor(std::shared_ptr<ICursor> cursor) {
+ if (cursor == nullptr) {
+ throw std::runtime_error("Can't use a nullptr as cursor.");
+ }
+
if (!IsValid()) return;
- assert(cursor);
- WinCursor* c = static_cast<WinCursor*>(cursor.get());
- auto outputError = [] {
- log::Debug(L"Failed to set cursor. Last error code: {}.", ::GetLastError());
- };
+ cursor_ = CheckPlatform<WinCursor>(cursor, GetPlatformId());
if (!::SetClassLongPtrW(hwnd_, GCLP_HCURSOR,
- reinterpret_cast<LONG_PTR>(c->GetHandle()))) {
- outputError();
+ reinterpret_cast<LONG_PTR>(cursor_->GetHandle()))) {
+ log::Warn(
+ "Failed to set cursor because failed to set class long. Last error "
+ "code: {}.",
+ ::GetLastError());
return;
}
+ if (!IsVisible()) return;
+
+ auto lg = [](const std::string_view& reason) {
+ log::Warn(
+ "Failed to set cursor because {} when window is visible. (We need "
+ "to update cursor if it is inside the window.) Last error code: {}.",
+ reason, ::GetLastError());
+ };
+
::POINT point;
if (!::GetCursorPos(&point)) {
- outputError();
+ lg("failed to get cursor pos");
return;
}
::RECT rect;
if (!::GetClientRect(hwnd_, &rect)) {
- outputError();
+ lg("failed to get window's client rect");
return;
}
::POINT lefttop{rect.left, rect.top};
::POINT rightbottom{rect.right, rect.bottom};
if (!::ClientToScreen(hwnd_, &lefttop)) {
- outputError();
+ lg("failed to call ClientToScreen on lefttop");
return;
}
if (!::ClientToScreen(hwnd_, &rightbottom)) {
- outputError();
+ lg("failed to call ClientToScreen on rightbottom");
return;
}
if (point.x >= lefttop.x && point.y >= lefttop.y &&
point.x <= rightbottom.x && point.y <= rightbottom.y) {
- ::SetCursor(c->GetHandle());
+ ::SetCursor(cursor_->GetHandle());
}
}
@@ -361,12 +373,12 @@ void WinNativeWindow::OnResizeInternal(const int new_width,
void WinNativeWindow::OnSetFocusInternal() {
has_focus_ = true;
- focus_event_.Raise(true);
+ focus_event_.Raise(FocusChangeType::Gain);
}
void WinNativeWindow::OnKillFocusInternal() {
has_focus_ = false;
- focus_event_.Raise(false);
+ focus_event_.Raise(FocusChangeType::Lost);
}
void WinNativeWindow::OnMouseMoveInternal(const POINT point) {
@@ -381,7 +393,7 @@ void WinNativeWindow::OnMouseMoveInternal(const POINT point) {
TrackMouseEvent(&tme);
is_mouse_in_ = true;
- mouse_enter_leave_event_.Raise(true);
+ mouse_enter_leave_event_.Raise(MouseEnterLeaveType::Enter);
}
mouse_move_event_.Raise(PiToDip(point));
@@ -389,7 +401,7 @@ void WinNativeWindow::OnMouseMoveInternal(const POINT point) {
void WinNativeWindow::OnMouseLeaveInternal() {
is_mouse_in_ = false;
- mouse_enter_leave_event_.Raise(false);
+ mouse_enter_leave_event_.Raise(MouseEnterLeaveType::Leave);
}
void WinNativeWindow::OnMouseDownInternal(platform::native::MouseButton button,
diff --git a/src/win/native/window_class.cpp b/src/win/native/window_class.cpp
index d69160ab..11dc86aa 100644
--- a/src/win/native/window_class.cpp
+++ b/src/win/native/window_class.cpp
@@ -3,9 +3,9 @@
#include "cru/win/native/exception.hpp"
namespace cru::platform::native::win {
-WindowClass::WindowClass(const std::wstring& name, WNDPROC window_proc,
+WindowClass::WindowClass(std::wstring name, WNDPROC window_proc,
HINSTANCE h_instance)
- : name_(name) {
+ : name_(std::move(name)) {
WNDCLASSEXW window_class;
window_class.cbSize = sizeof(WNDCLASSEXW);
@@ -18,7 +18,7 @@ WindowClass::WindowClass(const std::wstring& name, WNDPROC window_proc,
window_class.hCursor = LoadCursor(NULL, IDC_ARROW);
window_class.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
window_class.lpszMenuName = NULL;
- window_class.lpszClassName = name.c_str();
+ window_class.lpszClassName = name_.c_str();
window_class.hIconSm = NULL;
atom_ = ::RegisterClassExW(&window_class);
diff --git a/src/win/native/window_d2d_painter.cpp b/src/win/native/window_d2d_painter.cpp
index 16d276ef..ab74a964 100644
--- a/src/win/native/window_d2d_painter.cpp
+++ b/src/win/native/window_d2d_painter.cpp
@@ -1,7 +1,7 @@
#include "window_d2d_painter.hpp"
-#include "cru/win/graph/direct/direct_factory.hpp"
#include "cru/win/graph/direct/exception.hpp"
+#include "cru/win/graph/direct/factory.hpp"
#include "cru/win/native/window_render_target.hpp"
#include <cassert>
@@ -11,12 +11,12 @@ using namespace cru::platform::graph::win::direct;
WindowD2DPainter::WindowD2DPainter(WinNativeWindow* window)
: D2DPainter(window->GetWindowRenderTarget()
- ->GetWinNativeFactory()
+ ->GetDirectFactory()
->GetD2D1DeviceContext()),
window_(window) {
window->GetWindowRenderTarget()->SetAsTarget();
window->GetWindowRenderTarget()
- ->GetWinNativeFactory()
+ ->GetDirectFactory()
->GetD2D1DeviceContext()
->BeginDraw();
}
@@ -25,7 +25,7 @@ WindowD2DPainter::~WindowD2DPainter() { EndDraw(); }
void WindowD2DPainter::DoEndDraw() {
ThrowIfFailed(window_->GetWindowRenderTarget()
- ->GetWinNativeFactory()
+ ->GetDirectFactory()
->GetD2D1DeviceContext()
->EndDraw());
window_->GetWindowRenderTarget()->Present();
diff --git a/src/win/native/window_d2d_painter.hpp b/src/win/native/window_d2d_painter.hpp
index 1c90e8ab..6877babd 100644
--- a/src/win/native/window_d2d_painter.hpp
+++ b/src/win/native/window_d2d_painter.hpp
@@ -1,15 +1,13 @@
#pragma once
#include "cru/win/graph/direct/painter.hpp"
-#include "cru/win/native/native_window.hpp"
+#include "cru/win/native/window.hpp"
namespace cru::platform::native::win {
class WindowD2DPainter : public graph::win::direct::D2DPainter {
public:
explicit WindowD2DPainter(WinNativeWindow* window);
- WindowD2DPainter(const WindowD2DPainter& other) = delete;
- WindowD2DPainter& operator=(const WindowD2DPainter& other) = delete;
- WindowD2DPainter(WindowD2DPainter&& other) = delete;
- WindowD2DPainter& operator=(WindowD2DPainter&& other) = delete;
+ CRU_DELETE_COPY(WindowD2DPainter)
+ CRU_DELETE_MOVE(WindowD2DPainter)
~WindowD2DPainter() override;
protected:
@@ -18,4 +16,4 @@ class WindowD2DPainter : public graph::win::direct::D2DPainter {
private:
WinNativeWindow* window_;
};
-} // namespace cru::win::native
+} // namespace cru::platform::native::win
diff --git a/src/win/native/window_manager.cpp b/src/win/native/window_manager.cpp
index 5699b38a..0bf7656a 100644
--- a/src/win/native/window_manager.cpp
+++ b/src/win/native/window_manager.cpp
@@ -1,7 +1,7 @@
#include "window_manager.hpp"
#include "cru/win/native/ui_application.hpp"
-#include "cru/win/native/native_window.hpp"
+#include "cru/win/native/window.hpp"
#include "cru/win/native/window_class.hpp"
#include <cassert>
@@ -22,7 +22,7 @@ LRESULT __stdcall GeneralWndProc(HWND hWnd, UINT Msg, WPARAM wParam,
WindowManager::WindowManager(WinUiApplication* application) {
application_ = application;
- general_window_class_ = std::make_shared<WindowClass>(
+ general_window_class_ = std::make_unique<WindowClass>(
L"CruUIWindowClass", GeneralWndProc, application->GetInstanceHandle());
}
@@ -39,7 +39,7 @@ void WindowManager::UnregisterWindow(HWND hwnd) {
const auto find_result = window_map_.find(hwnd);
assert(find_result != window_map_.end()); // The hwnd is not in the map.
window_map_.erase(find_result);
- if (window_map_.empty()) application_->Quit(0);
+ if (window_map_.empty()) application_->RequestQuit(0);
}
WinNativeWindow* WindowManager::FromHandle(HWND hwnd) {
diff --git a/src/win/native/window_manager.hpp b/src/win/native/window_manager.hpp
index a0661556..677719aa 100644
--- a/src/win/native/window_manager.hpp
+++ b/src/win/native/window_manager.hpp
@@ -15,15 +15,15 @@ class WindowClass;
class WindowManager : public Object {
public:
WindowManager(WinUiApplication* application);
- WindowManager(const WindowManager& other) = delete;
- WindowManager(WindowManager&& other) = delete;
- WindowManager& operator=(const WindowManager& other) = delete;
- WindowManager& operator=(WindowManager&& other) = delete;
+
+ CRU_DELETE_COPY(WindowManager)
+ CRU_DELETE_MOVE(WindowManager)
+
~WindowManager() override;
// Get the general window class for creating ordinary window.
- std::shared_ptr<WindowClass> GetGeneralWindowClass() const {
- return general_window_class_;
+ WindowClass* GetGeneralWindowClass() const {
+ return general_window_class_.get();
}
// Register a window newly created.
@@ -45,8 +45,7 @@ class WindowManager : public Object {
private:
WinUiApplication* application_;
- std::shared_ptr<WindowClass> general_window_class_;
+ std::unique_ptr<WindowClass> general_window_class_;
std::map<HWND, WinNativeWindow*> window_map_;
};
-
-} // namespace cru::win::native
+} // namespace cru::platform::native::win
diff --git a/src/win/native/window_render_target.cpp b/src/win/native/window_render_target.cpp
index 426afdf6..f501b4dd 100644
--- a/src/win/native/window_render_target.cpp
+++ b/src/win/native/window_render_target.cpp
@@ -1,21 +1,22 @@
#include "cru/win/native/window_render_target.hpp"
-#include "cru/win/graph/direct/direct_factory.hpp"
#include "cru/win/graph/direct/exception.hpp"
+#include "cru/win/graph/direct/factory.hpp"
#include "dpi_util.hpp"
#include <cassert>
namespace cru::platform::native::win {
using namespace cru::platform::graph::win::direct;
-WindowRenderTarget::WindowRenderTarget(IDirectFactory* factory, HWND hwnd) {
- this->factory_ = factory;
+WindowRenderTarget::WindowRenderTarget(DirectGraphFactory* factory, HWND hwnd)
+ : factory_(factory) {
+ assert(factory);
const auto d3d11_device = factory->GetD3D11Device();
const auto dxgi_factory = factory->GetDxgiFactory();
// Allocate a descriptor.
- DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {0};
+ DXGI_SWAP_CHAIN_DESC1 swap_chain_desc;
swap_chain_desc.Width = 0; // use automatic sizing
swap_chain_desc.Height = 0;
swap_chain_desc.Format =
@@ -74,7 +75,7 @@ void WindowRenderTarget::CreateTargetBitmap() {
ThrowIfFailed(
dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer)));
- const auto dpi = GetDpi();
+ const auto dpi = GetDpi(); // TODO! DPI awareness.
auto bitmap_properties = D2D1::BitmapProperties1(
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,