From e9911ec586892bc150dbe39ecc1ecf300d89a6f4 Mon Sep 17 00:00:00 2001 From: Jonas Kümmerlin Date: Sat, 23 May 2020 21:25:42 +0200 Subject: rework default button and focus handling --- alf/alfwindow.cpp | 109 +++++++++++++++++++++++++++++++++--------------------- widgetfactory.cpp | 21 +++++++++-- 2 files changed, 85 insertions(+), 45 deletions(-) diff --git a/alf/alfwindow.cpp b/alf/alfwindow.cpp index 64cb6b0..c33a2b4 100644 --- a/alf/alfwindow.cpp +++ b/alf/alfwindow.cpp @@ -68,6 +68,66 @@ ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv) SendMessage(win, WM_SETFONT, (WPARAM)priv->hMessageFont, (LPARAM)1); } +static BOOL CALLBACK +ALF_Window_RemoveDefButton_EnumChildProc(HWND hwnd, LPARAM lParam) +{ + HWND keeper = (HWND)lParam; + if (hwnd != keeper && (SendMessage(hwnd, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)) { + SendMessage(hwnd, BM_SETSTYLE, BS_PUSHBUTTON, TRUE); + } + + return TRUE; +} + +static void +ALF_Window_RemoveDefButton(HWND hwnd, ALFWindowPriv *priv, HWND keeper) +{ + (void)priv; + + EnumChildWindows(hwnd, ALF_Window_RemoveDefButton_EnumChildProc, (LPARAM)keeper); +} + +static void +ALF_Window_FixDefButton(HWND hwnd, ALFWindowPriv *priv, HWND prevFocus, HWND currFocus, BOOL force) +{ + LRESULT prevCode = prevFocus ? SendMessage(prevFocus, WM_GETDLGCODE, 0, 0) : 0; + LRESULT currCode = currFocus ? SendMessage(currFocus, WM_GETDLGCODE, 0, 0) : 0; + + // speed hack: only do something if the focus moves from or to a defaultable button + if (!force && !(prevFocus && (prevCode & (DLGC_DEFPUSHBUTTON|DLGC_UNDEFPUSHBUTTON))) + && !(currFocus && (currCode & (DLGC_DEFPUSHBUTTON|DLGC_UNDEFPUSHBUTTON)))) + return; + + // find the target for the new default button + HWND newDefBtn = NULL; + LRESULT newDefCode = 0; + if (currFocus && (currCode & (DLGC_DEFPUSHBUTTON|DLGC_UNDEFPUSHBUTTON))) { + newDefBtn = currFocus; + newDefCode = currCode; + } else { + WORD defid = priv->defid != (WORD)-1 ? priv->defid : IDOK; + HWND defhwnd = ALF_WidgetHwndById(hwnd, defid); + if (defhwnd) { + newDefCode = SendMessage(defhwnd, WM_GETDLGCODE, 0, 0); + if (newDefCode & (DLGC_DEFPUSHBUTTON|DLGC_UNDEFPUSHBUTTON)) + newDefBtn = defhwnd; + } + } + + // speed hack: stop here if the target button is already default + // there is supposed to be exactly one default button + if (!force && newDefBtn && (newDefCode & DLGC_DEFPUSHBUTTON)) + return; + + // remove default button style from all other buttons + ALF_Window_RemoveDefButton(hwnd, priv, newDefBtn); + + // apply default button style to the new def btn + if (newDefBtn && (newDefCode & DLGC_UNDEFPUSHBUTTON)) { + SendMessage(newDefBtn, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE); + } +} + static void ALF_ApplyFocus(HWND hwnd, ALFWindowPriv *priv, BOOL restoringFocus) { @@ -78,26 +138,7 @@ ALF_ApplyFocus(HWND hwnd, ALFWindowPriv *priv, BOOL restoringFocus) if (GetForegroundWindow() == hwnd) { HWND oldFocus = SetFocus(priv->hwndFocus); - // FIXME! restore default button state - if (oldFocus && SendMessage(oldFocus, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) { - SendMessage(oldFocus, BM_SETSTYLE, BS_PUSHBUTTON, TRUE); - } - - if (priv->defid != (WORD)-1) { - HWND hwndOld = ALF_WidgetHwndById(hwnd, priv->defid); - if (hwndOld && SendMessage(hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) { - SendMessage(hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE); - } - } - - if (priv->hwndFocus && SendMessage(priv->hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_UNDEFPUSHBUTTON) { - SendMessage(priv->hwndFocus, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE); - } else { - HWND hwndDef = ALF_WidgetHwndById(hwnd, priv->defid); - if (hwndDef && SendMessage(hwndDef, WM_GETDLGCODE, 0, 0) & DLGC_UNDEFPUSHBUTTON) { - SendMessage(hwndDef, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE); - } - } + ALF_Window_FixDefButton(hwnd, priv, oldFocus, priv->hwndFocus, FALSE); } } else { priv->hwndFocus = GetNextDlgTabItem(hwnd, NULL, FALSE); @@ -278,18 +319,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) } else { priv->hwndFocus = GetFocus(); - // FIXME! remove default button state - // there has to be a better way to do this - if (priv->defid != (WORD)-1) { - HWND hwndDefBtn = ALF_WidgetHwndById(hwnd, priv->defid); - if (hwndDefBtn && SendMessage(hwndDefBtn, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) { - SendMessage(hwndDefBtn, BM_SETSTYLE, BS_PUSHBUTTON, TRUE); - } - } - - if (priv->hwndFocus && SendMessage(priv->hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) { - SendMessage(priv->hwndFocus, BM_SETSTYLE, BS_PUSHBUTTON, TRUE); - } + ALF_Window_RemoveDefButton(hwnd, priv, NULL); } } return 0; @@ -383,17 +413,12 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) } } if (msg == DM_SETDEFID) { - if (priv->defid != (WORD)-1) { - HWND hwndOld = ALF_WidgetHwndById(hwnd, priv->defid); - if (hwndOld && SendMessage(hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) { - SendMessage(hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE); - } - } + WORD newdefid = (WORD)wparam; + if (newdefid != priv->defid) { + priv->defid = newdefid; - priv->defid = (WORD)wparam; - HWND hwndNew = ALF_WidgetHwndById(hwnd, priv->defid); - if (hwndNew && SendMessage(hwndNew, WM_GETDLGCODE, 0, 0) & DLGC_UNDEFPUSHBUTTON) { - SendMessage(hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE); + if (GetForegroundWindow() == hwnd) + ALF_Window_FixDefButton(hwnd, priv, NULL, GetFocus(), TRUE); } return TRUE; } diff --git a/widgetfactory.cpp b/widgetfactory.cpp index f036387..8cdc6a4 100644 --- a/widgetfactory.cpp +++ b/widgetfactory.cpp @@ -20,7 +20,7 @@ static const TCHAR *g_paneLabels[PANE__MAX] = { }; enum { - ID_COMBO1, + ID_COMBO1 = 2, ID_COMBO2, ID_LBLCOMBOTEXT, ID_BTNCOMBOCLEAR, @@ -202,7 +202,7 @@ buttonPanelAttach(void *closure, HWND outerPanel) ALF_AddLabel(panel, (WORD)-1, 4, 0, TEXT("native")); ALF_AddLabel(panel, (WORD)-1, 0, 6, TEXT("layout dummy")); - b = ALF_AddButton(panel, ID_HELLO, 2, 2, TEXT("&Hello, World!")); + b = ALF_AddButton(panel, (WORD)-1, 2, 2, TEXT("Hello, World!")); ALF_SetWidgetLayoutMinSize(panel, b, 0, 0); b = ALF_AddButton(panel, (WORD)-1, 2, 4, TEXT("Hello, World!")); EnableWindow(b, FALSE); @@ -882,7 +882,7 @@ WinMain if (!win) MessageBox(0, TEXT("couldn't create main window!"), 0, MB_ICONHAND|MB_OK); - HWND hwndNtbk = ALF_AddNotebook(win, ID_NOTEBOOK, 0, 0); + HWND hwndNtbk = ALF_AddNotebook(win, ID_NOTEBOOK, 1, 1); addPaneToNotebook(hwndNtbk, PANE_BUTTONS); addPaneToNotebook(hwndNtbk, PANE_LABEL); @@ -891,6 +891,21 @@ WinMain addPaneToNotebook(hwndNtbk, PANE_COMBO); addPaneToNotebook(hwndNtbk, PANE_GROUPBOX); + HWND btnpanel = ALF_AddPanel(win, (WORD)-1, 1, 3); + ALF_AddButton(btnpanel, ID_HELLO, 1, 3, TEXT("&Hello World!")); + ALF_AddButton(btnpanel, (WORD)-1, 3, 3, TEXT("Goodbye, World")); + + ALF_LayoutSetRowMinSize(win, 2, 525); + ALF_LayoutSetRowMinSize(win, 0, 525); + ALF_LayoutSetRowMinSize(win, 4, 525); + ALF_LayoutSetColumnMinSize(win, 0, 525); + ALF_LayoutSetColumnMinSize(win, 2, 525); + ALF_LayoutSetRowExpandNumerator(win, 1, 1); + ALF_LayoutSetColumnExpandNumerator(win, 1, 1); + + ALF_LayoutSetColumnExpandNumerator(btnpanel, 9, 1); + ALF_LayoutSetColumnMinSize(btnpanel, 2, 525); + ALF_SetDefaultButton(win, ID_HELLO); ALF_ResizeWindow(win, 1, 1); -- cgit v1.2.3