diff options
| author | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2020-05-23 14:26:28 +0200 |
|---|---|---|
| committer | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2020-05-23 14:26:28 +0200 |
| commit | 9d237b5fd80e55d8b5e367323b6ee58be896f968 (patch) | |
| tree | ed3de9ac1eb47b55ac252ca025905b8b9f92d7c3 | |
| parent | 1069c22d0da82ba81a9fb1242a808e0a65316b55 (diff) | |
move radio button into button class
| -rw-r--r-- | Makefile.mingw | 7 | ||||
| -rw-r--r-- | Makefile.mingw-amd64 | 7 | ||||
| -rw-r--r-- | Makefile.vc6 | 5 | ||||
| -rw-r--r-- | Makefile.vc6-ansi | 5 | ||||
| -rw-r--r-- | alf/alfbutton.cpp | 174 | ||||
| -rw-r--r-- | alf/alfradiobutton.cpp | 96 |
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; -} - |
