diff options
| author | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2018-12-26 22:38:08 +0100 |
|---|---|---|
| committer | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2018-12-26 22:38:08 +0100 |
| commit | 641789a1c653f46bacfb9dad0a2fde50ac360a5f (patch) | |
| tree | b72414bf4fbb6ab50d69da8aabcd552eebeb24ac /alf | |
| parent | 061759e716ba8326efaa7f1328991ddd91085ad6 (diff) | |
focus and default button stuff
Diffstat (limited to 'alf')
| -rw-r--r-- | alf/alf.cpp | 105 | ||||
| -rw-r--r-- | alf/alf.h | 14 |
2 files changed, 107 insertions, 12 deletions
diff --git a/alf/alf.cpp b/alf/alf.cpp index 13839e4..efb8b8d 100644 --- a/alf/alf.cpp +++ b/alf/alf.cpp @@ -93,6 +93,8 @@ typedef struct { ALFListHeader widgets; int modalResult; ALFLayout layout; + WORD defid; + HWND hwndFocus; } ALFWindowPriv; static void @@ -101,6 +103,7 @@ ALF_InitializeWindowPriv(HWND hwnd, ALFWindowPriv *priv, ALFWindowInstanceParams priv->vtbl = (ALFWindowVTable*)GetClassLongPtr(hwnd, 0); priv->closure = params->closure; ALF_ListInit(&priv->widgets); + priv->defid = (WORD)-1; } static void @@ -310,7 +313,7 @@ ALF_ApplyLayout(HWND hwnd, ALFWindowPriv *win) int extraHeightError = 0; if (win->layout.occupiedRowCount) { extraHeightPart = extraHeight / win->layout.occupiedRowCount; - extraHeightError = extraHeight - extraWidthPart * win->layout.occupiedRowCount; + extraHeightError = extraHeight - extraHeightPart * win->layout.occupiedRowCount; } for (int i = 0; i < win->layout.nRows; ++i) { @@ -376,6 +379,22 @@ ALF_InternalAddWidget(HWND hwnd, ALFWindowPriv *priv, ALFAddWidgetParams *params ALF_UpdateFontForWidget(priv, w); } +static void +ALF_ApplyFocus(HWND hwnd, ALFWindowPriv *priv, BOOL restoringFocus) +{ + if (priv->hwndFocus) { + if (!restoringFocus && SendMessage(priv->hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_HASSETSEL) + SendMessage(priv->hwndFocus, EM_SETSEL, 0, -1); + + if (GetForegroundWindow() == hwnd) + SetFocus(priv->hwndFocus); + } else { + priv->hwndFocus = GetNextDlgTabItem(hwnd, NULL, FALSE); + if (priv->hwndFocus) + ALF_ApplyFocus(hwnd, priv, FALSE); + } +} + LRESULT ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { @@ -408,6 +427,24 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) if (msg == ALF_WM_ADDWIDGET) { ALF_InternalAddWidget(hwnd, priv, (ALFAddWidgetParams *)lparam); + return 0; + } + + if (msg == ALF_WM_SETFOCUS) { + priv->hwndFocus = (HWND)lparam; + ALF_ApplyFocus(hwnd, priv, FALSE); + return 0; + } + + if (msg == WM_ACTIVATE) { + if (!HIWORD(wparam)) { // if !minimized + if (LOWORD(wparam)) { + ALF_ApplyFocus(hwnd, priv, TRUE); + } else { + priv->hwndFocus = GetFocus(); + } + } + return 0; } if (msg == WM_SIZE) { @@ -463,6 +500,29 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) ALF_DestroyWindowPriv(priv); } + if (msg == DM_GETDEFID) { + if (priv->defid == (WORD)-1) { + return 0; + } else { + return MAKELONG(priv->defid, DC_HASDEFID); + } + } + 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); + } + } + + 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); + } + return TRUE; + } + return DefWindowProc(hwnd, msg, wparam, lparam); } @@ -625,6 +685,30 @@ ALF_ResizeWindow(HWND win, UINT cptWidth, UINT cptHeight) SetWindowPos(win, NULL, 0, 0, pxwidth, pxheight, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER); } +struct ALF_WidgetHwndById_Closure { + HWND result; + WORD needle; +}; + +static BOOL CALLBACK +ALF_WidgetHwndById_EnumChildProc(HWND hwnd, LPARAM lParam) +{ + struct ALF_WidgetHwndById_Closure *closure = (struct ALF_WidgetHwndById_Closure*)lParam; + if ((WORD)GetWindowLongPtr(hwnd, GWLP_ID) == closure->needle) { + closure->result = hwnd; + return FALSE; + } + return TRUE; +} + +HWND +ALF_WidgetHwndById(HWND win, WORD id) +{ + struct ALF_WidgetHwndById_Closure closure = { 0, id }; + EnumChildWindows(win, ALF_WidgetHwndById_EnumChildProc, (LPARAM)&closure); + return closure.result; +} + /* LABEL */ static LRESULT CALLBACK @@ -676,14 +760,14 @@ ALF__LabelSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_ } HWND -ALF_AddLabel(HWND win, int id, UINT x, UINT y, const WCHAR *text) +ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const WCHAR *text) { HWND hwndLabel = CreateWindow(L"STATIC", text, WS_CHILD | WS_VISIBLE | SS_LEFTNOWORDWRAP, 0, 0, 100, 100, win, - (HMENU)id, + (HMENU)(int)id, (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE), NULL); @@ -736,7 +820,7 @@ ALF__EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_P } HWND -ALF_AddEdit(HWND win, int id, UINT x, UINT y, const WCHAR *text) +ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const WCHAR *text) { HWND hwndEdit = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", @@ -744,7 +828,7 @@ ALF_AddEdit(HWND win, int id, UINT x, UINT y, const WCHAR *text) WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER, 0, 0, 100, 100, win, - (HMENU)id, + (HMENU)(int)id, (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE), NULL); @@ -821,7 +905,7 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT } HWND -ALF_AddButton(HWND win, int id, UINT x, UINT y, const WCHAR *text) +ALF_AddButton(HWND win, WORD id, UINT x, UINT y, const WCHAR *text) { HWND hwndButton = CreateWindowEx(0, L"BUTTON", @@ -829,7 +913,7 @@ ALF_AddButton(HWND win, int id, UINT x, UINT y, const WCHAR *text) WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_PUSHBUTTON | BS_MULTILINE, 0, 0, 100, 100, win, - (HMENU)id, + (HMENU)(int)id, (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE), NULL); @@ -848,3 +932,10 @@ ALF_AddButton(HWND win, int id, UINT x, UINT y, const WCHAR *text) return hwndButton; } + + +void +ALF_SetDefaultButton(HWND win, WORD id) +{ + SendMessage(win, DM_SETDEFID, (WPARAM)id, 0); +} @@ -41,6 +41,7 @@ typedef struct { #define ALF_WM_SETMODALRESULT (ALF_WM__BASE + 7) #define ALF_WM_GETMODALRESULT (ALF_WM__BASE + 8) #define ALF_WM_CENTIPOINTTOPX (ALF_WM__BASE + 9) +#define ALF_WM_SETFOCUS (ALF_WM__BASE + 10) typedef struct { @@ -82,16 +83,19 @@ LRESULT ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); HWND -ALF_AddLabel(HWND win, int id, UINT x, UINT y, const WCHAR *text); +ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const WCHAR *text); HWND -ALF_AddEdit(HWND win, int id, UINT x, UINT y, const WCHAR *text); +ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const WCHAR *text); HWND -ALF_AddButton(HWND win, int id, UINT x, UINT y, const WCHAR *text); +ALF_AddButton(HWND win, WORD id, UINT x, UINT y, const WCHAR *text); void -ALF_DestroyWidget(HWND win, int id); +ALF_SetDefaultButton(HWND win, WORD id); + +void +ALF_DestroyWidget(HWND win, WORD id); void ALF_AddWidget(HWND win, UINT x, UINT y, HWND widget, UINT cptWidth, UINT cptHeight, DWORD flags); @@ -100,7 +104,7 @@ void ALF_AddWidgetEx(HWND win, const ALFAddWidgetParams *params); HWND -ALF_WidgetHwndById(HWND win, int id); +ALF_WidgetHwndById(HWND win, WORD id); void ALF_RecalculateLayout(HWND win); |
