From 65d9985bdcaed63b52bfe8c35c61d8a4a43a8292 Mon Sep 17 00:00:00 2001 From: Jonas Kümmerlin Date: Tue, 28 Apr 2020 10:57:22 +0200 Subject: first try at checkbox The size calculation is really messy and the background stuff does not work with comctl v5. Probably need to go full owner-drawn, again. --- alf/alfcheckbox.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 alf/alfcheckbox.cpp (limited to 'alf/alfcheckbox.cpp') diff --git a/alf/alfcheckbox.cpp b/alf/alfcheckbox.cpp new file mode 100644 index 0000000..99a285f --- /dev/null +++ b/alf/alfcheckbox.cpp @@ -0,0 +1,118 @@ +#include "alfpriv.h" + +typedef struct { + ALFColor bgcolor; + WNDPROC origWndProc; +} ALFCheckboxPriv; + +static ALFCheckboxPriv * +ALF_Checkbox_InitializePriv(void) +{ + return ALF_New(ALFCheckboxPriv, 1); +} + +static void +ALF_Checkbox_FreePriv(ALFCheckboxPriv *priv) +{ + ALF_Free(priv); +} + +static BOOL +ALF_Checkbox_IsTransparencySupported(void) +{ + // FIXME: for safety, check if the control is actually a v6 control + return ALF_Compat_IsAppThemed(); +} + +static LRESULT +ALF_Checkbox_PaintBackground(HWND window, ALFCheckboxPriv *priv, HDC hDC) +{ + // FIXME: Drawing the (transparent) background in WM_CTLCOLORSTATIC is + // only supported in a themed V6 common control + + SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT)); + if (ALF_Checkbox_IsTransparencySupported()) { + RECT r; + GetClientRect(window, &r); + + if (priv->bgcolor == ALF_COLOR_TRANSPARENT) { + ALF_Compat_DrawThemeParentBackground(window, hDC, &r); + SetBkMode(hDC, TRANSPARENT); + } else { + ALF_FillRect(hDC, &r, priv->bgcolor); + SetBkMode(hDC, OPAQUE); + SetBkColor(hDC, ALF_ColorToGdi(priv->bgcolor)); + } + return (LRESULT)GetStockObject(HOLLOW_BRUSH); + } else { + SetBkColor(hDC, GetSysColor(COLOR_BTNFACE)); + SetBkMode(hDC, OPAQUE); + return (LRESULT)GetSysColorBrush(COLOR_BTNFACE); + } +} + +static LRESULT CALLBACK +ALF_Checkbox_WindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam) +{ + ALFCheckboxPriv *priv = (ALFCheckboxPriv *)GetWindowLongPtr(window, GWLP_USERDATA); + + if (!priv) // fuck + return DefWindowProc(window, msg, wparam, lparam); + + if (msg == ALF_WM_SETBGCOLOR) { + ALFColor newColor = (ALFColor)lparam; + if (newColor != priv->bgcolor) { + priv->bgcolor = newColor; + if (ALF_Checkbox_IsTransparencySupported()) + InvalidateRect(window, NULL, TRUE); + } + return TRUE; + } + + if (msg == 0x2000 + WM_CTLCOLORSTATIC) { + return ALF_Checkbox_PaintBackground(window, priv, (HDC)wparam); + } + + if (msg == ALF_WM_BACKGROUNDCHANGE) { + if (priv->bgcolor == ALF_COLOR_TRANSPARENT && ALF_Checkbox_IsTransparencySupported()) { + InvalidateRect(window, NULL, TRUE); + } + return TRUE; + } + + if (msg == WM_THEMECHANGED) { + InvalidateRect(window, NULL, TRUE); + } + + if (msg == WM_DESTROY) { + WNDPROC orig = priv->origWndProc; + SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)orig); + SetWindowLongPtr(window, GWLP_USERDATA, 0); + ALF_Checkbox_FreePriv(priv); + return CallWindowProc(orig, window, msg, wparam, lparam); + } + + return CallWindowProc(priv->origWndProc, window, msg, wparam, lparam); +} + +HWND +ALF_AddCheckbox(HWND parent, WORD id, int x, int y, const TCHAR *text) +{ + HWND hwnd = CreateWindowEx(0, + TEXT("BUTTON"), + text, + WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX, + 0, 0, 100, 100, + parent, + (HMENU)(ULONG_PTR)id, + ALF_HINSTANCE, + NULL); + + ALFCheckboxPriv *priv = ALF_Checkbox_InitializePriv(); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)priv); + priv->origWndProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)ALF_Checkbox_WindowProc); + + ALF_AddWidget(parent, x, y, hwnd, 0, 0, ALF_LAYOUT_SIZE_CHECKBOX | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_INHERITBGCOLOR | ALF_LAYOUT_SENDBGCHANGE); + + return hwnd; +} -- cgit v1.2.3