diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/platform/gui/win/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/platform/gui/win/UiApplication.cpp | 51 | ||||
| -rw-r--r-- | src/platform/gui/win/Window.cpp | 19 | ||||
| -rw-r--r-- | src/platform/gui/win/WindowManager.cpp | 57 | ||||
| -rw-r--r-- | src/platform/gui/win/WindowManager.h | 45 |
5 files changed, 56 insertions, 117 deletions
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 |
