summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2020-05-23 14:26:28 +0200
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2020-05-23 14:26:28 +0200
commit9d237b5fd80e55d8b5e367323b6ee58be896f968 (patch)
treeed3de9ac1eb47b55ac252ca025905b8b9f92d7c3
parent1069c22d0da82ba81a9fb1242a808e0a65316b55 (diff)
move radio button into button class
-rw-r--r--Makefile.mingw7
-rw-r--r--Makefile.mingw-amd647
-rw-r--r--Makefile.vc65
-rw-r--r--Makefile.vc6-ansi5
-rw-r--r--alf/alfbutton.cpp174
-rw-r--r--alf/alfradiobutton.cpp96
6 files changed, 166 insertions, 128 deletions
diff --git a/Makefile.mingw b/Makefile.mingw
index d92cfd7..991fce7 100644
--- a/Makefile.mingw
+++ b/Makefile.mingw
@@ -8,7 +8,7 @@ LDFLAGS = -luser32 -lcomctl32 -lshell32 -lversion -static
all: out/widgetfactory.exe out/alf/alf.c out/widgetfactory-c.exe
-out/widgetfactory.exe: out/widgetfactory.o out/alfbutton.o out/alfcombobox.o out/alfcompat.o out/alf.o out/alfdpiaware.o out/alfedit.o out/alfgroupbox.o out/alflabel.o out/alflayout.o out/alfnotebook.o out/alfpanel.o out/alfradiobutton.o out/alfwindow.o
+out/widgetfactory.exe: out/widgetfactory.o out/alfbutton.o out/alfcombobox.o out/alfcompat.o out/alf.o out/alfdpiaware.o out/alfedit.o out/alfgroupbox.o out/alflabel.o out/alflayout.o out/alfnotebook.o out/alfpanel.o out/alfwindow.o
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
out/alfbutton.o: alf/alfbutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
@@ -44,16 +44,13 @@ out/alfnotebook.o: alf/alfnotebook.cpp alf/alfcompat.h alf/alf.h alf/alflayout.
out/alfpanel.o: alf/alfpanel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
-out/alfradiobutton.o: alf/alfradiobutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
- $(CXX) $(CXXFLAGS) -c -o $@ $<
-
out/alfwindow.o: alf/alfwindow.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
out/widgetfactory.o: widgetfactory.cpp alf/alf.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
-out/alf/alf.c: alf/alflist.h alf/alflayout.h alf/alfcompat.h alf/alfpriv.h alf/alfbutton.cpp alf/alfcombobox.cpp alf/alfcompat.cpp alf/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alfgroupbox.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfradiobutton.cpp alf/alfwindow.cpp
+out/alf/alf.c: alf/alflist.h alf/alflayout.h alf/alfcompat.h alf/alfpriv.h alf/alfbutton.cpp alf/alfcombobox.cpp alf/alfcompat.cpp alf/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alfgroupbox.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfwindow.cpp
@mkdir -p out/alf
@printf "#include \"alf.h\"\\n" > $@
@cat $^ | grep -v "^#pragma once" | grep -v "^#include \"alf" >> $@
diff --git a/Makefile.mingw-amd64 b/Makefile.mingw-amd64
index 01d8f7c..98fed95 100644
--- a/Makefile.mingw-amd64
+++ b/Makefile.mingw-amd64
@@ -8,7 +8,7 @@ LDFLAGS = -luser32 -lcomctl32 -lshell32 -lversion -static
all: out/widgetfactory64.exe out/alf/alf64.c out/widgetfactory64-c.exe
-out/widgetfactory64.exe: out/widgetfactory.amd64.o out/alfbutton.amd64.o out/alfcombobox.amd64.o out/alfcompat.amd64.o out/alf.amd64.o out/alfdpiaware.amd64.o out/alfedit.amd64.o out/alfgroupbox.amd64.o out/alflabel.amd64.o out/alflayout.amd64.o out/alfnotebook.amd64.o out/alfpanel.amd64.o out/alfradiobutton.amd64.o out/alfwindow.amd64.o
+out/widgetfactory64.exe: out/widgetfactory.amd64.o out/alfbutton.amd64.o out/alfcombobox.amd64.o out/alfcompat.amd64.o out/alf.amd64.o out/alfdpiaware.amd64.o out/alfedit.amd64.o out/alfgroupbox.amd64.o out/alflabel.amd64.o out/alflayout.amd64.o out/alfnotebook.amd64.o out/alfpanel.amd64.o out/alfwindow.amd64.o
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
out/alfbutton.amd64.o: alf/alfbutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
@@ -44,16 +44,13 @@ out/alfnotebook.amd64.o: alf/alfnotebook.cpp alf/alfcompat.h alf/alf.h alf/alfl
out/alfpanel.amd64.o: alf/alfpanel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
-out/alfradiobutton.amd64.o: alf/alfradiobutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
- $(CXX) $(CXXFLAGS) -c -o $@ $<
-
out/alfwindow.amd64.o: alf/alfwindow.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
out/widgetfactory.amd64.o: widgetfactory.cpp alf/alf.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
-out/alf/alf64.c: alf/alflist.h alf/alflayout.h alf/alfcompat.h alf/alfpriv.h alf/alfbutton.cpp alf/alfcombobox.cpp alf/alfcompat.cpp alf/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alfgroupbox.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfradiobutton.cpp alf/alfwindow.cpp
+out/alf/alf64.c: alf/alflist.h alf/alflayout.h alf/alfcompat.h alf/alfpriv.h alf/alfbutton.cpp alf/alfcombobox.cpp alf/alfcompat.cpp alf/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alfgroupbox.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfwindow.cpp
@mkdir -p out/alf
@printf "#include \"alf.h\"\\n" > $@
@cat $^ | grep -v "^#pragma once" | grep -v "^#include \"alf" >> $@
diff --git a/Makefile.vc6 b/Makefile.vc6
index 7dbbd6d..88daafe 100644
--- a/Makefile.vc6
+++ b/Makefile.vc6
@@ -4,7 +4,7 @@ CXX = cl.exe
CFLAGS = -O2 -GA -W3 -DUNICODE -D_UNICODE -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo
LDFLAGS = /link unicows.lib kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib
-out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alfgroupbox.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfradiobutton.obj out/alfwindow.obj
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alfgroupbox.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.obj
$(CXX) $(CFLAGS) -Fe$@ $** $(LDFLAGS)
out/alfbutton.obj: alf/alfbutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
@@ -40,9 +40,6 @@ out/alfnotebook.obj: alf/alfnotebook.cpp alf/alfcompat.h alf/alf.h alf/alflayou
out/alfpanel.obj: alf/alfpanel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alfpanel.cpp
-out/alfradiobutton.obj: alf/alfradiobutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
- $(CXX) $(CFLAGS) -c -Fo$@ alf/alfradiobutton.cpp
-
out/alfwindow.obj: alf/alfwindow.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alfwindow.cpp
diff --git a/Makefile.vc6-ansi b/Makefile.vc6-ansi
index 698a582..57aa6df 100644
--- a/Makefile.vc6-ansi
+++ b/Makefile.vc6-ansi
@@ -4,7 +4,7 @@ CXX = cl.exe
CFLAGS = -O2 -GA -W3 -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo
LDFLAGS = /link /entry:_entry /opt:nowin98 /fixed:no kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib
-out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alfgroupbox.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfradiobutton.obj out/alfwindow.obj
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alfgroupbox.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.obj
$(CXX) $(CFLAGS) -Fe$@ $** $(LDFLAGS)
out/alfbutton.obj: alf/alfbutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
@@ -40,9 +40,6 @@ out/alfnotebook.obj: alf/alfnotebook.cpp alf/alfcompat.h alf/alf.h alf/alflayou
out/alfpanel.obj: alf/alfpanel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alfpanel.cpp
-out/alfradiobutton.obj: alf/alfradiobutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
- $(CXX) $(CFLAGS) -c -Fo$@ alf/alfradiobutton.cpp
-
out/alfwindow.obj: alf/alfwindow.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alfwindow.cpp
diff --git a/alf/alfbutton.cpp b/alf/alfbutton.cpp
index e63b5ce..f809410 100644
--- a/alf/alfbutton.cpp
+++ b/alf/alfbutton.cpp
@@ -24,6 +24,16 @@
#define CBS_MIXEDPRESSED 11
#define CBS_MIXEDDISABLED 12
+#define BP_RADIOBUTTON 2
+#define RBS_UNCHECKEDNORMAL 1
+#define RBS_UNCHECKEDHOT 2
+#define RBS_UNCHECKEDPRESSED 3
+#define RBS_UNCHECKEDDISABLED 4
+#define RBS_CHECKEDNORMAL 5
+#define RBS_CHECKEDHOT 6
+#define RBS_CHECKEDPRESSED 7
+#define RBS_CHECKEDDISABLED 8
+
#define ALF_NTBTN_FLAG_UXTHEME 1
#define ALF_NTBTN_FLAG_IS_DISABLED 2
#define ALF_NTBTN_FLAG_IS_DEFAULT 4
@@ -242,7 +252,7 @@ ALF_NtButton_CalculateSize(HWND hwnd, ALFNtButtonPriv *priv, SIZE *pSize)
DrawTextW(hdc, priv->text, -1, &r, format);
- if (priv->drawFlags & ALF_NTBTN_FLAG_DRAW_CHECKBOX) {
+ if (priv->drawFlags & (ALF_NTBTN_FLAG_DRAW_CHECKBOX | ALF_NTBTN_FLAG_DRAW_RADIOBTN | ALF_NTBTN_FLAG_DRAW_TRISTATE)) {
int checkwidth = 12 * priv->dpi / 96 + 1;
int space = ALF_Button_CalcCheckboxTextSpace(hdc);
@@ -300,7 +310,7 @@ ALF_NtButton_RenderUxtheme(HWND hwnd, ALFNtButtonPriv *priv, int uxpart, int uxs
RECT r;
GetClientRect(hwnd, &r);
- if (uxpart == BP_CHECKBOX) {
+ if (uxpart == BP_CHECKBOX || uxpart == BP_RADIOBUTTON) {
if (priv->bgcolor == ALF_COLOR_TRANSPARENT) {
ALF_Compat_DrawThemeParentBackground(hwnd, hDC, rcPaint);
} else {
@@ -320,7 +330,7 @@ ALF_NtButton_RenderUxtheme(HWND hwnd, ALFNtButtonPriv *priv, int uxpart, int uxs
r.right - r.left,
r.bottom - r.top };
- ALF_Compat_DrawThemeBackground(priv->hTheme, hDC, BP_CHECKBOX, uxstate, &rcCheckmark, rcPaint);
+ ALF_Compat_DrawThemeBackground(priv->hTheme, hDC, uxpart, uxstate, &rcCheckmark, rcPaint);
RECT textbounds = rcText;
DrawTextW(hDC, priv->text, -1, &textbounds, DT_LEFT | DT_CALCRECT | DT_EXPANDTABS);
@@ -335,7 +345,7 @@ ALF_NtButton_RenderUxtheme(HWND hwnd, ALFNtButtonPriv *priv, int uxpart, int uxs
if (priv->drawFlags & ALF_NTBTN_FLAG_HIDEACCEL)
style |= DT_HIDEPREFIX;
- ALF_Compat_DrawThemeText(priv->hTheme, hDC, BP_CHECKBOX, uxstate, priv->text, -1, style, 0, &texttarget);
+ ALF_Compat_DrawThemeText(priv->hTheme, hDC, uxpart, uxstate, priv->text, -1, style, 0, &texttarget);
if ((priv->drawFlags & ALF_NTBTN_FLAG_IS_FOCUSED) && !(priv->drawFlags & ALF_NTBTN_FLAG_HIDEFOCUS)) {
RECT f = texttarget;
@@ -395,7 +405,7 @@ ALF_NtButton_RenderClassicCheckbox(HWND hwnd, ALFNtButtonPriv *priv, HDC dc, REC
HFONT oldfont = SelectFont(dc, priv->font);
- UINT dfcs = DFCS_BUTTONCHECK;
+ UINT dfcs = priv->drawFlags & ALF_NTBTN_FLAG_DRAW_RADIOBTN ? DFCS_BUTTONRADIO : DFCS_BUTTONCHECK;
if (priv->drawFlags & ALF_NTBTN_FLAG_IS_CHECKED)
dfcs |= DFCS_CHECKED;
if (priv->drawFlags & ALF_NTBTN_FLAG_IS_PRESSED)
@@ -517,7 +527,7 @@ ALF_NtButton_RenderClassicPushBtn(HWND hwnd, ALFNtButtonPriv *priv, HDC dc, RECT
static void
ALF_NtButton_RenderClassic(HWND hwnd, ALFNtButtonPriv *priv, HDC dc, RECT *rcPaint)
{
- if (priv->drawFlags & ALF_NTBTN_FLAG_DRAW_CHECKBOX) {
+ if (priv->drawFlags & (ALF_NTBTN_FLAG_DRAW_CHECKBOX | ALF_NTBTN_FLAG_DRAW_RADIOBTN)) {
ALF_NtButton_RenderClassicCheckbox(hwnd, priv, dc, rcPaint);
} else {
ALF_NtButton_RenderClassicPushBtn(hwnd, priv, dc, rcPaint);
@@ -555,6 +565,28 @@ ALF_NtButton_Paint(HWND hwnd, ALFNtButtonPriv *priv, HDC dc, RECT *r)
if (priv->drawFlags & ALF_NTBTN_FLAG_IS_DISABLED)
stateid = CBS_UNCHECKEDDISABLED;
}
+ } else if (priv->drawFlags & ALF_NTBTN_FLAG_DRAW_RADIOBTN) {
+ partid = BP_RADIOBUTTON;
+
+ if (priv->drawFlags & ALF_NTBTN_FLAG_IS_CHECKED) {
+ stateid = RBS_CHECKEDNORMAL;
+
+ if (priv->drawFlags & ALF_NTBTN_FLAG_IS_HOT)
+ stateid = RBS_CHECKEDHOT;
+ if (priv->drawFlags & ALF_NTBTN_FLAG_IS_PRESSED)
+ stateid = RBS_CHECKEDPRESSED;
+ if (priv->drawFlags & ALF_NTBTN_FLAG_IS_DISABLED)
+ stateid = RBS_CHECKEDDISABLED;
+ } else {
+ stateid = RBS_UNCHECKEDNORMAL;
+
+ if (priv->drawFlags & ALF_NTBTN_FLAG_IS_HOT)
+ stateid = RBS_UNCHECKEDHOT;
+ if (priv->drawFlags & ALF_NTBTN_FLAG_IS_PRESSED)
+ stateid = RBS_UNCHECKEDPRESSED;
+ if (priv->drawFlags & ALF_NTBTN_FLAG_IS_DISABLED)
+ stateid = RBS_UNCHECKEDDISABLED;
+ }
} else {
partid = BP_PUSHBUTTON;
stateid = PBS_NORMAL;
@@ -660,6 +692,39 @@ ALF_NtButton_Paint(HWND hwnd, ALFNtButtonPriv *priv, HDC dc, RECT *r)
}
static void
+ALF_NtButton_FixRadioButtonCheck(HWND hwnd, ALFNtButtonPriv *priv, BOOL unselectOthers)
+{
+ if ((priv->drawFlags & ALF_NTBTN_FLAG_DRAW_RADIOBTN) == 0)
+ return;
+
+ // fix WS_TABSTOP style
+ LONG s = GetWindowLong(hwnd, GWL_STYLE);
+ if (priv->drawFlags & ALF_NTBTN_FLAG_IS_CHECKED)
+ s |= WS_TABSTOP;
+ else
+ s &= ~WS_TABSTOP;
+ SetWindowLong(hwnd, GWL_STYLE, s);
+
+ if (priv->drawFlags & ALF_NTBTN_FLAG_IS_CHECKED && unselectOthers) {
+ // uncheck all other radio buttons in the group
+ HWND p = GetParent(hwnd);
+ HWND h = GetNextDlgGroupItem(p, hwnd, FALSE);
+ for (int limit = 1000; limit > 0; --limit) {
+ if (h == hwnd || h == NULL)
+ break;
+
+ LRESULT dlgc = SendMessage(h, WM_GETDLGCODE, 0, 0);
+ if (dlgc & DLGC_RADIOBUTTON) {
+ SendMessage(h, BM_SETCHECK, BST_UNCHECKED, 0);
+ }
+
+ h = GetNextDlgGroupItem(p, h, FALSE);
+ }
+ }
+}
+
+
+static void
ALF_NtButton_Clicked(HWND hwnd, ALFNtButtonPriv *priv)
{
if (priv->drawFlags & ALF_NTBTN_FLAG_DRAW_CHECKBOX) {
@@ -668,6 +733,12 @@ ALF_NtButton_Clicked(HWND hwnd, ALFNtButtonPriv *priv)
} else {
ALF_NtButton_ModifyDrawFlags(hwnd, priv, ALF_NTBTN_FLAG_IS_CHECKED, 0, TRUE);
}
+ } else if (priv->drawFlags & ALF_NTBTN_FLAG_DRAW_RADIOBTN) {
+ if (priv->drawFlags & ALF_NTBTN_FLAG_IS_CHECKED)
+ return;
+
+ ALF_NtButton_ModifyDrawFlags(hwnd, priv, ALF_NTBTN_FLAG_IS_CHECKED, 0, TRUE);
+ ALF_NtButton_FixRadioButtonCheck(hwnd, priv, TRUE);
}
SendMessageW(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLong(hwnd, GWL_ID), BN_CLICKED), (LPARAM)hwnd);
@@ -681,8 +752,10 @@ ALF_NtButton_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (uMsg == WM_CREATE) {
priv = ALF_NtButton_InitializePriv((CREATESTRUCTW *)lParam);
- if (((CREATESTRUCTW *)lParam)->style & BS_CHECKBOX)
+ if ((((CREATESTRUCTW *)lParam)->style & 0x0C0F) == BS_AUTOCHECKBOX)
priv->drawFlags |= ALF_NTBTN_FLAG_DRAW_CHECKBOX;
+ if ((((CREATESTRUCTW *)lParam)->style & 0x0C0F) == BS_AUTORADIOBUTTON)
+ priv->drawFlags |= ALF_NTBTN_FLAG_DRAW_RADIOBTN;
SetWindowLongPtrW(hwnd, 0, (LONG_PTR)priv);
@@ -729,6 +802,9 @@ ALF_NtButton_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} else {
ALF_NtButton_ModifyDrawFlags(hwnd, priv, 0, ALF_NTBTN_FLAG_IS_CHECKED, TRUE);
}
+
+ ALF_NtButton_FixRadioButtonCheck(hwnd, priv, FALSE);
+
return 0;
} else if (uMsg == BM_GETCHECK) {
if (priv->drawFlags & ALF_NTBTN_FLAG_IS_CHECKED)
@@ -777,6 +853,10 @@ ALF_NtButton_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
ALF_NtButton_ModifyDrawFlags(hwnd, priv, 0, ALF_NTBTN_FLAG_IS_HOT, TRUE);
} else if (uMsg == WM_SETFOCUS) {
ALF_NtButton_ModifyDrawFlags(hwnd, priv, ALF_NTBTN_FLAG_IS_FOCUSED, 0, TRUE);
+
+ if ((priv->drawFlags & ALF_NTBTN_FLAG_DRAW_RADIOBTN) && !(priv->drawFlags & ALF_NTBTN_FLAG_IS_CHECKED)) {
+ ALF_NtButton_Clicked(hwnd, priv);
+ }
} else if (uMsg == WM_KILLFOCUS) {
ALF_NtButton_ModifyDrawFlags(hwnd, priv, 0, ALF_NTBTN_FLAG_IS_FOCUSED | ALF_NTBTN_FLAG_IS_PRESSED, TRUE);
} else if (uMsg == WM_LBUTTONDOWN) {
@@ -950,7 +1030,7 @@ ALF_NtButton_Create(HWND win, WORD id, int x, int y, const TCHAR *text, DWORD ad
int minwidth = 5625;
int minheight = 1725;
- if (addstyle & (BS_CHECKBOX | BS_RADIOBUTTON)) {
+ if (addstyle & (BS_CHECKBOX | BS_RADIOBUTTON | BS_AUTORADIOBUTTON)) {
minwidth = 0;
minheight = 0;
}
@@ -967,6 +1047,7 @@ ALF_NtButton_Create(HWND win, WORD id, int x, int y, const TCHAR *text, DWORD ad
#define ALF_CLSCBTN_FLAG_IS_DEFAULT ((DWORD)1)
#define ALF_CLSCBTN_FLAG_DRAW_CHECKBOX ((DWORD)2)
#define ALF_CLSCBTN_FLAG_IS_CHECKED ((DWORD)4)
+#define ALF_CLSCBTN_FLAG_DRAW_RADIO ((DWORD)8)
typedef struct {
WNDPROC origWndProc;
@@ -1021,7 +1102,7 @@ ALF_ClassicButton_CalculateSize(HWND hwnd, ALFClassicButtonPriv *priv, SIZE *pSi
ALF_Free(textbuf);
- if (priv->flags & ALF_CLSCBTN_FLAG_DRAW_CHECKBOX) {
+ if (priv->flags & (ALF_CLSCBTN_FLAG_DRAW_CHECKBOX | ALF_CLSCBTN_FLAG_DRAW_RADIO)) {
int checkwidth = 13;
int space = ALF_Button_CalcCheckboxTextSpace(hdc);
@@ -1072,7 +1153,7 @@ ALF_ClassicButton_PaintCheckbox(HWND hwnd, ALFClassicButtonPriv *priv, DRAWITEMS
}
if (dis->itemAction & (ODA_DRAWENTIRE | ODA_SELECT)) {
- UINT dfcs = DFCS_BUTTONCHECK;
+ UINT dfcs = priv->flags & ALF_CLSCBTN_FLAG_DRAW_RADIO ? DFCS_BUTTONRADIO : DFCS_BUTTONCHECK;
if (priv->flags & ALF_CLSCBTN_FLAG_IS_CHECKED)
dfcs |= DFCS_CHECKED;
if (dis->itemState & ODS_SELECTED)
@@ -1192,13 +1273,45 @@ ALF_ClassicButton_PaintButton(HWND hwnd, ALFClassicButtonPriv *priv, DRAWITEMSTR
static void
ALF_ClassicButton_Paint(HWND hwnd, ALFClassicButtonPriv *priv, DRAWITEMSTRUCT *dis)
{
- if (priv->flags & ALF_CLSCBTN_FLAG_DRAW_CHECKBOX) {
+ if (priv->flags & (ALF_CLSCBTN_FLAG_DRAW_CHECKBOX | ALF_CLSCBTN_FLAG_DRAW_RADIO)) {
ALF_ClassicButton_PaintCheckbox(hwnd, priv, dis);
} else {
ALF_ClassicButton_PaintButton(hwnd, priv, dis);
}
}
+static void
+ALF_ClassicButton_FixRadioButtonCheck(HWND hwnd, ALFClassicButtonPriv *priv, BOOL unselectOthers)
+{
+ if ((priv->flags & ALF_CLSCBTN_FLAG_DRAW_RADIO) == 0)
+ return;
+
+ // fix WS_TABSTOP style
+ LONG s = GetWindowLong(hwnd, GWL_STYLE);
+ if (priv->flags & ALF_CLSCBTN_FLAG_IS_CHECKED)
+ s |= WS_TABSTOP;
+ else
+ s &= ~WS_TABSTOP;
+ SetWindowLong(hwnd, GWL_STYLE, s);
+
+ if (priv->flags & ALF_CLSCBTN_FLAG_IS_CHECKED && unselectOthers) {
+ // uncheck all other radio buttons in the group
+ HWND p = GetParent(hwnd);
+ HWND h = GetNextDlgGroupItem(p, hwnd, FALSE);
+ for (int limit = 1000; limit > 0; --limit) {
+ if (h == hwnd || h == NULL)
+ break;
+
+ LRESULT dlgc = SendMessage(h, WM_GETDLGCODE, 0, 0);
+ if (dlgc & DLGC_RADIOBUTTON) {
+ SendMessage(h, BM_SETCHECK, BST_UNCHECKED, 0);
+ }
+
+ h = GetNextDlgGroupItem(p, h, FALSE);
+ }
+ }
+}
+
static LRESULT CALLBACK
ALF_ClassicButton_WndProc(ALFClassicButtonPriv *priv, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
@@ -1231,6 +1344,10 @@ ALF_ClassicButton_WndProc(ALFClassicButtonPriv *priv, HWND hwnd, UINT uMsg, WPAR
rcCheck.right = 13;
rcCheck.bottom = rcClient.bottom - rcClient.top;
InvalidateRect(hwnd, &rcCheck, TRUE);
+ } else if (HIWORD(wParam) == BN_CLICKED && priv->flags & ALF_CLSCBTN_FLAG_DRAW_RADIO) {
+ priv->flags |= ALF_CLSCBTN_FLAG_IS_CHECKED;
+ InvalidateRect(hwnd, NULL, TRUE);
+ ALF_ClassicButton_FixRadioButtonCheck(hwnd, priv, TRUE);
}
} else if (uMsg == WM_ERASEBKGND) {
return TRUE;
@@ -1245,6 +1362,8 @@ ALF_ClassicButton_WndProc(ALFClassicButtonPriv *priv, HWND hwnd, UINT uMsg, WPAR
if (wParam & BST_CHECKED)
priv->flags |= ALF_CLSCBTN_FLAG_IS_CHECKED;
+ ALF_ClassicButton_FixRadioButtonCheck(hwnd, priv, FALSE);
+
InvalidateRect(hwnd, NULL, TRUE);
return 0;
} else if (uMsg == BM_GETCHECK) {
@@ -1256,11 +1375,19 @@ ALF_ClassicButton_WndProc(ALFClassicButtonPriv *priv, HWND hwnd, UINT uMsg, WPAR
} else if (uMsg == WM_GETDLGCODE) {
if (priv->flags & ALF_CLSCBTN_FLAG_DRAW_CHECKBOX) {
return (LRESULT)DLGC_BUTTON;
+ } else if (priv->flags & ALF_CLSCBTN_FLAG_DRAW_RADIO) {
+ return (LRESULT)DLGC_RADIOBUTTON;
} else if (priv->flags & ALF_CLSCBTN_FLAG_IS_DEFAULT) {
return (LRESULT)DLGC_DEFPUSHBUTTON;
} else {
return (LRESULT)DLGC_UNDEFPUSHBUTTON;
}
+ } else if (uMsg == WM_SETFOCUS) {
+ if (priv->flags & ALF_CLSCBTN_FLAG_DRAW_RADIO && !(priv->flags & ALF_CLSCBTN_FLAG_IS_CHECKED)) {
+ priv->flags |= ALF_CLSCBTN_FLAG_IS_CHECKED;
+ ALF_ClassicButton_FixRadioButtonCheck(hwnd, priv, TRUE);
+ InvalidateRect(hwnd, NULL, TRUE);
+ }
} else if (uMsg == WM_SETFONT) {
ALF_InvalidateLayout(GetParent(hwnd));
InvalidateRect(hwnd, NULL, TRUE);
@@ -1292,11 +1419,20 @@ ALF_ClassicButton_Create(HWND win, WORD id, int x, int y, const TCHAR *text, DWO
int minwidth = 5625;
int minheight = 1725;
- if (style & BS_CHECKBOX) {
+ if ((style & 0x0C0F) == BS_AUTOCHECKBOX) {
minwidth = 0;
minheight = 0;
priv->flags |= ALF_CLSCBTN_FLAG_DRAW_CHECKBOX;
}
+ if ((style & 0x0C0F) == BS_AUTORADIOBUTTON) {
+ minwidth = 0;
+ minheight = 0;
+ priv->flags |= ALF_CLSCBTN_FLAG_DRAW_RADIO;
+
+ LONG s = GetWindowLong(hwndButton, GWL_STYLE);
+ s &= ~WS_TABSTOP;
+ SetWindowLong(hwndButton, GWL_STYLE, s);
+ }
priv->origWndProc = (WNDPROC)GetWindowLongPtr(hwndButton, GWLP_WNDPROC);
@@ -1323,9 +1459,19 @@ HWND
ALF_AddCheckbox(HWND win, WORD id, int x, int y, const TCHAR *text)
{
if (_alf_buttonClass) {
- return ALF_NtButton_Create(win, id, x, y, text, WS_TABSTOP | BS_CHECKBOX);
+ return ALF_NtButton_Create(win, id, x, y, text, WS_TABSTOP | BS_AUTOCHECKBOX);
+ } else {
+ return ALF_ClassicButton_Create(win, id, x, y, text, BS_AUTOCHECKBOX);
+ }
+}
+
+HWND
+ALF_AddRadioButton(HWND parent, WORD id, int x, int y, const TCHAR *text)
+{
+ if (_alf_buttonClass) {
+ return ALF_NtButton_Create(parent, id, x, y, text, BS_AUTORADIOBUTTON);
} else {
- return ALF_ClassicButton_Create(win, id, x, y, text, BS_CHECKBOX);
+ return ALF_ClassicButton_Create(parent, id, x, y, text, BS_AUTORADIOBUTTON);
}
}
diff --git a/alf/alfradiobutton.cpp b/alf/alfradiobutton.cpp
deleted file mode 100644
index 2fe6cb6..0000000
--- a/alf/alfradiobutton.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-#include "alfpriv.h"
-
-typedef struct {
- ALFColor bgcolor;
- WNDPROC origWndProc;
-} ALFRadioPriv;
-
-static ALFRadioPriv *
-ALF_Radio_InitializePriv(void)
-{
- return ALF_New(ALFRadioPriv, 1);
-}
-
-static void
-ALF_Radio_FreePriv(ALFRadioPriv *priv)
-{
- ALF_Free(priv);
-}
-
-static LRESULT
-ALF_Radio_HandleCtlColor(HWND window, ALFRadioPriv *priv, HDC hDC)
-{
- (void)priv; (void)window;
-
- SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT));
- SetBkColor(hDC, GetSysColor(COLOR_BTNFACE));
- SetBkMode(hDC, OPAQUE);
- return (LRESULT)GetSysColorBrush(COLOR_BTNFACE);
-}
-
-static LRESULT CALLBACK
-ALF_Radio_WindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
-{
- ALFRadioPriv *priv = (ALFRadioPriv *)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_Compat_IsAppThemed())
- InvalidateRect(window, NULL, TRUE);
- }
- return TRUE;
- }
-
- if (msg == 0x2000 + WM_CTLCOLORSTATIC || msg == 0x2000 + WM_CTLCOLORBTN) {
- return ALF_Radio_HandleCtlColor(window, priv, (HDC)wparam);
- }
-
- if (msg == ALF_WM_BACKGROUNDCHANGE) {
- if (priv->bgcolor == ALF_COLOR_TRANSPARENT && ALF_Compat_IsAppThemed()) {
- 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_Radio_FreePriv(priv);
- return CallWindowProc(orig, window, msg, wparam, lparam);
- }
-
- return CallWindowProc(priv->origWndProc, window, msg, wparam, lparam);
-}
-
-HWND
-ALF_AddRadioButton(HWND parent, WORD id, int x, int y, const TCHAR *text)
-{
- HWND hwnd = CreateWindowEx(0,
- TEXT("BUTTON"),
- text,
- WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
- 0, 0, 100, 100,
- parent,
- (HMENU)(ULONG_PTR)id,
- ALF_HINSTANCE,
- NULL);
-
- ALFRadioPriv *priv = ALF_Radio_InitializePriv();
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)priv);
- priv->origWndProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)ALF_Radio_WindowProc);
-
- ALF_AddWidget(parent, x, y, hwnd, 0, 0, ALF_LAYOUT_SIZE_CHECKBOX | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_INHERITBGCOLOR | ALF_LAYOUT_SENDBGCHANGE);
-
- return hwnd;
-}
-