aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/platform/gui/win/UiApplication.h19
-rw-r--r--src/platform/gui/win/CMakeLists.txt1
-rw-r--r--src/platform/gui/win/UiApplication.cpp51
-rw-r--r--src/platform/gui/win/Window.cpp19
-rw-r--r--src/platform/gui/win/WindowManager.cpp57
-rw-r--r--src/platform/gui/win/WindowManager.h45
6 files changed, 70 insertions, 122 deletions
diff --git a/include/cru/platform/gui/win/UiApplication.h b/include/cru/platform/gui/win/UiApplication.h
index 15c23148..b2d1f39b 100644
--- a/include/cru/platform/gui/win/UiApplication.h
+++ b/include/cru/platform/gui/win/UiApplication.h
@@ -1,8 +1,10 @@
#pragma once
#include "Base.h"
+#include "Window.h"
+#include "WindowClass.h"
-#include <cru/platform/gui/UiApplication.h>
#include <cru/base/Timer.h>
+#include <cru/platform/gui/UiApplication.h>
#include <memory>
@@ -13,6 +15,8 @@ class DirectGraphicsFactory;
namespace cru::platform::gui::win {
class CRU_WIN_GUI_API WinUiApplication : public WinNativeResource,
public virtual IUiApplication {
+ friend WinNativeWindow;
+
public:
static WinUiApplication* GetInstance() { return instance; }
@@ -49,8 +53,7 @@ class CRU_WIN_GUI_API WinUiApplication : public WinNativeResource,
cru::platform::graphics::IGraphicsFactory* GetGraphicsFactory() override;
- cru::platform::graphics::direct2d::DirectGraphicsFactory*
- GetDirectFactory() {
+ cru::platform::graphics::direct2d::DirectGraphicsFactory* GetDirectFactory() {
return graph_factory_.get();
}
@@ -59,8 +62,13 @@ class CRU_WIN_GUI_API WinUiApplication : public WinNativeResource,
IClipboard* GetClipboard() override;
HINSTANCE GetInstanceHandle() const { return instance_handle_; }
+ std::vector<WinNativeWindow*> GetAllWinWindow();
+ WinNativeWindow* FromHWND(HWND hwnd);
- WindowManager* GetWindowManager() const { return window_manager_.get(); }
+ private:
+ WindowClass* GetGeneralWindowClass();
+ void RegisterWindow(WinNativeWindow* window);
+ void UnregisterWindow(WinNativeWindow* window);
private:
HINSTANCE instance_handle_;
@@ -72,7 +80,8 @@ class CRU_WIN_GUI_API WinUiApplication : public WinNativeResource,
TimerRegistry<std::function<void()>> timers_;
- std::unique_ptr<WindowManager> window_manager_;
+ std::unique_ptr<WindowClass> general_window_class_;
+ std::vector<WinNativeWindow*> windows_;
std::unique_ptr<WinCursorManager> cursor_manager_;
std::unique_ptr<WinClipboard> clipboard_;
diff --git a/src/platform/gui/win/CMakeLists.txt b/src/platform/gui/win/CMakeLists.txt
index 8c0dd2a4..ff3c0d0b 100644
--- a/src/platform/gui/win/CMakeLists.txt
+++ b/src/platform/gui/win/CMakeLists.txt
@@ -7,7 +7,6 @@ add_library(CruPlatformGuiWin
UiApplication.cpp
Window.cpp
WindowClass.cpp
- WindowManager.cpp
)
target_link_libraries(CruPlatformGuiWin PUBLIC imm32)
target_link_libraries(CruPlatformGuiWin PUBLIC CruPlatformGraphicsDirect2d CruPlatformGui)
diff --git a/src/platform/gui/win/UiApplication.cpp b/src/platform/gui/win/UiApplication.cpp
index 12a74bc6..eb85ef90 100644
--- a/src/platform/gui/win/UiApplication.cpp
+++ b/src/platform/gui/win/UiApplication.cpp
@@ -1,21 +1,29 @@
#include "cru/platform/gui/win/UiApplication.h"
-#include "WindowManager.h"
#include "cru/platform/graphics/direct2d/Factory.h"
#include "cru/platform/gui/win/Base.h"
#include "cru/platform/gui/win/Clipboard.h"
#include "cru/platform/gui/win/Cursor.h"
#include "cru/platform/gui/win/Window.h"
+#include <algorithm>
#include <chrono>
-namespace cru::platform::gui {
-std::unique_ptr<IUiApplication> CreateUiApplication() {
- return std::make_unique<win::WinUiApplication>();
+namespace cru::platform::gui::win {
+namespace {
+LRESULT __stdcall GeneralWndProc(HWND hWnd, UINT Msg, WPARAM wParam,
+ LPARAM lParam) {
+ auto window = WinUiApplication::GetInstance()->FromHWND(hWnd);
+
+ LRESULT result;
+ if (window != nullptr &&
+ window->HandleNativeWindowMessage(hWnd, Msg, wParam, lParam, &result))
+ return result;
+
+ return DefWindowProc(hWnd, Msg, wParam, lParam);
}
-} // namespace cru::platform::gui
+} // namespace
-namespace cru::platform::gui::win {
WinUiApplication* WinUiApplication::instance = nullptr;
WinUiApplication::WinUiApplication() {
@@ -27,10 +35,12 @@ WinUiApplication::WinUiApplication() {
::SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
+ general_window_class_ = std::make_unique<WindowClass>(
+ L"CruUIWindowClass", GeneralWndProc, instance_handle_);
+
graph_factory_ = std::make_unique<
cru::platform::graphics::direct2d::DirectGraphicsFactory>();
- window_manager_ = std::make_unique<WindowManager>(this);
cursor_manager_ = std::make_unique<WinCursorManager>();
clipboard_ = std::make_unique<WinClipboard>(this);
}
@@ -94,9 +104,8 @@ long long WinUiApplication::SetInterval(std::chrono::milliseconds milliseconds,
void WinUiApplication::CancelTimer(long long id) { timers_.Remove(id); }
std::vector<INativeWindow*> WinUiApplication::GetAllWindow() {
- const auto&& windows = window_manager_->GetAllWindows();
std::vector<INativeWindow*> result;
- for (const auto w : windows) {
+ for (const auto w : windows_) {
result.push_back(static_cast<INativeWindow*>(w));
}
return result;
@@ -117,4 +126,28 @@ ICursorManager* WinUiApplication::GetCursorManager() {
IClipboard* WinUiApplication::GetClipboard() { return clipboard_.get(); }
+std::vector<WinNativeWindow*> WinUiApplication::GetAllWinWindow() {
+ return windows_;
+}
+
+WinNativeWindow* WinUiApplication::FromHWND(HWND hwnd) {
+ for (auto window : windows_) {
+ if (window->GetWindowHandle() == hwnd) {
+ return window;
+ }
+ }
+ return nullptr;
+}
+
+WindowClass* WinUiApplication::GetGeneralWindowClass() {
+ return general_window_class_.get();
+}
+
+void WinUiApplication::RegisterWindow(WinNativeWindow* window) {
+ windows_.push_back(window);
+}
+
+void WinUiApplication::UnregisterWindow(WinNativeWindow* window) {
+ windows_.erase(std::ranges::find(windows_, window));
+}
} // namespace cru::platform::gui::win
diff --git a/src/platform/gui/win/Window.cpp b/src/platform/gui/win/Window.cpp
index af308768..be834a25 100644
--- a/src/platform/gui/win/Window.cpp
+++ b/src/platform/gui/win/Window.cpp
@@ -1,6 +1,5 @@
#include "cru/platform/gui/win/Window.h"
-#include "WindowManager.h"
#include "cru/base/StringUtil.h"
#include "cru/base/log/Logger.h"
#include "cru/platform/graphics/NullPainter.h"
@@ -16,6 +15,7 @@
#include <windowsx.h>
#include <winuser.h>
+#include <algorithm>
#include <memory>
namespace cru::platform::gui::win {
@@ -68,6 +68,7 @@ Rect CalcClientRectFromWindow(const Rect& rect, WindowStyleFlag style_flag,
WinNativeWindow::WinNativeWindow(WinUiApplication* application)
: application_(application) {
+ application->RegisterWindow(this);
input_method_context_ = std::make_unique<WinInputMethodContext>(this);
}
@@ -75,6 +76,7 @@ WinNativeWindow::~WinNativeWindow() { Close(); }
void WinNativeWindow::Close() {
if (hwnd_) ::DestroyWindow(hwnd_);
+ application_->UnregisterWindow(this);
}
void WinNativeWindow::SetParent(INativeWindow* parent) {
@@ -459,8 +461,7 @@ RECT WinNativeWindow::GetClientRectPixel() {
}
void WinNativeWindow::RecreateWindow() {
- const auto window_manager = application_->GetWindowManager();
- auto window_class = window_manager->GetGeneralWindowClass();
+ auto window_class = application_->GetGeneralWindowClass();
hwnd_ = CreateWindowExW(
0, window_class->GetName(), L"", CalcWindowStyle(style_flag_),
@@ -477,7 +478,7 @@ void WinNativeWindow::RecreateWindow() {
dpi_ = static_cast<float>(dpi);
CRU_LOG_TAG_DEBUG("Dpi of window is {}.", dpi_);
- window_manager->RegisterWindow(hwnd_, this);
+ application_->RegisterWindow(this);
SetCursor(application_->GetCursorManager()->GetSystemCursor(
cru::platform::gui::SystemCursorType::Arrow));
@@ -497,8 +498,16 @@ void WinNativeWindow::OnCreateInternal() { create_event_.Raise(nullptr); }
void WinNativeWindow::OnDestroyInternal() {
destroy_event_.Raise(nullptr);
- application_->GetWindowManager()->UnregisterWindow(hwnd_);
+ application_->UnregisterWindow(this);
hwnd_ = nullptr;
+
+ if (application_->IsQuitOnAllWindowClosed() &&
+ std::ranges::all_of(application_->GetAllWinWindow(),
+ [](WinNativeWindow* window) {
+ return window->GetWindowHandle() == nullptr;
+ })) {
+ application_->RequestQuit(0);
+ }
}
void WinNativeWindow::OnPaintInternal() {
diff --git a/src/platform/gui/win/WindowManager.cpp b/src/platform/gui/win/WindowManager.cpp
deleted file mode 100644
index ac172dda..00000000
--- a/src/platform/gui/win/WindowManager.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "WindowManager.h"
-
-#include "cru/platform/gui/win/UiApplication.h"
-#include "cru/platform/gui/win/Window.h"
-#include "cru/platform/gui/win/WindowClass.h"
-
-namespace cru::platform::gui::win {
-LRESULT __stdcall GeneralWndProc(HWND hWnd, UINT Msg, WPARAM wParam,
- LPARAM lParam) {
- auto window =
- WinUiApplication::GetInstance()->GetWindowManager()->FromHandle(hWnd);
-
- LRESULT result;
- if (window != nullptr &&
- window->HandleNativeWindowMessage(hWnd, Msg, wParam, lParam, &result))
- return result;
-
- return DefWindowProc(hWnd, Msg, wParam, lParam);
-}
-
-WindowManager::WindowManager(WinUiApplication* application) {
- application_ = application;
- general_window_class_ = std::make_unique<WindowClass>(
- L"CruUIWindowClass", GeneralWndProc, application->GetInstanceHandle());
-}
-
-WindowManager::~WindowManager() {
- for (const auto& [key, window] : window_map_) delete window;
-}
-
-void WindowManager::RegisterWindow(HWND hwnd, WinNativeWindow* window) {
- Expects(window_map_.count(hwnd) == 0); // The hwnd is already in the map.
- window_map_.emplace(hwnd, window);
-}
-
-void WindowManager::UnregisterWindow(HWND hwnd) {
- const auto find_result = window_map_.find(hwnd);
- Expects(find_result != window_map_.end()); // The hwnd is not in the map.
- window_map_.erase(find_result);
- if (window_map_.empty() && application_->IsQuitOnAllWindowClosed())
- application_->RequestQuit(0);
-}
-
-WinNativeWindow* WindowManager::FromHandle(HWND hwnd) {
- const auto find_result = window_map_.find(hwnd);
- if (find_result == window_map_.end())
- return nullptr;
- else
- return find_result->second;
-}
-
-std::vector<WinNativeWindow*> WindowManager::GetAllWindows() const {
- std::vector<WinNativeWindow*> windows;
- for (const auto& [key, value] : window_map_) windows.push_back(value);
- return windows;
-}
-} // namespace cru::platform::gui::win
diff --git a/src/platform/gui/win/WindowManager.h b/src/platform/gui/win/WindowManager.h
deleted file mode 100644
index e674c951..00000000
--- a/src/platform/gui/win/WindowManager.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#pragma once
-#include "cru/base/platform/win/Base.h"
-
-#include <map>
-#include <memory>
-#include <vector>
-
-namespace cru::platform::gui::win {
-class WinUiApplication;
-class WinNativeWindow;
-class WindowClass;
-
-class WindowManager : public Object {
- public:
- WindowManager(WinUiApplication* application);
- ~WindowManager() override;
-
- // Get the general window class for creating ordinary window.
- WindowClass* GetGeneralWindowClass() const {
- return general_window_class_.get();
- }
-
- // Register a window newly created.
- // This function adds the hwnd to hwnd-window map.
- // It should be called immediately after a window was created.
- void RegisterWindow(HWND hwnd, WinNativeWindow* window);
-
- // Unregister a window that is going to be destroyed.
- // This function removes the hwnd from the hwnd-window map.
- // It should be called immediately before a window is going to be destroyed,
- void UnregisterWindow(HWND hwnd);
-
- // Return a pointer to the Window object related to the HWND or nullptr if the
- // hwnd is not in the map.
- WinNativeWindow* FromHandle(HWND hwnd);
-
- std::vector<WinNativeWindow*> GetAllWindows() const;
-
- private:
- WinUiApplication* application_;
-
- std::unique_ptr<WindowClass> general_window_class_;
- std::map<HWND, WinNativeWindow*> window_map_;
-};
-} // namespace cru::platform::gui::win