summaryrefslogtreecommitdiff
path: root/alf
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2020-04-14 16:02:05 +0200
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2020-04-14 16:02:05 +0200
commit0948993ec9e08e170d1d22f2c7176b00bd987103 (patch)
tree1f707d95bfbbef467dbce2ecc0b3e9c034c9cd4c /alf
parent29393896e21cab201646352cce017992cf0b2ddb (diff)
Make notebook bg gradient work. Anti-flicker work throughout the codebase.
Diffstat (limited to 'alf')
-rw-r--r--alf/alf.cpp2
-rw-r--r--alf/alfbutton.cpp4
-rw-r--r--alf/alfcompat.h9
-rw-r--r--alf/alfedit.cpp34
-rw-r--r--alf/alflabel.cpp2
-rw-r--r--alf/alflayout.cpp2
-rw-r--r--alf/alfnotebook.cpp154
-rw-r--r--alf/alfpanel.cpp30
8 files changed, 169 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;