aboutsummaryrefslogtreecommitdiff
path: root/src/win/gui/Window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/win/gui/Window.cpp')
-rw-r--r--src/win/gui/Window.cpp62
1 files changed, 57 insertions, 5 deletions
diff --git a/src/win/gui/Window.cpp b/src/win/gui/Window.cpp
index 20f86aff..827cc0a8 100644
--- a/src/win/gui/Window.cpp
+++ b/src/win/gui/Window.cpp
@@ -15,6 +15,7 @@
#include "cru/win/gui/WindowClass.hpp"
#include <windowsx.h>
+#include <winuser.h>
namespace cru::platform::gui::win {
namespace {
@@ -47,6 +48,21 @@ Rect CalcWindowRectFromClient(const Rect& rect, WindowStyleFlag style_flag,
return result;
}
+Rect CalcClientRectFromWindow(const Rect& rect, WindowStyleFlag style_flag,
+ float dpi) {
+ RECT o{100, 100, 500, 500};
+ RECT s = o;
+ if (!AdjustWindowRectEx(&s, CalcWindowStyle(style_flag), FALSE, 0))
+ throw Win32Error(::GetLastError(), "Failed to invoke AdjustWindowRectEx.");
+
+ Rect result = rect;
+ result.Shrink(Thickness(PixelToDip(s.left - o.left, dpi),
+ PixelToDip(o.top - s.top, dpi),
+ PixelToDip(s.right - o.right, dpi),
+ PixelToDip(s.bottom - o.bottom, dpi)));
+
+ return result;
+}
} // namespace
WinNativeWindow::WinNativeWindow(WinUiApplication* application)
@@ -60,6 +76,15 @@ void WinNativeWindow::Close() {
if (hwnd_) ::DestroyWindow(hwnd_);
}
+void WinNativeWindow::SetParent(INativeWindow *parent) {
+ auto p = CheckPlatform<WinNativeWindow>(parent, GetPlatformId());
+ parent_window_ = p;
+
+ if (hwnd_) {
+ ::SetParent(hwnd_, parent_window_->hwnd_);
+ }
+}
+
void WinNativeWindow::SetStyleFlag(WindowStyleFlag flag) {
if (flag == style_flag_) return;
@@ -108,11 +133,11 @@ void WinNativeWindow::SetClientRect(const Rect& rect) {
client_rect_ = rect;
if (hwnd_) {
- RECT rect =
+ RECT r =
DipToPixel(CalcWindowRectFromClient(client_rect_, style_flag_, dpi_));
- if (!SetWindowPos(hwnd_, nullptr, 0, 0, rect.right - rect.left,
- rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE))
+ if (!SetWindowPos(hwnd_, nullptr, 0, 0, r.right - r.left, r.bottom - r.top,
+ SWP_NOZORDER | SWP_NOMOVE))
throw Win32Error(::GetLastError(), "Failed to invoke SetWindowPos.");
}
}
@@ -126,11 +151,13 @@ Rect WinNativeWindow::GetWindowRect() {
return Rect::FromVertices(PixelToDip(rect.left), PixelToDip(rect.top),
PixelToDip(rect.right), PixelToDip(rect.bottom));
} else {
- return {};
+ return CalcWindowRectFromClient(client_rect_, style_flag_, dpi_);
}
}
void WinNativeWindow::SetWindowRect(const Rect& rect) {
+ client_rect_ = CalcClientRectFromWindow(rect, style_flag_, dpi_);
+
if (hwnd_) {
if (!SetWindowPos(hwnd_, nullptr, DipToPixel(rect.left),
DipToPixel(rect.top), DipToPixel(rect.GetRight()),
@@ -139,6 +166,14 @@ void WinNativeWindow::SetWindowRect(const Rect& rect) {
}
}
+bool WinNativeWindow::RequestFocus() {
+ if (hwnd_) {
+ SetFocus(hwnd_);
+ return true;
+ }
+ return false;
+}
+
Point WinNativeWindow::GetMousePosition() {
POINT p;
if (!::GetCursorPos(&p))
@@ -193,7 +228,7 @@ void WinNativeWindow::SetCursor(std::shared_ptr<ICursor> cursor) {
if (GetVisibility() != WindowVisibilityType::Show) return;
- auto lg = [](const std::u16string_view& reason) {
+ auto lg = [](StringView reason) {
log::TagWarn(
log_tag,
u"Failed to set cursor because {} when window is visible. (We need to "
@@ -348,6 +383,14 @@ 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;
+ return true;
case WM_SIZE:
OnResizeInternal(LOWORD(l_param), HIWORD(l_param));
*result = 0;
@@ -427,6 +470,8 @@ void WinNativeWindow::RecreateWindow() {
input_method_context_->DisableIME();
}
+void WinNativeWindow::OnCreateInternal() { create_event_.Raise(nullptr); }
+
void WinNativeWindow::OnDestroyInternal() {
destroy_event_.Raise(nullptr);
application_->GetWindowManager()->UnregisterWindow(hwnd_);
@@ -441,8 +486,15 @@ void WinNativeWindow::OnPaintInternal() {
}
}
+void WinNativeWindow::OnMoveInternal(const int new_left, const int new_top) {
+ client_rect_.left = PixelToDip(new_left);
+ client_rect_.top = PixelToDip(new_top);
+}
+
void WinNativeWindow::OnResizeInternal(const int new_width,
const int new_height) {
+ client_rect_.width = PixelToDip(new_width);
+ client_rect_.height = PixelToDip(new_height);
if (!(new_width == 0 && new_height == 0)) {
window_render_target_->ResizeBuffer(new_width, new_height);
resize_event_.Raise(Size{PixelToDip(new_width), PixelToDip(new_height)});