summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2018-12-26 22:38:08 +0100
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2018-12-26 22:38:08 +0100
commit641789a1c653f46bacfb9dad0a2fde50ac360a5f (patch)
treeb72414bf4fbb6ab50d69da8aabcd552eebeb24ac
parent061759e716ba8326efaa7f1328991ddd91085ad6 (diff)
focus and default button stuff
-rw-r--r--Makefile.mingw3
-rw-r--r--alf/alf.cpp105
-rw-r--r--alf/alf.h14
-rw-r--r--widgetfactory.c1
4 files changed, 111 insertions, 12 deletions
diff --git a/Makefile.mingw b/Makefile.mingw
index 9a6e50a..1fa7276 100644
--- a/Makefile.mingw
+++ b/Makefile.mingw
@@ -10,3 +10,6 @@ out/alf.o: alf/alf.cpp alf/alf.h
out/widgetfactory.o: widgetfactory.c alf/alf.h
$(CXX) $(CFLAGS) -c -o $@ $<
+
+clean:
+ rm -f out/*.o out/*.exe
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);
+}
diff --git a/alf/alf.h b/alf/alf.h
index d50bd67..b224538 100644
--- a/alf/alf.h
+++ b/alf/alf.h
@@ -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);
diff --git a/widgetfactory.c b/widgetfactory.c
index b5b9142..b0d503b 100644
--- a/widgetfactory.c
+++ b/widgetfactory.c
@@ -92,6 +92,7 @@ wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCm
ALF_AddButton(win, ID_B2, 0, 2, L"Oh m&y god,\r\nwho the hell cares?");
ALF_RecalculateLayout(win);
+ ALF_SetDefaultButton(win, ID_B1);
ALF_ResizeWindow(win, 1, 1);