From 1ef4651c4002eb3a155bcd36fed1e5b6b63b1c80 Mon Sep 17 00:00:00 2001 From: Yuqian Yang Date: Sun, 16 Nov 2025 15:43:20 +0800 Subject: Fix some part of WinWindow. --- src/platform/gui/win/Window.cpp | 50 +++++++++++++++++++++--------- src/ui/components/Menu.cpp | 5 +-- src/ui/controls/RootControl.cpp | 2 -- src/ui/controls/TextHostControlService.cpp | 6 ++-- 4 files changed, 43 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/platform/gui/win/Window.cpp b/src/platform/gui/win/Window.cpp index be834a25..95c840c3 100644 --- a/src/platform/gui/win/Window.cpp +++ b/src/platform/gui/win/Window.cpp @@ -21,7 +21,7 @@ namespace cru::platform::gui::win { namespace { inline int DipToPixel(const float dip, const float dpi) { - return static_cast(dip * dpi / 96.0f); + return static_cast(std::ceil(dip * dpi / 96.0f)); } inline float PixelToDip(const int pixel, const float dpi) { @@ -72,7 +72,10 @@ WinNativeWindow::WinNativeWindow(WinUiApplication* application) input_method_context_ = std::make_unique(this); } -WinNativeWindow::~WinNativeWindow() { Close(); } +WinNativeWindow::~WinNativeWindow() { + Close(); + application_->UnregisterWindow(this); +} void WinNativeWindow::Close() { if (hwnd_) ::DestroyWindow(hwnd_); @@ -109,11 +112,17 @@ void WinNativeWindow::SetStyleFlag(WindowStyleFlag flag) { } } -void WinNativeWindow::SetVisibility(WindowVisibilityType visibility) { - if (visibility == visibility_) return; - visibility_ = visibility; +WindowVisibilityType WinNativeWindow::GetVisibility() { + if (!hwnd_) return WindowVisibilityType::Hide; + if (IsIconic(hwnd_)) return WindowVisibilityType::Minimize; + return IsWindowVisible(hwnd_) ? WindowVisibilityType::Show + : WindowVisibilityType::Hide; +} + +void WinNativeWindow::SetVisibility(WindowVisibilityType visibility) { if (!hwnd_) { + if (visibility == WindowVisibilityType::Hide) return; RecreateWindow(); } @@ -129,6 +138,9 @@ void WinNativeWindow::SetVisibility(WindowVisibilityType visibility) { Size WinNativeWindow::GetClientSize() { return GetClientRect().GetSize(); } void WinNativeWindow::SetClientSize(const Size& size) { + CRU_LOG_TAG_INFO("{} set client size to {}.", + static_cast(GetWindowHandle()), size); + client_rect_.SetSize(size); if (hwnd_) { @@ -144,14 +156,17 @@ void WinNativeWindow::SetClientSize(const Size& size) { Rect WinNativeWindow::GetClientRect() { return client_rect_; } void WinNativeWindow::SetClientRect(const Rect& rect) { + CRU_LOG_TAG_INFO("{} set client rect to {}.", + static_cast(GetWindowHandle()), rect); + client_rect_ = rect; if (hwnd_) { RECT r = DipToPixel(CalcWindowRectFromClient(client_rect_, style_flag_, dpi_)); - if (!SetWindowPos(hwnd_, nullptr, 0, 0, r.right - r.left, r.bottom - r.top, - SWP_NOZORDER | SWP_NOMOVE)) + if (!SetWindowPos(hwnd_, nullptr, r.left, r.top, r.right - r.left, + r.bottom - r.top, SWP_NOZORDER)) throw Win32Error(::GetLastError(), "Failed to invoke SetWindowPos."); } } @@ -170,6 +185,9 @@ Rect WinNativeWindow::GetWindowRect() { } void WinNativeWindow::SetWindowRect(const Rect& rect) { + CRU_LOG_TAG_INFO("{} set window rect to {}.", + static_cast(GetWindowHandle()), rect); + client_rect_ = CalcClientRectFromWindow(rect, style_flag_, dpi_); if (hwnd_) { @@ -406,10 +424,6 @@ bool WinNativeWindow::HandleNativeWindowMessage(HWND hwnd, UINT msg, return true; } return false; - case WM_CREATE: - OnCreateInternal(); - *result = 0; - return true; case WM_MOVE: OnMoveInternal(LOWORD(l_param), HIWORD(l_param)); *result = 0; @@ -472,11 +486,14 @@ void WinNativeWindow::RecreateWindow() { if (hwnd_ == nullptr) throw Win32Error(::GetLastError(), "Failed to create window."); + OnCreateInternal(); + auto dpi = ::GetDpiForWindow(hwnd_); if (dpi == 0) throw Win32Error(::GetLastError(), "Failed to get dpi of window."); dpi_ = static_cast(dpi); - CRU_LOG_TAG_DEBUG("Dpi of window is {}.", dpi_); + CRU_LOG_TAG_DEBUG("Dpi of window {} is {}.", + static_cast(GetWindowHandle()), dpi_); application_->RegisterWindow(this); @@ -494,11 +511,16 @@ void WinNativeWindow::RecreateWindow() { input_method_context_->DisableIME(); } -void WinNativeWindow::OnCreateInternal() { create_event_.Raise(nullptr); } +void WinNativeWindow::OnCreateInternal() { + CRU_LOG_TAG_DEBUG("A native window is created, hwnd {}.", + static_cast(GetWindowHandle())); + create_event_.Raise(nullptr); +} void WinNativeWindow::OnDestroyInternal() { + CRU_LOG_TAG_DEBUG("A native window is destroying, hwnd {}.", + static_cast(GetWindowHandle())); destroy_event_.Raise(nullptr); - application_->UnregisterWindow(this); hwnd_ = nullptr; if (application_->IsQuitOnAllWindowClosed() && diff --git a/src/ui/components/Menu.cpp b/src/ui/components/Menu.cpp index 59bcf8ec..fa594399 100644 --- a/src/ui/components/Menu.cpp +++ b/src/ui/components/Menu.cpp @@ -91,13 +91,14 @@ PopupMenu::~PopupMenu() {} controls::Control* PopupMenu::GetRootControl() { return &popup_; } void PopupMenu::SetPosition(const Point& position) { - popup_.GetWindowHost()->GetNativeWindow()->SetClientRect(Rect{position, {}}); + auto window = popup_.GetWindowHost()->GetNativeWindow(); + window->SetClientRect(Rect{position, window->GetClientSize()}); } void PopupMenu::Show() { - popup_.GetWindowHost()->RelayoutWithSize(Size::Infinite(), true); auto native_window = popup_.GetWindowHost()->GetNativeWindow(); native_window->SetVisibility(platform::gui::WindowVisibilityType::Show); + popup_.GetWindowHost()->RelayoutWithSize(Size::Infinite(), true); native_window->RequestFocus(); native_window->SetToForeground(); } diff --git a/src/ui/controls/RootControl.cpp b/src/ui/controls/RootControl.cpp index 1bb2e7ee..7be1c630 100644 --- a/src/ui/controls/RootControl.cpp +++ b/src/ui/controls/RootControl.cpp @@ -1,7 +1,5 @@ #include "cru/ui/controls/RootControl.h" -#include "cru/base/Base.h" -#include "cru/platform/gui/Base.h" #include "cru/platform/gui/Window.h" #include "cru/ui/Base.h" #include "cru/ui/host/WindowHost.h" diff --git a/src/ui/controls/TextHostControlService.cpp b/src/ui/controls/TextHostControlService.cpp index b2fbd61d..06c1651f 100644 --- a/src/ui/controls/TextHostControlService.cpp +++ b/src/ui/controls/TextHostControlService.cpp @@ -273,7 +273,8 @@ void TextHostControlService::DeleteText(TextRange range, range = range.Normalize(); if (!Utf8IsValidInsertPosition(this->text_.data(), this->text_.size(), range.GetStart())) { - CRU_LOG_TAG_ERROR("Invalid text delete start position {}.", range.GetStart()); + CRU_LOG_TAG_ERROR("Invalid text delete start position {}.", + range.GetStart()); return; } if (!Utf8IsValidInsertPosition(this->text_.data(), this->text_.size(), @@ -701,6 +702,7 @@ void TextHostControlService::OpenContextMenu(const Point& position, ContextMenuItem items) { CRU_LOG_TAG_DEBUG("Open context menu."); auto menu = context_menu_->GetMenu(); + menu->ClearItems(); if (items & ContextMenuItem::kSelectAll) { menu->AddTextItem("Select All", [this] { this->SelectAll(); }); } @@ -713,8 +715,8 @@ void TextHostControlService::OpenContextMenu(const Point& position, if (items & ContextMenuItem::kPaste) { menu->AddTextItem("Paste", [this] { this->Paste(); }); } - context_menu_->SetPosition(position); context_menu_->Show(); + context_menu_->SetPosition(position); } } // namespace cru::ui::controls -- cgit v1.2.3