summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--DEFECTS.txt4
-rw-r--r--Makefile.mingw7
-rw-r--r--Makefile.mingw-amd647
-rw-r--r--Makefile.vc65
-rw-r--r--Makefile.vc6-ansi5
-rw-r--r--alf/alf.cpp2
-rw-r--r--alf/alf.h28
-rw-r--r--alf/alfcompat.cpp11
-rw-r--r--alf/alfcompat.h1
-rw-r--r--alf/alfpanel.cpp16
-rw-r--r--alf/alfspinbox.cpp306
-rw-r--r--widgetfactory.cpp66
12 files changed, 449 insertions, 9 deletions
diff --git a/DEFECTS.txt b/DEFECTS.txt
new file mode 100644
index 0000000..46d7663
--- /dev/null
+++ b/DEFECTS.txt
@@ -0,0 +1,4 @@
+spin box:
+- on vista+: drawing bug when resized in reaction to clicking the up button
+- doesn’t look good on Win32s/NT3.51
+
diff --git a/Makefile.mingw b/Makefile.mingw
index def3fa3..e61640a 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/alfcontrol.o out/alf.o out/alfdpiaware.o out/alfedit.o out/alfgroupbox.o out/alficon.o out/alflabel.o out/alflayout.o out/alfmessagedlg.o out/alfnativebtn.o out/alfnotebook.o out/alfpanel.o out/alftoplevel.o
+out/widgetfactory.exe: out/widgetfactory.o out/alfbutton.o out/alfcombobox.o out/alfcompat.o out/alfcontrol.o out/alf.o out/alfdpiaware.o out/alfedit.o out/alfgroupbox.o out/alficon.o out/alflabel.o out/alflayout.o out/alfmessagedlg.o out/alfnativebtn.o out/alfnotebook.o out/alfpanel.o out/alfspinbox.o out/alftoplevel.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
@@ -56,13 +56,16 @@ 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/alfspinbox.o: alf/alfspinbox.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CXXFLAGS) -c -o $@ $<
+
out/alftoplevel.o: alf/alftoplevel.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/alfcontrol.cpp alf/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alfgroupbox.cpp alf/alficon.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfmessagedlg.cpp alf/alfnativebtn.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alftoplevel.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/alfcontrol.cpp alf/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alfgroupbox.cpp alf/alficon.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfmessagedlg.cpp alf/alfnativebtn.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfspinbox.cpp alf/alftoplevel.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 57b79c4..5a87ede 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/alfcontrol.amd64.o out/alf.amd64.o out/alfdpiaware.amd64.o out/alfedit.amd64.o out/alfgroupbox.amd64.o out/alficon.amd64.o out/alflabel.amd64.o out/alflayout.amd64.o out/alfmessagedlg.amd64.o out/alfnativebtn.amd64.o out/alfnotebook.amd64.o out/alfpanel.amd64.o out/alftoplevel.amd64.o
+out/widgetfactory64.exe: out/widgetfactory.amd64.o out/alfbutton.amd64.o out/alfcombobox.amd64.o out/alfcompat.amd64.o out/alfcontrol.amd64.o out/alf.amd64.o out/alfdpiaware.amd64.o out/alfedit.amd64.o out/alfgroupbox.amd64.o out/alficon.amd64.o out/alflabel.amd64.o out/alflayout.amd64.o out/alfmessagedlg.amd64.o out/alfnativebtn.amd64.o out/alfnotebook.amd64.o out/alfpanel.amd64.o out/alfspinbox.amd64.o out/alftoplevel.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
@@ -56,13 +56,16 @@ 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/alfspinbox.amd64.o: alf/alfspinbox.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CXXFLAGS) -c -o $@ $<
+
out/alftoplevel.amd64.o: alf/alftoplevel.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/alfcontrol.cpp alf/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alfgroupbox.cpp alf/alficon.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfmessagedlg.cpp alf/alfnativebtn.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alftoplevel.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/alfcontrol.cpp alf/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alfgroupbox.cpp alf/alficon.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfmessagedlg.cpp alf/alfnativebtn.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfspinbox.cpp alf/alftoplevel.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 635e5eb..03a30cf 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/alfcontrol.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alfgroupbox.obj out/alficon.obj out/alflabel.obj out/alflayout.obj out/alfmessagedlg.obj out/alfnativebtn.obj out/alfnotebook.obj out/alfpanel.obj out/alftoplevel.obj
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alfcontrol.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alfgroupbox.obj out/alficon.obj out/alflabel.obj out/alflayout.obj out/alfmessagedlg.obj out/alfnativebtn.obj out/alfnotebook.obj out/alfpanel.obj out/alfspinbox.obj out/alftoplevel.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
@@ -52,6 +52,9 @@ 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/alfspinbox.obj: alf/alfspinbox.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfspinbox.cpp
+
out/alftoplevel.obj: alf/alftoplevel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alftoplevel.cpp
diff --git a/Makefile.vc6-ansi b/Makefile.vc6-ansi
index 174532f..759b494 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/alfcontrol.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alfgroupbox.obj out/alficon.obj out/alflabel.obj out/alflayout.obj out/alfmessagedlg.obj out/alfnativebtn.obj out/alfnotebook.obj out/alfpanel.obj out/alftoplevel.obj
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alfcontrol.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alfgroupbox.obj out/alficon.obj out/alflabel.obj out/alflayout.obj out/alfmessagedlg.obj out/alfnativebtn.obj out/alfnotebook.obj out/alfpanel.obj out/alfspinbox.obj out/alftoplevel.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
@@ -52,6 +52,9 @@ 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/alfspinbox.obj: alf/alfspinbox.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfspinbox.cpp
+
out/alftoplevel.obj: alf/alftoplevel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alftoplevel.cpp
diff --git a/alf/alf.cpp b/alf/alf.cpp
index c2f99ce..a6c9e01 100644
--- a/alf/alf.cpp
+++ b/alf/alf.cpp
@@ -168,7 +168,7 @@ ALF_ShouldMessageBubble(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
return FALSE;
return msg == ALF_WM_GETDPI
- || msg == WM_COMMAND || msg == WM_NOTIFY
+ || msg == WM_COMMAND || msg == WM_NOTIFY || msg == WM_NOTIFYFORMAT
|| msg == WM_MEASUREITEM || msg == WM_DRAWITEM
|| msg == WM_CTLCOLORBTN || msg == WM_CTLCOLOREDIT
|| msg == WM_CTLCOLORLISTBOX || msg == WM_CTLCOLORSCROLLBAR
diff --git a/alf/alf.h b/alf/alf.h
index 8969ee1..f6ef21d 100644
--- a/alf/alf.h
+++ b/alf/alf.h
@@ -125,6 +125,13 @@ typedef struct {
#define ALF_WM_ICONVIEW_GETICON (ALF_WM__BASE + 201)
#define ALF_WM_ICONVIEW_SETICON (ALF_WM__BASE + 202)
+#define ALF_WM_SPINBOX_GETRANGE (ALF_WM__BASE + 201)
+#define ALF_WM_SPINBOX_SETRANGE (ALF_WM__BASE + 202)
+#define ALF_WM_SPINBOX_GETPOS (ALF_WM__BASE + 203)
+#define ALF_WM_SPINBOX_SETPOS (ALF_WM__BASE + 204)
+#define ALF_WM_SPINBOX_GETEDIT (ALF_WM__BASE + 205)
+#define ALF_WM_SPINBOX_GETUDCTL (ALF_WM__BASE + 206)
+
#define ALF_WM_USER (ALF_WM__BASE + 300)
typedef DWORD ALFColor;
@@ -656,6 +663,27 @@ ALF_MessageDlg_Confirm(HWND owner, const TCHAR *text, const TCHAR *caption, cons
WORD
ALF_MessageDlg_ConfirmDanger(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText, const TCHAR *cancelBtnText);
+// spin box
+HWND
+ALF_AddNumericSpinBox(HWND parent, WORD id, int x, int y, short val, short min, short max);
+
+BOOL
+ALF_SpinBox_Range(HWND spinbox, short *pmin, short *pmax);
+
+BOOL
+ALF_SpinBox_SetRange(HWND spinbox, short min, short max);
+
+short
+ALF_SpinBox_Pos(HWND spinbox);
+
+BOOL
+ALF_SpinBox_SetPos(HWND spinbox, short pos);
+
+HWND
+ALF_SpinBox_EditControl(HWND spinbox);
+
+HWND
+ALF_SpinBox_UpDownControl(HWND spinbox);
#ifdef __cplusplus
} // extern C
diff --git a/alf/alfcompat.cpp b/alf/alfcompat.cpp
index f5bed22..d764895 100644
--- a/alf/alfcompat.cpp
+++ b/alf/alfcompat.cpp
@@ -434,6 +434,14 @@ ALF_Compat_fallbackBufferedPaintRenderAnimation(HWND hwnd, HDC hdc)
}
static HRESULT WINAPI
+ALF_Compat_fallbackBufferedPaintStopAllAnimations(HWND hwnd)
+{
+ (void)hwnd;
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
ALF_Compat_fallbackGetThemeTransitionDuration(HTHEME hTheme,
int iPartId,
int iStateIdFrom,
@@ -679,6 +687,7 @@ void ALF_LoadCompatFunctions(void)
LOAD_FUNC(uxtheme, EndBufferedAnimation);
LOAD_FUNC(uxtheme, EndBufferedPaint);
LOAD_FUNC(uxtheme, BufferedPaintRenderAnimation);
+ LOAD_FUNC(uxtheme, BufferedPaintStopAllAnimations);
LOAD_FUNC(uxtheme, GetThemeTransitionDuration);
LOAD_FUNC(uxtheme, GetThemePartSize);
LOAD_FUNC(uxtheme, GetThemeColor);
@@ -774,6 +783,7 @@ void ALF_UnloadCompatFunctions(void)
UNLOAD_FUNC(EndBufferedAnimation);
UNLOAD_FUNC(EndBufferedPaint);
UNLOAD_FUNC(BufferedPaintRenderAnimation);
+ UNLOAD_FUNC(BufferedPaintStopAllAnimations);
UNLOAD_FUNC(GetThemeTransitionDuration);
UNLOAD_FUNC(GetThemePartSize);
UNLOAD_FUNC(GetThemeColor);
@@ -814,6 +824,7 @@ ALF_Compat_HPAINTBUFFER (WINAPI *ALF_Compat_BeginBufferedPaint)(HDC,const RECT *
HRESULT (WINAPI *ALF_Compat_EndBufferedAnimation)(ALF_Compat_HANIMATIONBUFFER,BOOL) = NULL;
HRESULT (WINAPI *ALF_Compat_EndBufferedPaint)(ALF_Compat_HPAINTBUFFER,BOOL) = NULL;
BOOL (WINAPI *ALF_Compat_BufferedPaintRenderAnimation)(HWND,HDC) = NULL;
+HRESULT (WINAPI *ALF_Compat_BufferedPaintStopAllAnimations)(HWND) = NULL;
HRESULT (WINAPI *ALF_Compat_GetThemeTransitionDuration)(HTHEME,int,int,int,int,DWORD*) = NULL;
HRESULT (WINAPI *ALF_Compat_GetThemeColor)(HTHEME,int,int,int,COLORREF*) = NULL;
HRESULT (WINAPI *ALF_Compat_GetThemeMargins)(HTHEME,HDC,int,int,int,const RECT *,MARGINS *) = NULL;
diff --git a/alf/alfcompat.h b/alf/alfcompat.h
index 8f6b80f..2946453 100644
--- a/alf/alfcompat.h
+++ b/alf/alfcompat.h
@@ -140,6 +140,7 @@ extern ALF_Compat_HPAINTBUFFER (WINAPI *ALF_Compat_BeginBufferedPaint)(HDC,const
extern HRESULT (WINAPI *ALF_Compat_EndBufferedAnimation)(ALF_Compat_HANIMATIONBUFFER,BOOL);
extern HRESULT (WINAPI *ALF_Compat_EndBufferedPaint)(ALF_Compat_HPAINTBUFFER,BOOL);
extern BOOL (WINAPI *ALF_Compat_BufferedPaintRenderAnimation)(HWND,HDC);
+extern HRESULT (WINAPI *ALF_Compat_BufferedPaintStopAllAnimations)(HWND);
extern HRESULT (WINAPI *ALF_Compat_GetThemeTransitionDuration)(HTHEME,int,int,int,int,DWORD*);
extern HRESULT (WINAPI *ALF_Compat_GetThemeColor)(HTHEME,int,int,int,COLORREF*);
extern HRESULT (WINAPI *ALF_Compat_GetThemeMargins)(HTHEME,HDC,int,int,int,const RECT *,MARGINS *);
diff --git a/alf/alfpanel.cpp b/alf/alfpanel.cpp
index 62bac1e..be02890 100644
--- a/alf/alfpanel.cpp
+++ b/alf/alfpanel.cpp
@@ -152,6 +152,22 @@ ALF_Panel_DefWindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
return TRUE;
}
+ if (msg == WM_COMMAND && priv->vtbl && priv->vtbl->command) {
+ HWND source = (HWND)lparam;
+ WORD code = HIWORD(wparam);
+ WORD id = LOWORD(wparam);
+ LRESULT r = priv->vtbl->command(priv->closure, window, code, id, source);
+ if (r)
+ return r;
+ }
+
+ if (msg == WM_NOTIFY && priv->vtbl && priv->vtbl->notify) {
+ NMHDR *nmhdr = (NMHDR *)lparam;
+ LRESULT r = priv->vtbl->notify(priv->closure, window, wparam, nmhdr);
+ if (r)
+ return r;
+ }
+
if (ALF_ShouldMessageBubble(window, msg, wparam, lparam))
return SendMessage(GetParent(window), msg, wparam, lparam);
diff --git a/alf/alfspinbox.cpp b/alf/alfspinbox.cpp
new file mode 100644
index 0000000..bd3dd70
--- /dev/null
+++ b/alf/alfspinbox.cpp
@@ -0,0 +1,306 @@
+#include "alfpriv.h"
+
+typedef struct {
+ HWND hwndEdit;
+ HWND hwndUpdown;
+ int dpi;
+} ALFSpinBoxPriv;
+
+static void
+ALF_SpinBox_Initialize(ALFSpinBoxPriv *priv, HWND hwnd)
+{
+ priv->dpi = 96;
+
+ RECT rcClient;
+ GetClientRect(hwnd, &rcClient);
+
+ priv->hwndEdit = CreateWindowEx(ALF_Compat_Is40() ? WS_EX_CLIENTEDGE : 0,
+ TEXT("EDIT"),
+ TEXT("0"),
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP | (ALF_Compat_Is40() ? 0 : WS_BORDER),
+ 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,
+ hwnd,
+ NULL,
+ ALF_HINSTANCE,
+ NULL);
+ priv->hwndUpdown = CreateWindowEx(0,
+ TEXT("msctls_updown32"),
+ NULL,
+ WS_CHILD | WS_VISIBLE | (ALF_Compat_Is40() ? UDS_ALIGNRIGHT : WS_BORDER) | UDS_AUTOBUDDY | UDS_SETBUDDYINT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,
+ 0, 0,
+ 0, 0,
+ hwnd,
+ NULL,
+ ALF_HINSTANCE,
+ NULL);
+}
+
+static void
+ALF_SpinBox_Destroy(ALFSpinBoxPriv *priv, HWND hwnd)
+{
+ (void)priv;
+ (void)hwnd;
+
+ // nothing to do here (yet)
+ // child windows are destroyed automatically
+}
+
+static void
+ALF_SpinBox_Resize(ALFSpinBoxPriv *priv, HWND hwnd)
+{
+ (void)hwnd;
+
+ RECT rcClient;
+ GetClientRect(hwnd, &rcClient);
+
+ int overlap = GetWindowLong(priv->hwndEdit, GWL_EXSTYLE) & WS_EX_CLIENTEDGE
+ ? ALF_Compat_GetSystemMetricsForDpi(SM_CXBORDER, (UINT)priv->dpi) * 2
+ : ALF_Compat_GetSystemMetricsForDpi(SM_CXBORDER, (UINT)priv->dpi);
+ int updownwidth = ALF_Compat_GetSystemMetricsForDpi(SM_CXVSCROLL, (UINT)priv->dpi) - ALF_Compat_GetSystemMetricsForDpi(SM_CXBORDER, (UINT)priv->dpi);
+
+ if (updownwidth > rcClient.bottom - rcClient.top)
+ updownwidth = rcClient.bottom - rcClient.top;
+
+
+ RECT rcEdit = {
+ 0, 0, rcClient.right - rcClient.left - updownwidth, rcClient.bottom - rcClient.top
+ };
+ RECT rcUpdown = {
+ rcEdit.right - overlap, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top
+ };
+
+ HDWP hdwp = BeginDeferWindowPos(2);
+ hdwp = DeferWindowPos(hdwp, priv->hwndEdit, NULL, rcEdit.left, rcEdit.top, rcEdit.right - rcEdit.left, rcEdit.bottom - rcEdit.top, SWP_NOACTIVATE|SWP_NOZORDER);
+ hdwp = DeferWindowPos(hdwp, priv->hwndUpdown, NULL, rcUpdown.left, rcUpdown.top, rcUpdown.right - rcUpdown.left, rcUpdown.bottom - rcUpdown.top, SWP_NOACTIVATE|SWP_NOZORDER);
+ EndDeferWindowPos(hdwp);
+}
+
+static void
+ALF_SpinBox_SetFont(ALFSpinBoxPriv *priv, HFONT font, LPARAM lparam)
+{
+ SendMessage(priv->hwndEdit, WM_SETFONT, (WPARAM)font, lparam);
+}
+
+static LRESULT
+ALF_SpinBox_GetFont(ALFSpinBoxPriv *priv, WPARAM wp, LPARAM lp)
+{
+ return SendMessage(priv->hwndEdit, WM_GETFONT, wp, lp);
+}
+
+static void
+ALF_SpinBox_HandleDpiChange(ALFSpinBoxPriv *priv, HWND hwnd, int newdpi)
+{
+ if (priv->dpi == newdpi)
+ return;
+
+ priv->dpi = newdpi;
+ ALF_SpinBox_Resize(priv, hwnd);
+}
+
+static LRESULT
+ALF_SpinBox_HandleGetRange(ALFSpinBoxPriv *priv, HWND hwnd)
+{
+ (void)hwnd;
+ return SendMessage(priv->hwndUpdown, UDM_GETRANGE, 0, 0);
+}
+
+static LRESULT
+ALF_SpinBox_HandleSetRange(ALFSpinBoxPriv *priv, HWND hwnd, LPARAM lparam)
+{
+ (void)hwnd;
+
+ SendMessage(priv->hwndUpdown, UDM_SETRANGE, 0, lparam);
+ return 1;
+}
+
+static LRESULT
+ALF_SpinBox_HandleGetPos(ALFSpinBoxPriv *priv, HWND hwnd)
+{
+ (void)hwnd;
+
+ return SendMessage(priv->hwndUpdown, UDM_GETPOS, 0, 0);
+}
+
+static LRESULT
+ALF_SpinBox_HandleSetPos(ALFSpinBoxPriv *priv, HWND hwnd, LPARAM lparam)
+{
+ (void)hwnd;
+
+ SendMessage(priv->hwndUpdown, UDM_SETPOS, 0, lparam);
+ return 1;
+}
+
+static LRESULT
+ALF_SpinBox_HandleCommand(ALFSpinBoxPriv *priv, HWND hwnd, WORD code, WORD id, HWND control)
+{
+ if (control == priv->hwndEdit) {
+ return SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLong(hwnd, GWL_ID), code), (LPARAM)hwnd);
+ } else {
+ return SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(id, code), (LPARAM)control);
+ }
+}
+
+static LRESULT
+ALF_SpinBox_HandleNotify(ALFSpinBoxPriv *priv, HWND hwnd, WPARAM wparam, const NMHDR *pnmh)
+{
+ if (pnmh->hwndFrom == priv->hwndUpdown && pnmh->code == UDN_DELTAPOS) {
+ NMUPDOWN nmud = *(const NMUPDOWN *)pnmh;
+ nmud.hdr.hwndFrom = hwnd;
+ nmud.hdr.idFrom = (UINT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
+
+ return SendMessage(GetParent(hwnd), WM_NOTIFY, nmud.hdr.idFrom, (LPARAM)&nmud);
+ } else {
+ return SendMessage(GetParent(hwnd), WM_NOTIFY, wparam, (LPARAM)pnmh);
+ }
+}
+
+static LRESULT
+ALF_SpinBox_HandleGetEditControl(ALFSpinBoxPriv *priv)
+{
+ return (LRESULT)priv->hwndEdit;
+}
+
+static LRESULT
+ALF_SpinBox_HandleGetUpDownControl(ALFSpinBoxPriv *priv)
+{
+ return (LRESULT)priv->hwndUpdown;
+}
+
+static LRESULT
+ALF_SpinBox_HandlePaint(ALFSpinBoxPriv *priv, HWND hwnd)
+{
+ (void)priv;
+
+ PAINTSTRUCT ps;
+ HDC dc = BeginPaint(hwnd, &ps);
+ FillRect(dc, &ps.rcPaint, GetSysColorBrush(COLOR_BTNFACE));
+ EndPaint(hwnd, &ps);
+ return 0;
+}
+
+static LRESULT WINAPI
+ALF_SpinBox_WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ ALFSpinBoxPriv *priv = (ALFSpinBoxPriv *)GetWindowLongPtr(hwnd, 0);
+
+ if (!priv && msg == WM_NCCREATE) {
+ priv = ALF_New(ALFSpinBoxPriv, 1);
+ SetWindowLongPtr(hwnd, 0, (LONG_PTR)priv);
+ }
+
+ if (!priv)
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+
+ switch (msg) {
+ case WM_CREATE:
+ ALF_SpinBox_Initialize(priv, hwnd);
+ break;
+ case WM_DESTROY:
+ ALF_SpinBox_Destroy(priv, hwnd);
+ SetWindowLongPtr(hwnd, 0, 0);
+ ALF_Free(priv);
+ priv = NULL;
+ break;
+ case WM_SETFONT:
+ ALF_SpinBox_SetFont(priv, (HFONT)wparam, lparam);
+ break;
+ case WM_GETFONT:
+ return ALF_SpinBox_GetFont(priv, wparam, lparam);
+ case WM_SIZE:
+ ALF_SpinBox_Resize(priv, hwnd);
+ break;
+ case ALF_WM_DPICHANGE:
+ ALF_SpinBox_HandleDpiChange(priv, hwnd, (int)lparam);
+ return 0;
+ case ALF_WM_SPINBOX_GETRANGE:
+ return ALF_SpinBox_HandleGetRange(priv, hwnd);
+ case ALF_WM_SPINBOX_SETRANGE:
+ return ALF_SpinBox_HandleSetRange(priv, hwnd, lparam);
+ case ALF_WM_SPINBOX_GETPOS:
+ return ALF_SpinBox_HandleGetPos(priv, hwnd);
+ case ALF_WM_SPINBOX_SETPOS:
+ return ALF_SpinBox_HandleSetPos(priv, hwnd, lparam);
+ case ALF_WM_SPINBOX_GETEDIT:
+ return ALF_SpinBox_HandleGetEditControl(priv);
+ case ALF_WM_SPINBOX_GETUDCTL:
+ return ALF_SpinBox_HandleGetUpDownControl(priv);
+ case WM_GETTEXT:
+ return (LRESULT)GetWindowText(priv->hwndEdit, (TCHAR *)lparam, (int)wparam);
+ case WM_GETTEXTLENGTH:
+ return (LRESULT)GetWindowTextLength(priv->hwndEdit);
+ case WM_SETTEXT:
+ return (LRESULT)SetWindowText(priv->hwndEdit, (const TCHAR *)lparam);
+ case WM_COMMAND:
+ return ALF_SpinBox_HandleCommand(priv, hwnd, HIWORD(wparam), LOWORD(wparam), (HWND)lparam);
+ case WM_NOTIFY:
+ return ALF_SpinBox_HandleNotify(priv, hwnd, wparam, (const NMHDR *)lparam);
+ case WM_PAINT:
+ return ALF_SpinBox_HandlePaint(priv, hwnd);
+ case WM_ERASEBKGND:
+ return 1;
+ }
+
+ if (ALF_ShouldMessageBubble(hwnd, msg, wparam, lparam))
+ return SendMessage(GetParent(hwnd), msg, wparam, lparam);
+
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+HWND
+ALF_AddNumericSpinBox(HWND parent, WORD id, int x, int y, short val, short min, short max)
+{
+ HWND hwnd = ALF_CreateControlWindow(WS_EX_CONTROLPARENT,
+ TEXT(""),
+ WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,
+ 0, 0, 0, 0,
+ parent,
+ (HMENU)(ULONG_PTR)id,
+ ALF_SpinBox_WndProc,
+ NULL);
+
+ ALF_AddControl(parent, x, y, hwnd, 0, 0, ALF_LAYOUT_SIZE_EDIT | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_SENDDPICHANGE);
+
+ ALF_SpinBox_SetRange(hwnd, min, max);
+ ALF_SpinBox_SetPos(hwnd, val);
+
+ return hwnd;
+}
+
+BOOL
+ALF_SpinBox_Range(HWND spinbox, short *pmin, short *pmax)
+{
+ LRESULT r = SendMessage(spinbox, ALF_WM_SPINBOX_GETRANGE, 0, 0);
+ *pmin = GET_X_LPARAM(r);
+ *pmax = GET_Y_LPARAM(r);
+ return TRUE;
+}
+
+BOOL
+ALF_SpinBox_SetRange(HWND spinbox, short min, short max)
+{
+ return (BOOL)SendMessage(spinbox, ALF_WM_SPINBOX_SETRANGE, 0, MAKELPARAM((WORD)max, (WORD)min));
+}
+
+short
+ALF_SpinBox_Pos(HWND spinbox)
+{
+ return (short)SendMessage(spinbox, ALF_WM_SPINBOX_GETPOS, 0, 0);
+}
+
+BOOL
+ALF_SpinBox_SetPos(HWND spinbox, short pos)
+{
+ return (BOOL)SendMessage(spinbox, ALF_WM_SPINBOX_SETPOS, 0, (LPARAM)pos);
+}
+
+HWND
+ALF_SpinBox_EditControl(HWND spinbox)
+{
+ return (HWND)SendMessage(spinbox, ALF_WM_SPINBOX_GETEDIT, 0, 0);
+}
+
+HWND
+ALF_SpinBox_UpDownControl(HWND spinbox)
+{
+ return (HWND)SendMessage(spinbox, ALF_WM_SPINBOX_GETUDCTL, 0, 0);
+}
diff --git a/widgetfactory.cpp b/widgetfactory.cpp
index 3298d81..b2c3396 100644
--- a/widgetfactory.cpp
+++ b/widgetfactory.cpp
@@ -10,6 +10,7 @@ enum {
PANE_CHECKBOX,
PANE_GROUPBOX,
PANE_ICONVIEW,
+ PANE_SPINBOX,
PANE__MAX
};
@@ -20,7 +21,8 @@ static const TCHAR *g_paneLabels[PANE__MAX] = {
TEXT("Notebook"), //PANE_NOTEBOOK,
TEXT("Checkbox"), //PANE_CHECKBOX,
TEXT("GroupBox"), //PANE_GROUPBOX,
- TEXT("Icon View") //PANE_ICONVIEW
+ TEXT("Icon View"), //PANE_ICONVIEW,
+ TEXT("Spin Box") //PANE_SPINBOX
};
enum {
@@ -30,6 +32,8 @@ enum {
ID_BTNCOMBOCLEAR,
ID_NOTEBOOK,
ID_HELLO,
+ ID_SPINBOX,
+ ID_SPINBOXOUT,
IDM_FILE,
IDM_FILE_CLOSE,
IDM_HELP,
@@ -808,6 +812,62 @@ iconviewPanelInit(HWND panel)
ALF_Panel_SetVTable(panel, &iconviewPanelVtbl, priv);
}
+/* spinbox panel */
+
+static LRESULT
+spinboxPanelCommand(void *closure, HWND panel, WORD notificationcode, WORD sourceid, HWND control)
+{
+ (void)closure;
+
+ if (notificationcode == EN_CHANGE && sourceid == ID_SPINBOX) {
+ HWND out = ALF_ControlHwndById(panel, ID_SPINBOXOUT);
+ TCHAR buf[12];
+ wsprintf(buf, TEXT("%d"), (int)ALF_SpinBox_Pos(control));
+ ALF_SetText(out, buf);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+spinboxPanelAttach(void *closure, HWND panel)
+{
+ (void)closure;
+
+ ALF_AddLabel(panel, (WORD)-1, 1, 1, TEXT("Spin Box -10 to +42"));
+ ALF_AddNumericSpinBox(panel, ID_SPINBOX, 3, 1, 12, -10, 42);
+ ALF_AddLabel(panel, ID_SPINBOXOUT, 3, 3, TEXT("initial"));
+
+ ALF_Layout_SetRowMinSize(panel, 0, 825);
+ ALF_Layout_SetRowMinSize(panel, 2, 825);
+ ALF_Layout_SetRowMinSize(panel, 4, 825);
+ ALF_Layout_SetColumnMinSize(panel, 0, 825);
+ ALF_Layout_SetColumnMinSize(panel, 2, 525);
+ ALF_Layout_SetColumnMinSize(panel, 4, 825);
+ ALF_Layout_SetRowExpandNumerator(panel, 1, 1);
+ ALF_Layout_SetRowExpandNumerator(panel, 3, 1);
+ ALF_Layout_SetColumnExpandNumerator(panel, 3, 1);
+ ALF_Layout_SetColumnExpandNumerator(panel, 4, 1);
+}
+
+static ALFPanelVTable spinboxPanelVtbl = {
+ spinboxPanelAttach,
+ commonPanelDestroy,
+ commonPanelMessage,
+ spinboxPanelCommand,
+ NULL,
+ commonPanelPaint,
+ NULL
+};
+
+static void
+spinboxPanelInit(HWND panel)
+{
+ CommonPanelPriv *priv = ALF_New(CommonPanelPriv, 1);
+ ALF_Panel_SetVTable(panel, &spinboxPanelVtbl, priv);
+}
+
void (*g_paneInitTable[PANE__MAX])(HWND) = {
buttonPanelInit, //PANE_BUTTONS
labelPanelInit, //PANE_LABEL,
@@ -815,7 +875,8 @@ void (*g_paneInitTable[PANE__MAX])(HWND) = {
notebookPanelInit, //PANE_NOTEBOOK,
checkboxPanelInit, //PANE_CHECKBOX,
groupboxPanelInit, //PANE_GROUPBOX,
- iconviewPanelInit //PANE_ICONVIEW
+ iconviewPanelInit, //PANE_ICONVIEW,
+ spinboxPanelInit //PANE_SPINBOX
};
static void
@@ -1094,6 +1155,7 @@ WinMain
addPaneToNotebook(hwndNtbk, PANE_COMBO);
addPaneToNotebook(hwndNtbk, PANE_GROUPBOX);
addPaneToNotebook(hwndNtbk, PANE_ICONVIEW);
+ addPaneToNotebook(hwndNtbk, PANE_SPINBOX);
ALF_AddNativeButton(win, ID_HELLO, 1, 3, TEXT("&Hello World!"));
ALF_AddNativeButton(win, (WORD)-1, 3, 3, TEXT("Goodbye, World"));