From 647fd553af9054b89f4a0d751ea89a98439ae5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Sat, 23 Jul 2022 22:42:03 +0200 Subject: Improve window layout. This reverts much of 97f0a27. 1. It turns out not to be a good idea to resize the list view columns based on the list view window's own rectangle, as it will change depending on whether a scrollbar is visible. The problem is that resizing the columns may add a horizontal scrollbar -- which in turn may add a vertical scrollbar. 2. The WS_EX_CLIENTEDGE style does not look very good in "modern" (non-classic) themes. In 97f0a27, I tried solving this by extending the dimensions of the child windows such that their edges were hidden. However, this type of overlapping causes problems with the status bar. My new solution is to instead *reduce* the child windows' dimensions. This achieves a visual impression similar to the thicker (more well-designed) edges of the "classically themed" list view control. To make it look even better, the main window background is changed from COLOR_WINDOWFRAME (white) to COLOR_WINDOW (light gray). --- c/common.h | 4 ++++ c/datalistview.cpp | 9 +++------ c/datalistview.h | 2 +- c/episodelistview.cpp | 11 +++++------ c/episodelistview.h | 2 +- c/listview.cpp | 2 +- c/listview.h | 2 +- c/main.cpp | 41 +++++++++++++++++++---------------------- c/main.h | 2 +- 9 files changed, 36 insertions(+), 39 deletions(-) (limited to 'c') diff --git a/c/common.h b/c/common.h index fb21e6f..709a258 100644 --- a/c/common.h +++ b/c/common.h @@ -55,6 +55,10 @@ std::optional maybe_make(U... xs) } } +/* Variable template for caching values from GetSystemMetrics. */ +template +const auto Metric = GetSystemMetrics(I); + /* Check result of Windows API call, throwing error on NULL. */ template inline T require(const T x) diff --git a/c/datalistview.cpp b/c/datalistview.cpp index 1ceeb3b..82b62e6 100644 --- a/c/datalistview.cpp +++ b/c/datalistview.cpp @@ -29,15 +29,12 @@ DataListView::DataListView(const HWND hWndParent) ListView_InsertColumn(hWnd, DLVSIVALUE, &lvc); } -void DataListView::ResizeColumns() +void DataListView::ResizeColumns(int w) { - RECT rc; - require(GetClientRect(hWnd, &rc)); - ListView_SetColumnWidth(hWnd, DLVSIKEY, LVSCW_AUTOSIZE); - const int cxColumn = ListView_GetColumnWidth(hWnd, 0)+4; + const int cxColumn = ListView_GetColumnWidth(hWnd, DLVSIKEY)+Dpi(4); ListView_SetColumnWidth(hWnd, DLVSIKEY, cxColumn); - ListView_SetColumnWidth(hWnd, DLVSIVALUE, rc.right-cxColumn); + ListView_SetColumnWidth(hWnd, DLVSIVALUE, w-cxColumn-Metric-Dpi(4)); } void DataListView::ShowEpisode(const int iEpisode) diff --git a/c/datalistview.h b/c/datalistview.h index 0bea546..5865ed1 100644 --- a/c/datalistview.h +++ b/c/datalistview.h @@ -9,7 +9,7 @@ struct DataListView : public ListView { DataListView(HWND hWndParent); - void ResizeColumns() override; + void ResizeColumns(int w) override; void ShowEpisode(int iEpisode); }; diff --git a/c/episodelistview.cpp b/c/episodelistview.cpp index bc01ce9..4b93587 100644 --- a/c/episodelistview.cpp +++ b/c/episodelistview.cpp @@ -141,16 +141,13 @@ void EpisodeListView::Redraw() RDW_ERASE|RDW_FRAME|RDW_INVALIDATE|RDW_ALLCHILDREN); } -void EpisodeListView::ResizeColumns() +void EpisodeListView::ResizeColumns(int w) { - RECT rc; - require(GetClientRect(hWnd, &rc)); - ListView_SetColumnWidth(hWnd, ELVSIEPISODE, LVSCW_AUTOSIZE); - int cxColumn = ListView_GetColumnWidth(hWnd, ELVSIEPISODE)+4; + int cxColumn = ListView_GetColumnWidth(hWnd, ELVSIEPISODE)+Dpi(4); ListView_SetColumnWidth(hWnd, ELVSIEPISODE, cxColumn); cxColumn += ListView_GetColumnWidth(hWnd, ELVSIRATING); - ListView_SetColumnWidth(hWnd, ELVSITITLE, rc.right-cxColumn); + ListView_SetColumnWidth(hWnd, ELVSITITLE, w-cxColumn-Metric-Dpi(4)); } /* Select previously focused episode. */ @@ -406,8 +403,10 @@ void EpisodeListView::Update() if (iItemTopNew != -1) SetTop(iItemTopNew); + /* Show number of displayed items in status bar. */ _stprintf_s(tszDisp, sizeof(tszDisp), TEXT("%d"), iItem); SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)tszDisp); + SendMessage(hWnd, WM_SETREDRAW, TRUE, 0); } diff --git a/c/episodelistview.h b/c/episodelistview.h index 36ac04b..8747f6b 100644 --- a/c/episodelistview.h +++ b/c/episodelistview.h @@ -16,7 +16,7 @@ struct EpisodeListView : public ListView void EnsureFocusVisible(); LRESULT HandleNotify(LPARAM lParam); void Redraw(); - void ResizeColumns() override; + void ResizeColumns(int w) override; void RestoreFocus(); void SaveFocus(); void SetTop(int iItem); diff --git a/c/listview.cpp b/c/listview.cpp index 5418e33..622ff87 100644 --- a/c/listview.cpp +++ b/c/listview.cpp @@ -38,7 +38,7 @@ int ListView::Height(int bHeader) return iCount? Dpi(bHeader? 27: 4)+iCount*Dpi(19): 0; } -void ListView::ResizeColumns() {} +void ListView::ResizeColumns(int) {} void ListView::UpdateTheme(const BOOL bThemeActive) { diff --git a/c/listview.h b/c/listview.h index 528ddc3..478819f 100644 --- a/c/listview.h +++ b/c/listview.h @@ -9,7 +9,7 @@ struct ListView ListView(HWND hWndParent, HMENU hMenu, DWORD dwStyle); int Height(int bHeader = -1); - virtual void ResizeColumns(); + virtual void ResizeColumns(int w); virtual void UpdateTheme(BOOL bThemeActive); virtual LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); protected: diff --git a/c/main.cpp b/c/main.cpp index 72d405b..746bf7e 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -107,7 +107,7 @@ int WINAPI WinMain(const HINSTANCE hInstance, const HINSTANCE, char* const, cons wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); wc.lpszClassName = TEXT("Episode Browser"); wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); @@ -207,7 +207,7 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, switch (uMsg) { case WM_CREATE: UpdateTheme(); - SetWindowPos(hWnd, NULL, -1, -1, Dpi(510), Dpi(400), SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE); + SetWindowPos(hWnd, NULL, -1, -1, Dpi(510), Dpi(412), SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE); SetFocus(g_pElv->hWnd); /* Set menu item checkmarks according to saved settings. */ @@ -227,7 +227,7 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, break; case WM_SIZE: SendMessage(g_hWndStatus, WM_SIZE, wParam, lParam); - UpdateLayout(); + UpdateLayout(LOWORD(lParam), HIWORD(lParam)); break; case WM_GETMINMAXINFO: { @@ -248,7 +248,7 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, lpr->right-lpr->left, lpr->bottom-lpr->top, SWP_NOZORDER|SWP_NOACTIVATE)); - UpdateLayout(); + UpdateLayout(lpr->right-lpr->left, lpr->bottom-lpr->top); break; } case WM_ACTIVATE: @@ -506,35 +506,32 @@ INT_PTR CALLBACK AboutDlgProc(const HWND hWnd, const UINT uMsg, const WPARAM wPa return TRUE; } -void UpdateLayout() +void UpdateLayout(int w, int h) { if (!g_hWndStatus) return; RECT rc, rrStatus; - require(GetClientRect(g_hWnd, &rc)); + if (w && h) rc = {0, 0, w, h}; + else require(GetClientRect(g_hWnd, &rc)); require(GetRelativeRect(g_hWndStatus, &rrStatus)); - /* Resize list views. */ - SendMessage(g_pDlv->hWnd, WM_SETREDRAW, FALSE, 0); - SendMessage(g_pElv->hWnd, WM_SETREDRAW, FALSE, 0); - - /* If a modern theme is used, list view borders should be - * hidden. This variable governs that. (See how it is used in - * the arguments to SetWindowRect below.) */ - const long x = IsThemeActive(); - - const long cyDlv = rrStatus.top-g_pDlv->Height(); - require(SetWindowRect(g_pDlv->hWnd, -x, cyDlv, rc.right+x*2, rrStatus.top+x)); - require(SetWindowRect(g_pElv->hWnd, -x, -x*2, rc.right+x*2, cyDlv+x)); - g_pDlv->ResizeColumns(); - g_pElv->ResizeColumns(); + SendMessage(g_hWnd, WM_SETREDRAW, FALSE, 0); - SendMessage(g_pElv->hWnd, WM_SETREDRAW, TRUE, 0); - SendMessage(g_pDlv->hWnd, WM_SETREDRAW, TRUE, 0); + /* Resize list views. */ + const long pad = IsThemeActive()? Dpi(6): 0; /* Add padding in modern themes. */ + const long cyDlv = rrStatus.top-g_pDlv->Height()-pad; + require(SetWindowRect(g_pDlv->hWnd, pad, cyDlv, rc.right-pad, rrStatus.top-pad)); + require(SetWindowRect(g_pElv->hWnd, pad, pad, rc.right-pad, cyDlv-pad)); + g_pDlv->ResizeColumns(rc.right-pad-pad); + g_pElv->ResizeColumns(rc.right-pad-pad); /* Resize status bar parts. */ const int aParts[] = {rc.right-Dpi(55), rc.right}; SendMessage(g_hWndStatus, SB_SETPARTS, (WPARAM)sizeof(aParts), (LPARAM)aParts); + + SendMessage(g_hWnd, WM_SETREDRAW, TRUE, 0); + RedrawWindow(g_hWnd, NULL, NULL, + RDW_ERASE|RDW_FRAME|RDW_INVALIDATE|RDW_ALLCHILDREN); } /* Try to style application according to current Windows theme. */ diff --git a/c/main.h b/c/main.h index 0b899e6..1f9d3bf 100644 --- a/c/main.h +++ b/c/main.h @@ -1,6 +1,6 @@ #ifndef MAIN_H #define MAIN_H -void UpdateLayout(); +void UpdateLayout(int w = 0, int h = 0); #endif -- cgit v1.2.3