11#include < dwmapi.h>
22#include < windows.h>
3+ #include < cmath>
34#include < iostream>
45#include " ../../foundation/id_allocator.h"
56#include " ../../window.h"
@@ -346,8 +347,14 @@ bool Window::IsFullScreen() const {
346347
347348void Window::SetBounds (Rectangle bounds) {
348349 if (pimpl_->hwnd_ ) {
349- SetWindowPos (pimpl_->hwnd_ , nullptr , static_cast <int >(bounds.x ), static_cast <int >(bounds.y ),
350- static_cast <int >(bounds.width ), static_cast <int >(bounds.height ), SWP_NOZORDER);
350+ double scale = GetScaleFactorForWindow (pimpl_->hwnd_ );
351+ if (scale <= 0.0 )
352+ scale = 1.0 ;
353+ SetWindowPos (pimpl_->hwnd_ , nullptr ,
354+ static_cast <int >(std::lround (bounds.x * scale)),
355+ static_cast <int >(std::lround (bounds.y * scale)),
356+ static_cast <int >(std::lround (bounds.width * scale)),
357+ static_cast <int >(std::lround (bounds.height * scale)), SWP_NOZORDER);
351358 }
352359}
353360
@@ -356,10 +363,13 @@ Rectangle Window::GetBounds() const {
356363 if (pimpl_->hwnd_ ) {
357364 RECT rect;
358365 GetWindowRect (pimpl_->hwnd_ , &rect);
359- bounds.x = rect.left ;
360- bounds.y = rect.top ;
361- bounds.width = rect.right - rect.left ;
362- bounds.height = rect.bottom - rect.top ;
366+ double scale = GetScaleFactorForWindow (pimpl_->hwnd_ );
367+ if (scale <= 0.0 )
368+ scale = 1.0 ;
369+ bounds.x = static_cast <double >(rect.left ) / scale;
370+ bounds.y = static_cast <double >(rect.top ) / scale;
371+ bounds.width = static_cast <double >(rect.right - rect.left ) / scale;
372+ bounds.height = static_cast <double >(rect.bottom - rect.top ) / scale;
363373 }
364374 return bounds;
365375}
@@ -368,8 +378,13 @@ void Window::SetSize(Size size, bool animate) {
368378 if (pimpl_->hwnd_ ) {
369379 // Windows doesn't have built-in animation for window resizing
370380 // Animation would require custom implementation
371- SetWindowPos (pimpl_->hwnd_ , nullptr , 0 , 0 , static_cast <int >(size.width ),
372- static_cast <int >(size.height ), SWP_NOMOVE | SWP_NOZORDER);
381+ double scale = GetScaleFactorForWindow (pimpl_->hwnd_ );
382+ if (scale <= 0.0 )
383+ scale = 1.0 ;
384+ SetWindowPos (pimpl_->hwnd_ , nullptr , 0 , 0 ,
385+ static_cast <int >(std::lround (size.width * scale)),
386+ static_cast <int >(std::lround (size.height * scale)),
387+ SWP_NOMOVE | SWP_NOZORDER);
373388 }
374389}
375390
@@ -378,8 +393,11 @@ Size Window::GetSize() const {
378393 if (pimpl_->hwnd_ ) {
379394 RECT rect;
380395 GetWindowRect (pimpl_->hwnd_ , &rect);
381- size.width = rect.right - rect.left ;
382- size.height = rect.bottom - rect.top ;
396+ double scale = GetScaleFactorForWindow (pimpl_->hwnd_ );
397+ if (scale <= 0.0 )
398+ scale = 1.0 ;
399+ size.width = static_cast <double >(rect.right - rect.left ) / scale;
400+ size.height = static_cast <double >(rect.bottom - rect.top ) / scale;
383401 }
384402 return size;
385403}
@@ -394,8 +412,13 @@ void Window::SetContentSize(Size size) {
394412 int borderWidth = (windowRect.right - windowRect.left ) - clientRect.right ;
395413 int borderHeight = (windowRect.bottom - windowRect.top ) - clientRect.bottom ;
396414
397- SetWindowPos (pimpl_->hwnd_ , nullptr , 0 , 0 , static_cast <int >(size.width ) + borderWidth,
398- static_cast <int >(size.height ) + borderHeight, SWP_NOMOVE | SWP_NOZORDER);
415+ double scale = GetScaleFactorForWindow (pimpl_->hwnd_ );
416+ if (scale <= 0.0 )
417+ scale = 1.0 ;
418+ SetWindowPos (pimpl_->hwnd_ , nullptr , 0 , 0 ,
419+ static_cast <int >(std::lround (size.width * scale)) + borderWidth,
420+ static_cast <int >(std::lround (size.height * scale)) + borderHeight,
421+ SWP_NOMOVE | SWP_NOZORDER);
399422 }
400423}
401424
@@ -404,8 +427,11 @@ Size Window::GetContentSize() const {
404427 if (pimpl_->hwnd_ ) {
405428 RECT rect;
406429 GetClientRect (pimpl_->hwnd_ , &rect);
407- size.width = rect.right ;
408- size.height = rect.bottom ;
430+ double scale = GetScaleFactorForWindow (pimpl_->hwnd_ );
431+ if (scale <= 0.0 )
432+ scale = 1.0 ;
433+ size.width = static_cast <double >(rect.right ) / scale;
434+ size.height = static_cast <double >(rect.bottom ) / scale;
409435 }
410436 return size;
411437}
@@ -428,11 +454,15 @@ void Window::SetContentBounds(Rectangle bounds) {
428454 int offsetX = clientTopLeft.x - windowRect.left ;
429455 int offsetY = clientTopLeft.y - windowRect.top ;
430456
457+ double scale = GetScaleFactorForWindow (pimpl_->hwnd_ );
458+ if (scale <= 0.0 )
459+ scale = 1.0 ;
460+
431461 // Calculate window position so that client area is at bounds position
432- int windowX = static_cast <int >(bounds.x ) - offsetX;
433- int windowY = static_cast <int >(bounds.y ) - offsetY;
434- int windowWidth = static_cast <int >(bounds.width ) + borderWidth;
435- int windowHeight = static_cast <int >(bounds.height ) + borderHeight;
462+ int windowX = static_cast <int >(std::lround ( bounds.x * scale) ) - offsetX;
463+ int windowY = static_cast <int >(std::lround ( bounds.y * scale) ) - offsetY;
464+ int windowWidth = static_cast <int >(std::lround ( bounds.width * scale) ) + borderWidth;
465+ int windowHeight = static_cast <int >(std::lround ( bounds.height * scale) ) + borderHeight;
436466
437467 SetWindowPos (pimpl_->hwnd_ , nullptr , windowX, windowY, windowWidth, windowHeight, SWP_NOZORDER);
438468 }
@@ -488,13 +518,16 @@ static int RegisterMinMaxInfoHandler(HWND hwnd, int existing_handler_id) {
488518 auto minSize = window->GetMinimumSize ();
489519 auto maxSize = window->GetMaximumSize ();
490520 MINMAXINFO* mmi = reinterpret_cast <MINMAXINFO*>(lparam);
521+ double scale_mm = GetScaleFactorForWindow (hwnd);
522+ if (scale_mm <= 0.0 )
523+ scale_mm = 1.0 ;
491524 if (minSize.width > 0 && minSize.height > 0 ) {
492- mmi->ptMinTrackSize .x = static_cast <LONG>(minSize.width );
493- mmi->ptMinTrackSize .y = static_cast <LONG>(minSize.height );
525+ mmi->ptMinTrackSize .x = static_cast <LONG>(std::lround ( minSize.width * scale_mm) );
526+ mmi->ptMinTrackSize .y = static_cast <LONG>(std::lround ( minSize.height * scale_mm) );
494527 }
495528 if (maxSize.width > 0 && maxSize.height > 0 ) {
496- mmi->ptMaxTrackSize .x = static_cast <LONG>(maxSize.width );
497- mmi->ptMaxTrackSize .y = static_cast <LONG>(maxSize.height );
529+ mmi->ptMaxTrackSize .x = static_cast <LONG>(std::lround ( maxSize.width * scale_mm) );
530+ mmi->ptMaxTrackSize .y = static_cast <LONG>(std::lround ( maxSize.height * scale_mm) );
498531 }
499532 return std::make_optional (0 );
500533 }
@@ -668,8 +701,13 @@ bool Window::IsAlwaysOnTop() const {
668701
669702void Window::SetPosition (Point point) {
670703 if (pimpl_->hwnd_ ) {
671- SetWindowPos (pimpl_->hwnd_ , nullptr , static_cast <int >(point.x ), static_cast <int >(point.y ), 0 , 0 ,
672- SWP_NOSIZE | SWP_NOZORDER);
704+ double scale = GetScaleFactorForWindow (pimpl_->hwnd_ );
705+ if (scale <= 0.0 )
706+ scale = 1.0 ;
707+ SetWindowPos (pimpl_->hwnd_ , nullptr ,
708+ static_cast <int >(std::lround (point.x * scale)),
709+ static_cast <int >(std::lround (point.y * scale)),
710+ 0 , 0 , SWP_NOSIZE | SWP_NOZORDER);
673711 }
674712}
675713
@@ -678,8 +716,11 @@ Point Window::GetPosition() const {
678716 if (pimpl_->hwnd_ ) {
679717 RECT rect;
680718 GetWindowRect (pimpl_->hwnd_ , &rect);
681- point.x = rect.left ;
682- point.y = rect.top ;
719+ double scale = GetScaleFactorForWindow (pimpl_->hwnd_ );
720+ if (scale <= 0.0 )
721+ scale = 1.0 ;
722+ point.x = static_cast <double >(rect.left ) / scale;
723+ point.y = static_cast <double >(rect.top ) / scale;
683724 }
684725 return point;
685726}
@@ -700,6 +741,7 @@ void Window::Center() {
700741 GetMonitorInfo (monitor, &mi);
701742
702743 // Calculate the center position on the monitor's work area
744+ // All values here are in physical pixels (GetWindowRect and rcWork), so no DPI scaling needed
703745 int centerX = mi.rcWork .left + (mi.rcWork .right - mi.rcWork .left - windowWidth) / 2 ;
704746 int centerY = mi.rcWork .top + (mi.rcWork .bottom - mi.rcWork .top - windowHeight) / 2 ;
705747
0 commit comments