diff options
| author | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2020-04-14 16:02:05 +0200 |
|---|---|---|
| committer | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2020-04-14 16:02:05 +0200 |
| commit | 0948993ec9e08e170d1d22f2c7176b00bd987103 (patch) | |
| tree | 1f707d95bfbbef467dbce2ecc0b3e9c034c9cd4c | |
| parent | 29393896e21cab201646352cce017992cf0b2ddb (diff) | |
Make notebook bg gradient work. Anti-flicker work throughout the codebase.
| -rw-r--r-- | alf/alf.cpp | 2 | ||||
| -rw-r--r-- | alf/alfbutton.cpp | 4 | ||||
| -rw-r--r-- | alf/alfcompat.h | 9 | ||||
| -rw-r--r-- | alf/alfedit.cpp | 34 | ||||
| -rw-r--r-- | alf/alflabel.cpp | 2 | ||||
| -rw-r--r-- | alf/alflayout.cpp | 2 | ||||
| -rw-r--r-- | alf/alfnotebook.cpp | 154 | ||||
| -rw-r--r-- | alf/alfpanel.cpp | 30 | ||||
| -rw-r--r-- | widgetfactory.cpp | 6 |
9 files changed, 175 insertions, 68 deletions
diff --git a/alf/alf.cpp b/alf/alf.cpp index ecf2e7f..c59cdbb 100644 --- a/alf/alf.cpp +++ b/alf/alf.cpp @@ -532,7 +532,7 @@ ALF_UnregisterWindowClass(HINSTANCE hinstance, LPCTSTR className) HWND ALF_InstantiateWindow(HINSTANCE hinstance, LPCTSTR className, HWND hwndParent, void *closure) { - return CreateWindowEx(0, + return CreateWindowEx(ALF_Compat_IsMinWindowsVersion(5, 1) ? WS_EX_COMPOSITED : 0, className, TEXT("Window"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, diff --git a/alf/alfbutton.cpp b/alf/alfbutton.cpp index fb8d1c3..ce87f15 100644 --- a/alf/alfbutton.cpp +++ b/alf/alfbutton.cpp @@ -178,6 +178,8 @@ ALF__Button_Render3x(HWND hwnd, ALFButtonPriv *priv, LPDRAWITEMSTRUCT dis) { RECT r = dis->rcItem; + ALF_Compat_DrawThemeParentBackground(hwnd, dis->hDC, &r); + int textlen = GetWindowTextLength(hwnd); TCHAR *textbuf = ALF_New(TCHAR, textlen + 1); GetWindowText(hwnd, textbuf, textlen+1); @@ -473,6 +475,8 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT ALF_Compat_CloseThemeData(priv->hTheme); ALF_Free(priv); ALF_Compat_RemoveWindowSubclass(hwnd, ALF__ButtonSubclassProc, 0); + } else if (uMsg == WM_ERASEBKGND) { + return TRUE; } return ALF_Compat_DefSubclassProc(hwnd, uMsg, wParam, lParam); diff --git a/alf/alfcompat.h b/alf/alfcompat.h index 9c7f3f2..3996309 100644 --- a/alf/alfcompat.h +++ b/alf/alfcompat.h @@ -15,6 +15,15 @@ extern IMAGE_DOS_HEADER __ImageBase; #endif #define ALF_HINSTANCE ((HINSTANCE)&__ImageBase) +static inline BOOL ALF_Compat_IsMinWindowsVersion(DWORD major, DWORD minor) +{ + DWORD v = GetVersion(); + DWORD vMajor = LOBYTE(LOWORD(v)); + DWORD vMinor = HIBYTE(LOWORD(v)); + + return vMajor > major || (vMajor == major && vMinor >= minor); +} + typedef LRESULT (CALLBACK *ALF_COMPAT_SUBCLASSPROC)(HWND,UINT,WPARAM,LPARAM,UINT_PTR,DWORD_PTR); typedef struct { diff --git a/alf/alfedit.cpp b/alf/alfedit.cpp index c6570e4..be06b01 100644 --- a/alf/alfedit.cpp +++ b/alf/alfedit.cpp @@ -11,28 +11,26 @@ ALF__EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_P HDC hDc = GetDC(hwnd); HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0); - if (font) { - HFONT oldfont = SelectFont(hDc, font); - - TEXTMETRIC tm; - ZeroMemory(&tm, sizeof(tm)); - - if (GetTextMetrics(hDc, &tm)) { - SIZE *ps = (SIZE*)lParam; - if (!ps->cx) { - ps->cx = ALF_CentipointsToPixels(GetParent(hwnd), 12000); - } - - if (!ps->cy) { - ps->cy = tm.tmHeight + 2*ALF_Compat_GetSystemMetricsForDpi( - SM_CYEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200)) - + 4 /* padding internal to the edit control */; - } + HFONT oldfont = SelectFont(hDc, font); + + TEXTMETRIC tm; + ZeroMemory(&tm, sizeof(tm)); + + if (GetTextMetrics(hDc, &tm)) { + SIZE *ps = (SIZE*)lParam; + if (!ps->cx) { + ps->cx = ALF_CentipointsToPixels(GetParent(hwnd), 12000); } - SelectFont(hDc, oldfont); + if (!ps->cy) { + ps->cy = tm.tmHeight + 2*ALF_Compat_GetSystemMetricsForDpi( + SM_CYEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200)) + + 4 /* padding internal to the edit control */; + } } + SelectFont(hDc, oldfont); + ReleaseDC(hwnd, hDc); return 0; } else if (uMsg == ALF_WM_APPLYSIZE) { diff --git a/alf/alflabel.cpp b/alf/alflabel.cpp index 56e53d2..422a8dc 100644 --- a/alf/alflabel.cpp +++ b/alf/alflabel.cpp @@ -81,6 +81,8 @@ ALF__LabelWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return (LRESULT)priv->font; } else if (uMsg == WM_UPDATEUISTATE) { InvalidateRect(hwnd, NULL, TRUE); + } else if (uMsg == WM_ERASEBKGND) { + return 1; // do it in WM_PAINT } else if (uMsg == WM_PAINT) { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); diff --git a/alf/alflayout.cpp b/alf/alflayout.cpp index 5e79443..9c4b8f1 100644 --- a/alf/alflayout.cpp +++ b/alf/alflayout.cpp @@ -240,7 +240,7 @@ ALF_Layout_Apply(ALFLayout* layout, HWND window) hdwp = DeferWindowPos(hdwp, c->hwnd, 0, r.left, r.top, r.right - r.left, r.bottom - r.top, - SWP_NOACTIVATE | SWP_NOZORDER); + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS); } } 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, diff --git a/alf/alfpanel.cpp b/alf/alfpanel.cpp index 8583d2e..b8ef8b3 100644 --- a/alf/alfpanel.cpp +++ b/alf/alfpanel.cpp @@ -18,6 +18,13 @@ ALF_Panel_ClearPriv(ALFPanelPriv *priv) ALF_Layout_Clear(&priv->layout); } +static void +ALF_Panel_Paint(ALFPanelPriv *priv, HWND hwnd, HDC dc, RECT *r) +{ + (void)priv; + ALF_Compat_DrawThemeParentBackground(hwnd, dc, r); +} + static LRESULT WINAPI ALF__PanelWindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam) { @@ -38,15 +45,28 @@ ALF__PanelWindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam) } if (msg == WM_ERASEBKGND) { - HDC hdc = (HDC)wparam; + return TRUE; + } + if (msg == WM_PRINTCLIENT) { RECT r = { 0, 0, 0, 0 }; GetClientRect(window, &r); - ALF_Compat_DrawThemeParentBackground(window, hdc, &r); + ALF_Panel_Paint(priv, window, (HDC)wparam, &r); return TRUE; } + if (msg == WM_PAINT) { + PAINTSTRUCT ps; + HDC dc = BeginPaint(window, &ps); + + ALF_Panel_Paint(priv, window, dc, &ps.rcPaint); + + EndPaint(window, &ps); + + return 0; + } + if (ALF_ShouldMessageBubble(window, msg, wparam, lparam)) return SendMessage(GetParent(window), msg, wparam, lparam); @@ -72,12 +92,6 @@ ALF_RegisterPanelClass(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(void*); cls.lpfnWndProc = ALF__PanelWindowProc; diff --git a/widgetfactory.cpp b/widgetfactory.cpp index c9b74d7..e4127f0 100644 --- a/widgetfactory.cpp +++ b/widgetfactory.cpp @@ -197,6 +197,12 @@ WinMain ALF_AddLabel(hwndTabPanel1, (WORD)-1, 0, 0, TEXT("Hello World!")); ALF_AddLabel(hwndTabPanel2, (WORD)-1, 0, 0, TEXT("Goodbye, &World!")); ALF_AddEdit(hwndTabPanel2, (WORD)-1, 1, 0, TEXT("lol")); + ALF_AddWidgetLayoutFlag(win, hwndTab, ALF_VEXPAND); + + HWND hwndTabLabel2 = ALF_AddLabel(hwndTabPanel1, (WORD)-1, 0, 1, TEXT("Blabla")); + ALF_AddWidgetLayoutFlag(hwndTabPanel1, hwndTabLabel2, ALF_VEXPAND); + ALF_AddLabel(hwndTabPanel1, (WORD)-1, 0, 2, TEXT("No 3")); + ALF_AddEdit(hwndTabPanel1, (WORD)-1, 0, 3, TEXT("Dummy")); ALF_ApplyFonts(win); |
