summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2020-04-27 17:09:25 +0200
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2020-04-27 17:09:25 +0200
commit7ebda0eb50ad2972a93cc6f597b22c9d4473f304 (patch)
tree0e4df6c5fd4676ba139e142aa0fac3e332b6d1da
parent2f9bdf479c438a9f2e1129e5787db6e079c2204b (diff)
button: make themed button always use unicode and do internal text handling
-rw-r--r--alf/alf.cpp17
-rw-r--r--alf/alfbutton.cpp115
-rw-r--r--alf/alfpriv.h3
3 files changed, 97 insertions, 38 deletions
diff --git a/alf/alf.cpp b/alf/alf.cpp
index 917008a..25dcd21 100644
--- a/alf/alf.cpp
+++ b/alf/alf.cpp
@@ -124,6 +124,23 @@ ALF_BuildUniqueName(TCHAR *buf, const TCHAR *prefix, ULONG_PTR uniquifier)
}
void
+ALF_BuildUniqueNameW(WCHAR *buf, const WCHAR *prefix, ULONG_PTR uniquifier)
+{
+ int prefixlen = lstrlenW(prefix);
+ CopyMemory(buf, prefix, (SIZE_T)prefixlen * sizeof(*prefix));
+
+ int numlen = sizeof(LONG_PTR)*2;
+ int i = numlen - 1;
+ while (i >= 0) {
+ buf[prefixlen + i] = L"0123456789ABCDEF"[uniquifier & 0xf];
+ uniquifier >>= 4;
+ i--;
+ }
+
+ buf[prefixlen + numlen] = 0;
+}
+
+void
ALF_DestroyWindow(HWND win)
{
DestroyWindow(win);
diff --git a/alf/alfbutton.cpp b/alf/alfbutton.cpp
index 2c7e918..dcf0898 100644
--- a/alf/alfbutton.cpp
+++ b/alf/alfbutton.cpp
@@ -30,6 +30,7 @@ typedef struct {
DWORD uxDefaultAnimationDuration;
int dpi;
HFONT font;
+ WCHAR *text;
} ALFNtButtonPriv;
TCHAR *_alf_buttonClass = NULL;
@@ -47,6 +48,17 @@ ALF_Button_DrawDisabledText_DrawStateProc(HDC hdc,
return TRUE;
}
+static BOOL CALLBACK
+ALF_Button_DrawDisabledTextW_DrawStateProc(HDC hdc,
+ LPARAM lData,
+ WPARAM wData,
+ int cx,
+ int cy)
+{
+ RECT rc = { 0, 0, cx, cy };
+ DrawTextW(hdc, (const WCHAR *)lData, -1, &rc, (UINT)wData);
+ return TRUE;
+}
static int
ALF_Button_DrawDisabledTextNt(HDC hdc,
@@ -63,6 +75,20 @@ ALF_Button_DrawDisabledTextNt(HDC hdc,
}
static int
+ALF_Button_DrawDisabledTextNtW(HDC hdc,
+ LPCWSTR lpchText,
+ int cchText,
+ LPRECT lprc,
+ UINT format)
+{
+ (void)cchText;
+ return DrawStateW(hdc, NULL, ALF_Button_DrawDisabledTextW_DrawStateProc,
+ (LPARAM)lpchText, (WPARAM)format,
+ lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
+ DST_COMPLEX | DSS_DISABLED);
+}
+
+static int
ALF_Button_DrawDisabledText9x(HDC hdc,
LPCTSTR lpchText,
int cchText,
@@ -91,7 +117,7 @@ ALF_Button_DrawDisabledText31(HDC hdc,
static ALFNtButtonPriv *
-ALF_NtButton_InitializePriv(void)
+ALF_NtButton_InitializePriv(CREATESTRUCTW *cs)
{
ALFNtButtonPriv *priv = ALF_New(ALFNtButtonPriv, 1);
@@ -100,6 +126,10 @@ ALF_NtButton_InitializePriv(void)
priv->uxStatePrev = -1;
priv->dpi = 96;
+ SIZE_T l = (SIZE_T)lstrlenW(cs->lpszName);
+ priv->text = ALF_New(WCHAR, l + 1);
+ CopyMemory(priv->text, cs->lpszName, l * sizeof(WCHAR));
+
return priv;
}
@@ -107,6 +137,7 @@ static void
ALF_NtButton_FreePriv(ALFNtButtonPriv *priv)
{
ALF_Compat_CloseThemeData(priv->hTheme);
+ ALF_Free(priv->text);
ALF_Free(priv);
}
@@ -128,7 +159,7 @@ ALF_NtButton_ModifyDrawFlags(HWND hwnd, ALFNtButtonPriv *priv, DWORD add, DWORD
static void
ALF_NtButton_HandleUIState(HWND hwnd, ALFNtButtonPriv *priv)
{
- LRESULT uiState = SendMessage(hwnd, WM_QUERYUISTATE, 0, 0);
+ LRESULT uiState = SendMessageW(hwnd, WM_QUERYUISTATE, 0, 0);
DWORD add = 0;
DWORD remove = 0;
if (uiState & UISF_HIDEACCEL) {
@@ -172,11 +203,7 @@ ALF_NtButton_CalculateSize(HWND hwnd, ALFNtButtonPriv *priv, SIZE *pSize)
RECT r = { 0, 0, 0x7FFFFFFF, 100 };
- TCHAR *textbuf = ALF_Text(hwnd);
-
- DrawText(hdc, textbuf, -1, &r, format);
-
- ALF_Free(textbuf);
+ DrawTextW(hdc, priv->text, -1, &r, format);
int xpadding = ALF_Compat_GetSystemMetricsForDpi(SM_CXEDGE,
(UINT)priv->dpi) * 2 + 6;
@@ -232,17 +259,13 @@ ALF_NtButton_RenderUxtheme(HWND hwnd, ALFNtButtonPriv *priv, int uxstate, DWORD
if ((drawFlags & ALF_NTBTN_FLAG_IS_FOCUSED) && !(drawFlags & ALF_NTBTN_FLAG_HIDEFOCUS))
DrawFocusRect(hDC, &content);
- int textlen = GetWindowTextLengthW(hwnd);
- WCHAR *textbuf = ALF_New(WCHAR, (SIZE_T)textlen + 1);
- GetWindowTextW(hwnd, textbuf, textlen+1);
-
UINT style = DT_CENTER;
if (drawFlags & ALF_NTBTN_FLAG_HIDEACCEL)
style |= DT_HIDEPREFIX;
RECT textbounds = content;
- ALF_Compat_GetThemeTextExtent(priv->hTheme, hDC, BP_PUSHBUTTON, uxstate, textbuf, -1, style, &content, &textbounds);
+ ALF_Compat_GetThemeTextExtent(priv->hTheme, hDC, BP_PUSHBUTTON, uxstate, priv->text, -1, style, &content, &textbounds);
RECT texttarget = content;
texttarget.top += ((content.bottom - content.top) - (textbounds.bottom - textbounds.top)) / 2;
@@ -250,9 +273,7 @@ ALF_NtButton_RenderUxtheme(HWND hwnd, ALFNtButtonPriv *priv, int uxstate, DWORD
texttarget.right = texttarget.left + (textbounds.right - textbounds.left);
texttarget.bottom = texttarget.top + (textbounds.bottom - textbounds.top);
- ALF_Compat_DrawThemeText(priv->hTheme, hDC, BP_PUSHBUTTON, uxstate, textbuf, -1, style, 0, &texttarget);
-
- ALF_Free(textbuf);
+ ALF_Compat_DrawThemeText(priv->hTheme, hDC, BP_PUSHBUTTON, uxstate, priv->text, -1, style, 0, &texttarget);
SelectFont(hDC, oldfont);
}
@@ -269,8 +290,6 @@ ALF_NtButton_RenderClassic(HWND hwnd, ALFNtButtonPriv *priv, HDC dc, RECT *rcPai
RECT r = rcClient;
- TCHAR *textbuf = ALF_Text(hwnd);
-
if (priv->drawFlags & ALF_NTBTN_FLAG_IS_DEFAULT) {
HBRUSH framecolor = GetSysColorBrush(COLOR_WINDOWFRAME);
FrameRect(dc, &r, framecolor);
@@ -287,14 +306,8 @@ ALF_NtButton_RenderClassic(HWND hwnd, ALFNtButtonPriv *priv, HDC dc, RECT *rcPai
DrawFrameControl(dc, &r, DFC_BUTTON, dfcs);
- if ((priv->drawFlags & ALF_NTBTN_FLAG_IS_FOCUSED) && !(priv->drawFlags & ALF_NTBTN_FLAG_HIDEFOCUS)) {
- RECT f = r;
- InflateRect(&f, -1, -1);
- DrawFocusRect(dc, &f);
- }
-
RECT textbounds = rcClient;
- DrawText(dc, textbuf, -1, &textbounds, DT_LEFT | DT_CALCRECT);
+ DrawTextW(dc, priv->text, -1, &textbounds, DT_LEFT | DT_CALCRECT);
RECT texttarget = rcClient;
texttarget.top += ((rcClient.bottom - rcClient.top) - (textbounds.bottom - textbounds.top)) / 2 - 1;
@@ -316,14 +329,19 @@ ALF_NtButton_RenderClassic(HWND hwnd, ALFNtButtonPriv *priv, HDC dc, RECT *rcPai
COLORREF oldBkColor = SetBkColor(dc, GetSysColor(COLOR_BTNFACE));
if (priv->drawFlags & ALF_NTBTN_FLAG_IS_DISABLED) {
- ALF_Button_DrawDisabledText(dc, textbuf, -1, &texttarget, style);
+ ALF_Button_DrawDisabledTextNtW(dc, priv->text, -1, &texttarget, style);
} else {
- DrawText(dc, textbuf, -1, &texttarget, style);
+ DrawTextW(dc, priv->text, -1, &texttarget, style);
}
SetBkColor(dc, oldBkColor);
+ if ((priv->drawFlags & ALF_NTBTN_FLAG_IS_FOCUSED) && !(priv->drawFlags & ALF_NTBTN_FLAG_HIDEFOCUS)) {
+ RECT f = r;
+ InflateRect(&f, -1, -1);
+ DrawFocusRect(dc, &f);
+ }
+
SelectFont(dc, oldfont);
- ALF_Free(textbuf);
}
static void
@@ -436,7 +454,7 @@ static void
ALF_NtButton_Clicked(HWND hwnd, ALFNtButtonPriv *priv)
{
(void)priv;
- SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLong(hwnd, GWL_ID), BN_CLICKED), (LPARAM)hwnd);
+ SendMessageW(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLong(hwnd, GWL_ID), BN_CLICKED), (LPARAM)hwnd);
}
static LRESULT CALLBACK
@@ -445,9 +463,9 @@ ALF_NtButton_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
ALFNtButtonPriv *priv = (ALFNtButtonPriv *)GetWindowLongPtr(hwnd, 0);
if (uMsg == WM_CREATE) {
- priv = ALF_NtButton_InitializePriv();
+ priv = ALF_NtButton_InitializePriv((CREATESTRUCTW *)lParam);
- SetWindowLongPtr(hwnd, 0, (LONG_PTR)priv);
+ SetWindowLongPtrW(hwnd, 0, (LONG_PTR)priv);
ALF_NtButton_HandleThemeChange(hwnd, priv);
ALF_NtButton_HandleUIState(hwnd, priv);
@@ -567,7 +585,28 @@ ALF_NtButton_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} else if (uMsg == WM_ERASEBKGND) {
return TRUE;
} else if (uMsg == WM_SETTEXT) {
- ALF_InvalidateLayout(GetParent(hwnd));
+ const WCHAR *newtext = (const WCHAR *)lParam;
+ if (newtext) {
+ SIZE_T len = (SIZE_T)lstrlenW(newtext);
+ ALF_Free(priv->text);
+ priv->text = ALF_New(WCHAR, len+1);
+ CopyMemory(priv->text, newtext, (len+1)*sizeof(WCHAR));
+ ALF_InvalidateLayout(GetParent(hwnd));
+ return TRUE;
+ }
+ return FALSE;
+ } else if (uMsg == WM_GETTEXTLENGTH) {
+ return (LRESULT)lstrlenW(priv->text);
+ } else if (uMsg == WM_GETTEXT) {
+ if (wParam < 1)
+ return 0;
+
+ SIZE_T selflen = (SIZE_T)lstrlenW(priv->text);
+ SIZE_T buflen = (SIZE_T)wParam - 1;
+ SIZE_T tocopy = selflen < buflen ? selflen : buflen;
+ CopyMemory((WCHAR*)lParam, priv->text, tocopy * sizeof(WCHAR));
+ ((WCHAR*)lParam)[tocopy] = 0;
+ return (LRESULT)tocopy;
} else if (uMsg == WM_SETFONT) {
priv->font = (HFONT)wParam;
if (LOWORD(lParam) != 0)
@@ -585,7 +624,7 @@ ALF_NtButton_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} else if (uMsg == WM_SIZE) {
InvalidateRect(hwnd, NULL, TRUE);
} else if (uMsg == WM_UPDATEUISTATE) {
- LRESULT rv = DefWindowProc(hwnd, uMsg, wParam, lParam);
+ LRESULT rv = DefWindowProcW(hwnd, uMsg, wParam, lParam);
ALF_NtButton_HandleUIState(hwnd, priv);
@@ -599,10 +638,10 @@ ALF_NtButton_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} else if (uMsg == WM_DESTROY) {
ALF_NtButton_FreePriv(priv);
priv = NULL;
- SetWindowLongPtr(hwnd, 0, 0);
+ SetWindowLongPtrW(hwnd, 0, 0);
}
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
void
@@ -622,11 +661,11 @@ ALF_RegisterButtonClass(void)
// Initialize custom themed button class on windows 2000 and newer
// Win9x and NT3.51/NT4 are well served by the classic version
if (ALF_Compat_IsMinWindowsVersion(5, 0)) {
- WNDCLASS cls;
+ WNDCLASSW cls;
ZeroMemory(&cls, sizeof(cls));
- TCHAR classNameBuf[256];
- ALF_BuildUniqueName(classNameBuf, TEXT("ALFNtButton."), (ULONG_PTR)&_alf_buttonClass);
+ WCHAR classNameBuf[256];
+ ALF_BuildUniqueNameW(classNameBuf, L"ALFNtButton.", (ULONG_PTR)&_alf_buttonClass);
cls.hInstance = ALF_HINSTANCE;
cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW);
@@ -634,7 +673,7 @@ ALF_RegisterButtonClass(void)
cls.cbWndExtra = sizeof(void*);
cls.lpfnWndProc = ALF_NtButton_WndProc;
- ATOM classatom = RegisterClass(&cls);
+ ATOM classatom = RegisterClassW(&cls);
if (!classatom)
MessageBox(NULL, TEXT("FATAL: Could not register button class"), NULL, MB_OK);
diff --git a/alf/alfpriv.h b/alf/alfpriv.h
index 77925e4..c2ab557 100644
--- a/alf/alfpriv.h
+++ b/alf/alfpriv.h
@@ -44,6 +44,9 @@ ALF_CreatePanelWindow(HWND parent, WORD id);
void
ALF_BuildUniqueName(TCHAR *buf, const TCHAR *prefix, ULONG_PTR uniquifier);
+void
+ALF_BuildUniqueNameW(WCHAR *buf, const WCHAR *prefix, ULONG_PTR uniquifier);
+
BOOL
ALF_ShouldMessageBubble(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);