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 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 42 deletions(-) (limited to 'alf/alfwindow.cpp') 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; } -- cgit v1.2.3