From c7e8399c277ad7a7476112be985139a4ae0a62ed Mon Sep 17 00:00:00 2001 From: Paolo Messina Date: Mon, 2 Sep 2024 18:06:49 +0200 Subject: [PATCH] Fix maximized appearance on Windows 10/11 --- ResizableDialog/DemoDlg.cpp | 78 +++++++++++++++++++++++++++++++------ ResizableDialog/DemoDlg.h | 2 + 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/ResizableDialog/DemoDlg.cpp b/ResizableDialog/DemoDlg.cpp index f1dd8a1..65963cc 100644 --- a/ResizableDialog/DemoDlg.cpp +++ b/ResizableDialog/DemoDlg.cpp @@ -99,17 +99,7 @@ BOOL CDemoDlg::OnInitDialog() _T("Isn't it cool?")); // min/max size settings - - // get desktop size - CRect rc; - GetDesktopWindow()->GetClientRect(&rc); - - // set max tracking size to half a screen - SetMaxTrackSize(CSize(rc.Width(), rc.Height()/2)); - - // maximized position and size on top of the screen - rc.bottom = 100; - SetMaximizedRect(rc); + UpdateMaxSize(); // save/restore // (for dialog based app, default is a .INI file with @@ -119,11 +109,62 @@ BOOL CDemoDlg::OnInitDialog() return FALSE; // return TRUE unless you set the focus to a control } +void CDemoDlg::UpdateMaxSize() +{ + ResetMaxTrackSize(); + ResetMaximizedRect(); + + // get desktop size + CRect rcMax; + GetDesktopWindow()->GetClientRect(&rcMax); + + if (GetThemeAppProperties() & STAP_ALLOW_NONCLIENT) + { + // modern style windows use the borders for drop-shadow effects but window size appears smaller when maximized + // try to determine the correct size for maximized state, based on the current style + CRect rcWnd, rcClient, rcMargins; + GetWindowRect(&rcWnd); + GetClientRect(&rcClient); + ::MapWindowPoints(GetSafeHwnd(), NULL, (LPPOINT)&rcClient, 2); + + rcMargins.left = rcClient.left - rcWnd.left; + rcMargins.top = rcClient.top - rcWnd.top - GetSystemMetrics(GetExStyle() & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION); + rcMargins.right = rcWnd.right - rcClient.right; + rcMargins.bottom = rcWnd.bottom - rcClient.bottom; + + rcMax.InflateRect(&rcMargins); + } + // use half height for tracking size limits + int half = rcMax.Height() / 2; + // clip maximized size to the top 100 pixels + rcMax.bottom = 100; + + // maximized position and size on top of the screen + SetMaximizedRect(rcMax); + + // limit max tracking size to half a screen vertically + SetMaxTrackSize(CSize(rcMax.Width(), half)); + + if (IsZoomed()) + { + // window already maximized needs to be refreshed, but we try to avoid flickering + // when you disable redraw the window loses WS_VISIBLE but stay displayed on the screen + // so the only chance is to use SW_HIDE to change the maximized state without affecting visibility + // (any other show command would make the window appear again and flash, or it won't refresh the maximized state) + // then we maximize again, which implies the window will also be visible and then we restore redraw + SetRedraw(FALSE); + ShowWindow(SW_HIDE); + ShowWindow(SW_SHOWMAXIMIZED); + SetRedraw(TRUE); + } +} + void CDemoDlg::OnRadio1() { ModifyStyle(WS_THICKFRAME, 0, SWP_FRAMECHANGED | SWP_DRAWFRAME); HideSizeGrip(&m_dwGripTempState); UpdateSizeGrip(); + UpdateMaxSize(); } void CDemoDlg::OnRadio2() @@ -131,6 +172,7 @@ void CDemoDlg::OnRadio2() ModifyStyle(0, WS_THICKFRAME, SWP_FRAMECHANGED | SWP_DRAWFRAME); ShowSizeGrip(&m_dwGripTempState); UpdateSizeGrip(); + UpdateMaxSize(); } BOOL CALLBACK CDemoDlg::SendThemeChangedProc(HWND hwnd, LPARAM /*lParam*/) @@ -139,6 +181,20 @@ BOOL CALLBACK CDemoDlg::SendThemeChangedProc(HWND hwnd, LPARAM /*lParam*/) return TRUE; } +DWORD CDemoDlg::GetThemeProperties() +{ + static HMODULE hThemeLib = GetModuleHandle(_T("UxTheme.dll")); + typedef DWORD(STDAPICALLTYPE* LPFNGETTHEMEAPPPROPERTIES)(); + static LPFNGETTHEMEAPPPROPERTIES lpfnGetThemeAppProperties = (hThemeLib == NULL) ? NULL : + (LPFNGETTHEMEAPPPROPERTIES)GetProcAddress(hThemeLib, "GetThemeAppProperties"); + + if (lpfnGetThemeAppProperties == NULL) + return 0; // do nothing if no theme support + + // return theme settings + return lpfnGetThemeAppProperties(); +} + void CDemoDlg::SetThemeProperties(DWORD dwFlags) { static HMODULE hThemeLib = GetModuleHandle(_T("UxTheme.dll")); diff --git a/ResizableDialog/DemoDlg.h b/ResizableDialog/DemoDlg.h index d6adb24..e622db0 100644 --- a/ResizableDialog/DemoDlg.h +++ b/ResizableDialog/DemoDlg.h @@ -38,7 +38,9 @@ class CDemoDlg : public CResizableDialog HICON m_hIcon; static BOOL CALLBACK SendThemeChangedProc(HWND hwnd, LPARAM lParam); + static DWORD GetThemeProperties(); void SetThemeProperties(DWORD dwFlags); + void UpdateMaxSize(); // Generated message map functions //{{AFX_MSG(CDemoDlg)