From 0948993ec9e08e170d1d22f2c7176b00bd987103 Mon Sep 17 00:00:00 2001 From: Jonas Kümmerlin Date: Tue, 14 Apr 2020 16:02:05 +0200 Subject: Make notebook bg gradient work. Anti-flicker work throughout the codebase. --- alf/alfnotebook.cpp | 154 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 114 insertions(+), 40 deletions(-) (limited to 'alf/alfnotebook.cpp') diff --git a/alf/alfnotebook.cpp b/alf/alfnotebook.cpp index 82b2201..d60ea6b 100644 --- a/alf/alfnotebook.cpp +++ b/alf/alfnotebook.cpp @@ -7,8 +7,31 @@ #define ALF_NB_GETSELINDEX (ALF_WM__BASE + 203) #define ALF_NB_GETPNLINDEX (ALF_WM__BASE + 204) +#define TABP_BODY 10 + TCHAR *_alf_notebookClass = NULL; +typedef struct { + HWND hwndTabCtrl; + HTHEME hTheme; +} ALFNotebookPriv; + +static ALFNotebookPriv * +ALF_Notebook_CreatePriv(void) +{ + ALFNotebookPriv *priv = ALF_New(ALFNotebookPriv, 1); + + return priv; +} + +void +ALF_Notebook_FreePriv(ALFNotebookPriv *priv) +{ + ALF_Compat_CloseThemeData(priv->hTheme); + priv->hTheme = NULL; + ALF_Free(priv); +} + static int ALF_Notebook_InternalTabCount(HWND notebook, HWND tabControl) { @@ -50,13 +73,24 @@ ALF_Notebook_InternalHandleTabChange(HWND hwndNotebook, HWND hwndTabCtrl) for (int i = 0; i < n; ++i) { if (i == selectedIndex) { - ShowWindow(ALF_Notebook_InternalTabPanel(hwndNotebook, hwndTabCtrl, i), SW_SHOW); + SetWindowPos(ALF_Notebook_InternalTabPanel(hwndNotebook, hwndTabCtrl, i), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); } else { ShowWindow(ALF_Notebook_InternalTabPanel(hwndNotebook, hwndTabCtrl, i), SW_HIDE); } } } +static void +ALF_Notebook_InternalHandleThemeChange(HWND hwndNotebook, ALFNotebookPriv *priv) +{ + ALF_Compat_CloseThemeData(priv->hTheme); + priv->hTheme = NULL; + if (ALF_Compat_IsAppThemed()) + priv->hTheme = ALF_Compat_OpenThemeData(hwndNotebook, L"TAB"); + + InvalidateRect(hwndNotebook, NULL, TRUE); +} + static HWND ALF_Notebook_InternalAddTab(HWND notebook, HWND tabControl, const TCHAR *title) @@ -114,43 +148,71 @@ ALF_Notebook_TabCtrlSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa return ALF_Compat_DefSubclassProc(hwnd, uMsg, wParam, lParam); } +static void +ALF_Notebook_InternalPaint(HWND hwnd, ALFNotebookPriv *priv, HDC dc, RECT *f) +{ + if (priv->hTheme != NULL) { + RECT r; + GetClientRect(priv->hwndTabCtrl, &r); + TabCtrl_AdjustRect(priv->hwndTabCtrl, FALSE, &r); + MapWindowRect(priv->hwndTabCtrl, hwnd, &r); + + ALF_Compat_DrawThemeBackground(priv->hTheme, dc, TABP_BODY, 0, &r, NULL); + + ExcludeClipRect(dc, r.left, r.top, r.right, r.bottom); + } + + FillRect(dc, f, GetSysColorBrush(COLOR_BTNFACE)); +} + static LRESULT CALLBACK ALF__NotebookWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (ALF_ShouldMessageBubble(hwnd, uMsg, wParam, lParam)) return SendMessage(GetParent(hwnd), uMsg, wParam, lParam); - HWND hwndTabCtrl = (HWND)GetWindowLongPtr(hwnd, 0); + ALFNotebookPriv *priv = (ALFNotebookPriv *)GetWindowLongPtr(hwnd, 0); - if (uMsg == WM_CREATE) { - hwndTabCtrl = CreateWindowEx(0, - WC_TABCONTROL, - TEXT(""), - WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS, - 0, 0, 100, 100, - hwnd, - NULL, - ALF_HINSTANCE, - NULL); + if (uMsg == WM_CREATE && priv == NULL) { + priv = ALF_Notebook_CreatePriv(); + priv->hwndTabCtrl = CreateWindowEx(0, + WC_TABCONTROL, + TEXT(""), + WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS, + 0, 0, 100, 100, + hwnd, + NULL, + ALF_HINSTANCE, + NULL); - ALF_Compat_SetWindowSubclass(hwndTabCtrl, ALF_Notebook_TabCtrlSubclassProc, 0, 0); + ALF_Compat_SetWindowSubclass(priv->hwndTabCtrl, ALF_Notebook_TabCtrlSubclassProc, 0, 0); - SetWindowLongPtr(hwnd, 0, (LONG_PTR)hwndTabCtrl); + SetWindowLongPtr(hwnd, 0, (LONG_PTR)priv); + ALF_Notebook_InternalHandleThemeChange(hwnd, priv); + } + + if (!priv) + return DefWindowProc(hwnd, uMsg, wParam, lParam); + + if (uMsg == WM_DESTROY) { + ALF_Notebook_FreePriv(priv); + SetWindowLongPtr(hwnd, 0, 0); + priv = NULL; } else if (uMsg == ALF_WM_APPLYFONTS) { - int n = ALF_Notebook_InternalTabCount(hwnd, hwndTabCtrl); + int n = ALF_Notebook_InternalTabCount(hwnd, priv->hwndTabCtrl); for (int i = 0; i < n; ++i) { - HWND p = ALF_Notebook_InternalTabPanel(hwnd, hwndTabCtrl, i); + HWND p = ALF_Notebook_InternalTabPanel(hwnd, priv->hwndTabCtrl, i); SendMessage(p, ALF_WM_APPLYFONTS, wParam, lParam); } return TRUE; } else if (uMsg == WM_SETFONT) { - SendMessage(hwndTabCtrl, WM_SETFONT, wParam, lParam); + SendMessage(priv->hwndTabCtrl, WM_SETFONT, wParam, lParam); } else if (uMsg == ALF_WM_QUERYSIZE) { - int n = ALF_Notebook_InternalTabCount(hwnd, hwndTabCtrl); + int n = ALF_Notebook_InternalTabCount(hwnd, priv->hwndTabCtrl); RECT r = { 0, 0, 0, 0 }; for (int i = 0; i < n; ++i) { - HWND p = ALF_Notebook_InternalTabPanel(hwnd, hwndTabCtrl, i); + HWND p = ALF_Notebook_InternalTabPanel(hwnd, priv->hwndTabCtrl, i); SIZE s = { 0, 0 }; SendMessage(p, ALF_WM_QUERYSIZE, 0, (LPARAM)&s); if (s.cx > r.right) @@ -164,7 +226,7 @@ ALF__NotebookWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (!r.bottom) r.bottom = 100; // FIXME! - TabCtrl_AdjustRect(hwndTabCtrl, TRUE, &r); + TabCtrl_AdjustRect(priv->hwndTabCtrl, TRUE, &r); SIZE *ps = (SIZE*)lParam; if (!ps->cx) { @@ -181,29 +243,47 @@ ALF__NotebookWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (!(pos->flags & SWP_NOSIZE)) { RECT r; GetClientRect(hwnd, &r); - MoveWindow(hwndTabCtrl, 0, 0, r.right - r.left, r.bottom - r.top, FALSE); + MoveWindow(priv->hwndTabCtrl, 0, 0, r.right - r.left, r.bottom - r.top, FALSE); + InvalidateRect(priv->hwndTabCtrl, NULL, TRUE); - GetClientRect(hwndTabCtrl, &r); - TabCtrl_AdjustRect(hwndTabCtrl, FALSE, &r); - MapWindowRect(hwndTabCtrl, hwnd, &r); + GetClientRect(priv->hwndTabCtrl, &r); + TabCtrl_AdjustRect(priv->hwndTabCtrl, FALSE, &r); + MapWindowRect(priv->hwndTabCtrl, hwnd, &r); - int n = ALF_Notebook_InternalTabCount(hwnd, hwndTabCtrl); + int n = ALF_Notebook_InternalTabCount(hwnd, priv->hwndTabCtrl); for (int i = 0; i < n; ++i) { - HWND p = ALF_Notebook_InternalTabPanel(hwnd, hwndTabCtrl, i); + HWND p = ALF_Notebook_InternalTabPanel(hwnd, priv->hwndTabCtrl, i); MoveWindow(p, r.left, r.top, r.right - r.left, r.bottom - r.top, FALSE); + InvalidateRect(p, NULL, TRUE); } - - InvalidateRect(hwnd, NULL, TRUE); } } else if (uMsg == ALF_NB_ADDTAB) { - return (LRESULT)ALF_Notebook_InternalAddTab(hwnd, hwndTabCtrl, (TCHAR *)lParam); + return (LRESULT)ALF_Notebook_InternalAddTab(hwnd, priv->hwndTabCtrl, (TCHAR *)lParam); } else if (uMsg == ALF_NB_TABCOUNT) { - return (LRESULT)ALF_Notebook_InternalTabCount(hwnd, hwndTabCtrl); + return (LRESULT)ALF_Notebook_InternalTabCount(hwnd, priv->hwndTabCtrl); } else if (uMsg == ALF_NB_GETPANEL) { - return (LRESULT)ALF_Notebook_InternalTabPanel(hwnd, hwndTabCtrl, (int)lParam); + return (LRESULT)ALF_Notebook_InternalTabPanel(hwnd, priv->hwndTabCtrl, (int)lParam); } else if (uMsg == ALF_NB_GETSELINDEX) { - return (LRESULT)ALF_Notebook_InternalSelectedIndex(hwnd, hwndTabCtrl); + return (LRESULT)ALF_Notebook_InternalSelectedIndex(hwnd, priv->hwndTabCtrl); + } else if (uMsg == WM_THEMECHANGED) { + ALF_Notebook_InternalHandleThemeChange(hwnd, priv); + } else if (uMsg == WM_ERASEBKGND) { + return TRUE; + } else if (uMsg == WM_PRINTCLIENT) { + RECT r = {0, 0, 0, 0}; + GetClientRect(hwnd, &r); + + ALF_Notebook_InternalPaint(hwnd, priv, (HDC)wParam, &r); + return TRUE; + } else if (uMsg == WM_PAINT) { + PAINTSTRUCT ps; + HDC dc = BeginPaint(hwnd, &ps); + + ALF_Notebook_InternalPaint(hwnd, priv, dc, &ps.rcPaint); + + EndPaint(hwnd, &ps); + return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); @@ -220,14 +300,8 @@ ALF_RegisterNotebookClass(void) cls.hInstance = ALF_HINSTANCE; cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW); - if (LOBYTE(LOWORD(GetVersion())) >= 4) { - cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); - } else { - // NT 3.x has white dialog backgrounds - cls.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); - } cls.lpszClassName = classNameBuf; - cls.cbWndExtra = sizeof(HWND); + cls.cbWndExtra = sizeof(ALFNotebookPriv*); cls.lpfnWndProc = ALF__NotebookWindowProc; ATOM classatom = RegisterClass(&cls); @@ -244,7 +318,7 @@ ALF_AddNotebook(HWND parent, WORD id, UINT x, UINT y) HWND hwndNtbk = CreateWindowEx(WS_EX_CONTROLPARENT, _alf_notebookClass, TEXT(""), - WS_CHILD | WS_VISIBLE, + WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, 0, 0, 100, 100, parent, (HMENU)(int)id, -- cgit v1.2.3