aboutsummaryrefslogtreecommitdiff
path: root/src/win/native/window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/win/native/window.cpp')
-rw-r--r--src/win/native/window.cpp130
1 files changed, 53 insertions, 77 deletions
diff --git a/src/win/native/window.cpp b/src/win/native/window.cpp
index a8016676..2e99a5cb 100644
--- a/src/win/native/window.cpp
+++ b/src/win/native/window.cpp
@@ -23,10 +23,12 @@ inline Point PiToDip(const POINT& pi_point) {
WinNativeWindow::WinNativeWindow(WinUiApplication* application,
WindowClass* window_class, DWORD window_style,
WinNativeWindow* parent)
- : application_(application), parent_window_(parent) {
+ : application_(application),
+ resolver_(std::make_shared<WinNativeWindowResolver>(this)),
+ parent_window_(parent) {
assert(application); // application can't be null.
- if (parent != nullptr && !parent->IsValid()) {
+ if (parent != nullptr) {
throw new std::runtime_error("Can't use a invalid window as parent.");
}
@@ -51,63 +53,45 @@ WinNativeWindow::WinNativeWindow(WinUiApplication* application,
}
WinNativeWindow::~WinNativeWindow() {
- if (IsValid()) {
- SetDeleteThisOnDestroy(false); // avoid double delete.
+ if (!sync_flag_) {
+ sync_flag_ = true;
Close();
}
+ resolver_->Reset();
}
-bool WinNativeWindow::IsValid() { return hwnd_ != nullptr; }
+void WinNativeWindow::Close() { ::DestroyWindow(hwnd_); }
-void WinNativeWindow::SetDeleteThisOnDestroy(bool value) {
- delete_this_on_destroy_ = value;
-}
-
-void WinNativeWindow::Close() {
- if (IsValid()) DestroyWindow(hwnd_);
-}
-
-bool WinNativeWindow::IsVisible() {
- if (IsValid()) return ::IsWindowVisible(hwnd_);
- return false;
-}
+bool WinNativeWindow::IsVisible() { return ::IsWindowVisible(hwnd_); }
void WinNativeWindow::SetVisible(bool is_visible) {
- if (!IsValid()) return;
is_visible ? ShowWindow(hwnd_, SW_SHOWNORMAL) : ShowWindow(hwnd_, SW_HIDE);
}
Size WinNativeWindow::GetClientSize() {
- if (!IsValid()) return Size{};
-
const auto pixel_rect = GetClientRectPixel();
return Size(PixelToDipX(pixel_rect.right), PixelToDipY(pixel_rect.bottom));
}
void WinNativeWindow::SetClientSize(const Size& size) {
- if (IsValid()) {
- const auto window_style =
- static_cast<DWORD>(GetWindowLongPtr(hwnd_, GWL_STYLE));
- const auto window_ex_style =
- static_cast<DWORD>(GetWindowLongPtr(hwnd_, GWL_EXSTYLE));
-
- RECT rect;
- rect.left = 0;
- rect.top = 0;
- rect.right = DipToPixelX(size.width);
- rect.bottom = DipToPixelY(size.height);
- if (!AdjustWindowRectEx(&rect, window_style, FALSE, window_ex_style))
- throw Win32Error(::GetLastError(),
- "Failed to invoke AdjustWindowRectEx.");
-
- if (!SetWindowPos(hwnd_, nullptr, 0, 0, rect.right - rect.left,
- rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE))
- throw Win32Error(::GetLastError(), "Failed to invoke SetWindowPos.");
- }
+ const auto window_style =
+ static_cast<DWORD>(GetWindowLongPtr(hwnd_, GWL_STYLE));
+ const auto window_ex_style =
+ static_cast<DWORD>(GetWindowLongPtr(hwnd_, GWL_EXSTYLE));
+
+ RECT rect;
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = DipToPixelX(size.width);
+ rect.bottom = DipToPixelY(size.height);
+ if (!AdjustWindowRectEx(&rect, window_style, FALSE, window_ex_style))
+ throw Win32Error(::GetLastError(), "Failed to invoke AdjustWindowRectEx.");
+
+ if (!SetWindowPos(hwnd_, nullptr, 0, 0, rect.right - rect.left,
+ rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE))
+ throw Win32Error(::GetLastError(), "Failed to invoke SetWindowPos.");
}
Rect WinNativeWindow::GetWindowRect() {
- if (!IsValid()) return Rect{};
-
RECT rect;
if (!::GetWindowRect(hwnd_, &rect))
throw Win32Error(::GetLastError(), "Failed to invoke GetWindowRect.");
@@ -117,50 +101,37 @@ Rect WinNativeWindow::GetWindowRect() {
}
void WinNativeWindow::SetWindowRect(const Rect& rect) {
- if (IsValid()) {
- if (!SetWindowPos(hwnd_, nullptr, DipToPixelX(rect.left),
- DipToPixelY(rect.top), DipToPixelX(rect.GetRight()),
- DipToPixelY(rect.GetBottom()), SWP_NOZORDER))
- throw Win32Error(::GetLastError(), "Failed to invoke SetWindowPos.");
- }
+ if (!SetWindowPos(hwnd_, nullptr, DipToPixelX(rect.left),
+ DipToPixelY(rect.top), DipToPixelX(rect.GetRight()),
+ DipToPixelY(rect.GetBottom()), SWP_NOZORDER))
+ throw Win32Error(::GetLastError(), "Failed to invoke SetWindowPos.");
}
Point WinNativeWindow::GetMousePosition() {
- if (IsValid()) {
- POINT p;
- if (!::GetCursorPos(&p))
- throw Win32Error(::GetLastError(), "Failed to get cursor position.");
- if (!::ScreenToClient(hwnd_, &p))
- throw Win32Error(::GetLastError(), "Failed to call ScreenToClient.");
- return PiToDip(p);
- }
- return Point{};
+ POINT p;
+ if (!::GetCursorPos(&p))
+ throw Win32Error(::GetLastError(), "Failed to get cursor position.");
+ if (!::ScreenToClient(hwnd_, &p))
+ throw Win32Error(::GetLastError(), "Failed to call ScreenToClient.");
+ return PiToDip(p);
}
bool WinNativeWindow::CaptureMouse() {
- if (IsValid()) {
- ::SetCapture(hwnd_);
- return true;
- }
- return false;
+ ::SetCapture(hwnd_);
+ return true;
}
bool WinNativeWindow::ReleaseMouse() {
- if (IsValid()) {
- const auto result = ::ReleaseCapture();
- return result != 0;
- }
- return false;
+ const auto result = ::ReleaseCapture();
+ return result != 0;
}
void WinNativeWindow::RequestRepaint() {
- if (IsValid()) {
- log::Debug("A repaint is requested.");
- if (!::InvalidateRect(hwnd_, nullptr, FALSE))
- throw Win32Error(::GetLastError(), "Failed to invalidate window.");
- if (!::UpdateWindow(hwnd_))
- throw Win32Error(::GetLastError(), "Failed to update window.");
- }
+ log::Debug("A repaint is requested.");
+ if (!::InvalidateRect(hwnd_, nullptr, FALSE))
+ throw Win32Error(::GetLastError(), "Failed to invalidate window.");
+ if (!::UpdateWindow(hwnd_))
+ throw Win32Error(::GetLastError(), "Failed to update window.");
}
std::unique_ptr<graph::IPainter> WinNativeWindow::BeginPaint() {
@@ -172,8 +143,6 @@ void WinNativeWindow::SetCursor(std::shared_ptr<ICursor> cursor) {
throw std::runtime_error("Can't use a nullptr as cursor.");
}
- if (!IsValid()) return;
-
cursor_ = CheckPlatform<WinCursor>(cursor, GetPlatformId());
if (!::SetClassLongPtrW(hwnd_, GCLP_HCURSOR,
@@ -358,8 +327,10 @@ void WinNativeWindow::OnDestroyInternal() {
application_->GetWindowManager()->UnregisterWindow(hwnd_);
hwnd_ = nullptr;
destroy_event_.Raise(nullptr);
- if (delete_this_on_destroy_)
- application_->InvokeLater([this] { delete this; });
+ if (!sync_flag_) {
+ sync_flag_ = true;
+ delete this;
+ }
}
void WinNativeWindow::OnPaintInternal() {
@@ -438,4 +409,9 @@ void WinNativeWindow::OnCharInternal(wchar_t c) { CRU_UNUSED(c) }
void WinNativeWindow::OnActivatedInternal() {}
void WinNativeWindow::OnDeactivatedInternal() {}
+
+void WinNativeWindowResolver::Reset() {
+ assert(window_); // already reset, can't reset again
+ window_ = nullptr;
+}
} // namespace cru::platform::native::win