summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.h38
-rw-r--r--alf/alfprogress.cpp476
-rw-r--r--widgetfactory.cpp115
7 files changed, 645 insertions, 8 deletions
diff --git a/Makefile.mingw b/Makefile.mingw
index e61640a..e2157ca 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/alfspinbox.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/alfprogress.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,6 +56,9 @@ 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/alfprogress.o: alf/alfprogress.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 $@ $<
@@ -65,7 +68,7 @@ out/alftoplevel.o: alf/alftoplevel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.
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/alfspinbox.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/alfprogress.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 5a87ede..5ecf4dc 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/alfspinbox.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/alfprogress.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,6 +56,9 @@ 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/alfprogress.amd64.o: alf/alfprogress.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 $@ $<
@@ -65,7 +68,7 @@ out/alftoplevel.amd64.o: alf/alftoplevel.cpp alf/alfcompat.h alf/alf.h alf/alfl
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/alfspinbox.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/alfprogress.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 03a30cf..a41f66e 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/alfspinbox.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/alfprogress.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/alfprogress.obj: alf/alfprogress.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfprogress.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
diff --git a/Makefile.vc6-ansi b/Makefile.vc6-ansi
index 759b494..1a1ec7a 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/alfspinbox.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/alfprogress.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/alfprogress.obj: alf/alfprogress.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfprogress.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
diff --git a/alf/alf.h b/alf/alf.h
index f6ef21d..e64cac7 100644
--- a/alf/alf.h
+++ b/alf/alf.h
@@ -685,6 +685,44 @@ ALF_SpinBox_EditControl(HWND spinbox);
HWND
ALF_SpinBox_UpDownControl(HWND spinbox);
+// progress
+enum ALFProgressState {
+ ALF_PROGRESS_STATE_NORMAL = 1, //==PBST_NORMAL
+ ALF_PROGRESS_STATE_ERROR = 2, //==PBST_ERROR FIXME! only supported in native commctl v6 progress bar on Vista+
+ ALF_PROGRESS_STATE_PAUSED = 3, //==PBST_PAUSED FIXME! only supported in native commctl v6 progress bar on Vista+
+ ALF_PROGRESS_STATE_INDETERMINATE = 4,
+ ALF_PROGRESS_STATE_HIDDEN = 5 // TODO: define semantics and implement
+};
+
+HWND
+ALF_AddNativeProgressBar(HWND parent, WORD id, int x, int y);
+
+HWND
+ALF_AddProgressGauge(HWND parent, WORD id, int x, int y);
+
+// creates a native progress bar on commctlv6 (XP+), a selfmade progress gauge otherwise
+HWND
+ALF_AddProgressBar(HWND parent, WORD id, int x, int y);
+
+void
+ALF_Progress_Range(HWND progress, int *pMin, int *pMax);
+
+void
+ALF_Progress_SetRange(HWND progress, int min, int max);
+
+int
+ALF_Progress_Value(HWND progress);
+
+void
+ALF_Progress_SetValue(HWND progress, int value);
+
+enum ALFProgressState
+ALF_Progress_State(HWND progress);
+
+void
+ALF_Progress_SetState(HWND progress, enum ALFProgressState state);
+
+
#ifdef __cplusplus
} // extern C
#endif
diff --git a/alf/alfprogress.cpp b/alf/alfprogress.cpp
new file mode 100644
index 0000000..3a5c4fc
--- /dev/null
+++ b/alf/alfprogress.cpp
@@ -0,0 +1,476 @@
+#include "alfpriv.h"
+
+#define ALF_PROGRESS_MARQUEE_WIDTH 5
+#define ALF_PROGRESS_MARQUEE_TIMER_ID 42
+
+// need special messages for gauge on Win32s because Win32s only keeps the
+// low word of WPARAM where we occasionally need to pass 32bit LONGs
+#define ALF_WM_PROGRESS_SETRANGE (ALF_WM__BASE + 201)
+#define ALF_WM_PROGRESS_SETPOS (ALF_WM__BASE + 202)
+
+typedef struct {
+ int min;
+ int max;
+ int pos;
+ int marquee;
+ HFONT font;
+} ALFProgressGaugePriv;
+
+static void
+ALF_ProgressGauge_Init(ALFProgressGaugePriv *priv)
+{
+ priv->min = 0;
+ priv->max = 100;
+ priv->pos = 0;
+ priv->marquee = 0;
+}
+
+static LRESULT
+ALF_ProgressGauge_GetRange(ALFProgressGaugePriv *priv, HWND hwnd, WPARAM retminormax, PBRANGE *pRange)
+{
+ (void)hwnd;
+
+ if (pRange) {
+ pRange->iLow = priv->min;
+ pRange->iHigh = priv->max;
+ }
+
+ if (retminormax)
+ return priv->min;
+ else
+ return priv->max;
+}
+
+static LRESULT
+ALF_ProgressGauge_SetRange(ALFProgressGaugePriv *priv, HWND hwnd, int min, int max)
+{
+ priv->min = min;
+ priv->max = max;
+
+ if (max < min)
+ priv->max = min;
+
+ if (priv->pos < min)
+ priv->pos = min;
+
+ if (priv->pos > max)
+ priv->pos = max;
+
+ InvalidateRect(hwnd, NULL, TRUE);
+ return 1;
+}
+
+static LRESULT
+ALF_ProgressGauge_GetPos(ALFProgressGaugePriv *priv, HWND hwnd)
+{
+ (void)hwnd;
+
+ return (LRESULT)priv->pos;
+}
+
+static LRESULT
+ALF_ProgressGauge_SetPos(ALFProgressGaugePriv *priv, HWND hwnd, int pos)
+{
+ priv->pos = pos;
+
+ if (priv->pos < priv->min)
+ priv->pos = priv->min;
+
+ if (priv->pos > priv->max)
+ priv->pos = priv->max;
+
+ InvalidateRect(hwnd, NULL, TRUE);
+ return 1;
+}
+
+static LRESULT
+ALF_ProgressGauge_Size(ALFProgressGaugePriv *priv, HWND hwnd, WPARAM wparam, LPARAM lparam)
+{
+ (void)priv;
+
+ InvalidateRect(hwnd, NULL, TRUE);
+
+ return DefWindowProc(hwnd, WM_SIZE, wparam, lparam);
+}
+
+static void
+ALF_ProgressGauge_DoPaint(ALFProgressGaugePriv *priv, HWND hwnd, HDC dc, RECT *rcClip)
+{
+ (void)rcClip;
+
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+ OffsetRect(&rc, -rc.left, -rc.top);
+
+ DrawEdge(dc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
+
+ FrameRect(dc, &rc, GetSysColorBrush(COLOR_BTNFACE));
+ InflateRect(&rc, -1, -1);
+
+ TCHAR textbuf[64]; // FIXME! make this variable length?
+ ZeroMemory(textbuf, sizeof(textbuf));
+
+ int len = GetWindowText(hwnd, textbuf, sizeof(textbuf)/sizeof(textbuf[0]));
+
+ HFONT oldfont = SelectFont(dc, (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0));
+
+ TEXTMETRIC tm;
+ ZeroMemory(&tm, sizeof(tm));
+
+ GetTextMetrics(dc, &tm);
+
+ int refx = rc.left + (rc.right - rc.left) / 2;
+ int refy = rc.top + (rc.bottom - rc.top + tm.tmAscent - tm.tmDescent) / 2;
+
+ SetTextAlign(dc, TA_CENTER | TA_BASELINE);
+
+ COLORREF clrHilight = GetSysColor(COLOR_HIGHLIGHT);
+ COLORREF clrHilightText = GetSysColor(COLOR_HIGHLIGHTTEXT);
+ COLORREF clrBtnFace = GetSysColor(COLOR_BTNFACE);
+ COLORREF clrBtnText = GetSysColor(COLOR_BTNTEXT);
+
+ if (GetWindowLong(hwnd, GWL_STYLE) & PBS_MARQUEE) {
+ RECT rcMarquee = { rc.left + priv->marquee,
+ rc.top,
+ rc.left + priv->marquee + ALF_PROGRESS_MARQUEE_WIDTH,
+ rc.bottom };
+ if (rcMarquee.left < rc.left)
+ rcMarquee.left = rc.left;
+ if (rcMarquee.right > rc.right)
+ rcMarquee.right = rc.right;
+
+ RECT rcMarqueeWrap = { rc.left,
+ rc.top,
+ rc.left + priv->marquee + ALF_PROGRESS_MARQUEE_WIDTH - rc.right + rc.left,
+ rc.bottom };
+ if (rcMarqueeWrap.right < rcMarqueeWrap.left)
+ rcMarqueeWrap.right = rcMarqueeWrap.left;
+
+ RECT rcLeftSpace = { rcMarqueeWrap.right, rc.top, rcMarquee.left, rc.bottom };
+ RECT rcRightSpace = { rcMarquee.right, rc.top, rc.right, rc.bottom };
+
+ SetBkColor(dc, clrHilight);
+ SetTextColor(dc, clrHilightText);
+ ExtTextOut(dc, refx, refy, ETO_OPAQUE|ETO_CLIPPED, &rcMarquee, textbuf, (UINT)len, NULL);
+ ExtTextOut(dc, refx, refy, ETO_OPAQUE|ETO_CLIPPED, &rcMarqueeWrap, textbuf, (UINT)len, NULL);
+
+ SetBkColor(dc, clrBtnFace);
+ SetTextColor(dc, clrBtnText);
+ ExtTextOut(dc, refx, refy, ETO_OPAQUE|ETO_CLIPPED, &rcLeftSpace, textbuf, (UINT)len, NULL);
+ ExtTextOut(dc, refx, refy, ETO_OPAQUE|ETO_CLIPPED, &rcRightSpace, textbuf, (UINT)len, NULL);
+ } else {
+ int barwidth = MulDiv(priv->pos - priv->min, rc.right - rc.left, priv->max - priv->min);
+
+ // XXX: make the painting pixel-compatible to the original progress bar
+ // IMHO this seems to be some kind of off-by-one error in the microsoft code
+ if (barwidth >= rc.right - rc.left)
+ barwidth -= 1;
+
+ RECT rcLeft = { rc.left, rc.top, rc.left + barwidth, rc.bottom };
+ RECT rcRight = { rc.left + barwidth, rc.top, rc.right, rc.bottom };
+
+ SetBkColor(dc, clrHilight);
+ SetTextColor(dc, clrHilightText);
+ ExtTextOut(dc, refx, refy, ETO_OPAQUE|ETO_CLIPPED, &rcLeft, textbuf, (UINT)len, NULL);
+
+ SetBkColor(dc, clrBtnFace);
+ SetTextColor(dc, clrBtnText);
+ ExtTextOut(dc, refx, refy, ETO_OPAQUE|ETO_CLIPPED, &rcRight, textbuf, (UINT)len, NULL);
+ }
+
+ SelectFont(dc, oldfont);
+}
+
+static LRESULT
+ALF_ProgressGauge_Paint(ALFProgressGaugePriv *priv, HWND hwnd)
+{
+ PAINTSTRUCT ps;
+ HDC dc = BeginPaint(hwnd, &ps);
+
+ ALF_ProgressGauge_DoPaint(priv, hwnd, dc, &ps.rcPaint);
+
+ EndPaint(hwnd, &ps);
+ return 0;
+}
+
+static LRESULT
+ALF_ProgressGauge_PrintClient(ALFProgressGaugePriv *priv, HWND hwnd, HDC dc)
+{
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+ OffsetRect(&rc, -rc.left, -rc.top);
+
+ ALF_ProgressGauge_DoPaint(priv, hwnd, dc, &rc);
+ return 0;
+}
+
+static LRESULT
+ALF_ProgressGauge_Timer(ALFProgressGaugePriv *priv, HWND hwnd, WPARAM id, LPARAM lparam)
+{
+ if (id == ALF_PROGRESS_MARQUEE_TIMER_ID) {
+ if (GetWindowLong(hwnd, GWL_STYLE) & PBS_MARQUEE) {
+ RECT rcClient;
+ GetClientRect(hwnd, &rcClient);
+
+ priv->marquee += 1;
+ if (priv->marquee >= rcClient.right - rcClient.left - 4) {
+ priv->marquee = 0;
+ }
+
+ InvalidateRect(hwnd, NULL, TRUE);
+ } else {
+ KillTimer(hwnd, id);
+ }
+
+ return 0;
+ } else {
+ return DefWindowProc(hwnd, WM_TIMER, id, lparam);
+ }
+}
+
+static LRESULT
+ALF_ProgressGauge_SetMarquee(ALFProgressGaugePriv *priv, HWND hwnd, WPARAM onoff, UINT milliseconds)
+{
+ if (GetWindowLong(hwnd, GWL_STYLE) & PBS_MARQUEE) {
+ if (onoff) {
+ priv->pos = priv->min;
+ priv->marquee = -2;
+ InvalidateRect(hwnd, NULL, TRUE);
+
+ if (milliseconds == 0)
+ milliseconds = 30;
+
+ SetTimer(hwnd, ALF_PROGRESS_MARQUEE_TIMER_ID, milliseconds, NULL);
+ } else {
+ KillTimer(hwnd, ALF_PROGRESS_MARQUEE_TIMER_ID);
+ }
+ }
+
+ return 0;
+}
+
+static LRESULT
+ALF_ProgressGauge_StyleChanged(ALFProgressGaugePriv *priv, HWND hwnd, WPARAM wparam, LPARAM lparam)
+{
+ (void)priv;
+ InvalidateRect(hwnd, NULL, TRUE);
+ return DefWindowProc(hwnd, WM_STYLECHANGED, wparam, lparam);
+}
+
+static LRESULT
+ALF_ProgressGauge_SetFont(ALFProgressGaugePriv *priv, HWND hwnd, HFONT font)
+{
+ priv->font = font;
+ InvalidateRect(hwnd, NULL, TRUE);
+ return 0;
+}
+
+static LRESULT
+ALF_ProgressGauge_GetFont(ALFProgressGaugePriv *priv, HWND hwnd)
+{
+ (void)hwnd;
+ return (LRESULT)priv->font;
+}
+
+static LRESULT
+ALF_ProgressGauge_SetText(ALFProgressGaugePriv *priv, HWND hwnd, const TCHAR *text)
+{
+ (void)priv;
+
+ InvalidateRect(hwnd, NULL, TRUE);
+ return DefWindowProc(hwnd, WM_SETTEXT, 0, (LPARAM)text);
+}
+
+static LRESULT
+ALF_ProgressGauge_CalcSize(ALFProgressGaugePriv *priv, HWND hwnd, SIZE *pSize)
+{
+ if (GetWindowTextLength(hwnd) > 0) {
+ HDC dc = GetDC(hwnd);
+ HFONT oldfont = SelectFont(dc, priv->font);
+
+ TEXTMETRIC tm;
+ ZeroMemory(&tm, sizeof(tm));
+ GetTextMetrics(dc, &tm);
+
+ int cy = tm.tmHeight + 8;
+ if (pSize->cy < cy)
+ pSize->cy = cy;
+
+ SelectFont(dc, oldfont);
+ ReleaseDC(hwnd, dc);
+ }
+
+ return 0;
+}
+
+static LRESULT WINAPI
+ALF_ProgressGauge_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ ALFProgressGaugePriv *priv = (ALFProgressGaugePriv *)GetWindowLongPtr(hwnd, 0);
+
+ if (!priv) {
+ if (msg == WM_CREATE) {
+ priv = ALF_New(ALFProgressGaugePriv, 1);
+ ALF_ProgressGauge_Init(priv);
+ SetWindowLongPtr(hwnd, 0, (LONG_PTR)priv);
+ } else {
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ }
+ }
+
+ switch (msg) {
+ case WM_DESTROY:
+ SetWindowLongPtr(hwnd, 0, 0);
+ ALF_Free(priv);
+ break;
+ case PBM_GETPOS:
+ return ALF_ProgressGauge_GetPos(priv, hwnd);
+ case PBM_SETPOS:
+ return ALF_ProgressGauge_SetPos(priv, hwnd, (int)wparam);
+ case ALF_WM_PROGRESS_SETPOS:
+ return ALF_ProgressGauge_SetPos(priv, hwnd, (int)lparam);
+ case PBM_GETRANGE:
+ return ALF_ProgressGauge_GetRange(priv, hwnd, wparam, (PBRANGE *)lparam);
+ case PBM_SETRANGE32:
+ return ALF_ProgressGauge_SetRange(priv, hwnd, (int)wparam, (int)lparam);
+ case ALF_WM_PROGRESS_SETRANGE:
+ return ALF_ProgressGauge_SetRange(priv, hwnd, ((PBRANGE *)lparam)->iLow, ((PBRANGE *)lparam)->iHigh);
+ case WM_PAINT:
+ return ALF_ProgressGauge_Paint(priv, hwnd);
+ case WM_ERASEBKGND:
+ return TRUE;
+ case WM_PRINTCLIENT:
+ return ALF_ProgressGauge_PrintClient(priv, hwnd, (HDC)wparam);
+ case WM_TIMER:
+ return ALF_ProgressGauge_Timer(priv, hwnd, wparam, lparam);
+ case PBM_SETMARQUEE:
+ return ALF_ProgressGauge_SetMarquee(priv, hwnd, wparam, (UINT)lparam);
+ case WM_STYLECHANGED:
+ return ALF_ProgressGauge_StyleChanged(priv, hwnd, wparam, lparam);
+ case WM_SIZE:
+ return ALF_ProgressGauge_Size(priv, hwnd, wparam, lparam);
+ case WM_SETFONT:
+ return ALF_ProgressGauge_SetFont(priv, hwnd, (HFONT)wparam);
+ case WM_GETFONT:
+ return ALF_ProgressGauge_GetFont(priv, hwnd);
+ case WM_SETTEXT:
+ return ALF_ProgressGauge_SetText(priv, hwnd, (const TCHAR *)lparam);
+ case ALF_WM_QUERYSIZE:
+ return ALF_ProgressGauge_CalcSize(priv, hwnd, (SIZE *)lparam);
+ }
+
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+HWND
+ALF_AddNativeProgressBar(HWND parent, WORD id, int x, int y)
+{
+ HWND hwnd = CreateWindowEx(0,
+ PROGRESS_CLASS,
+ NULL,
+ WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
+ 0, 0, 10, 10,
+ parent,
+ (HMENU)(ULONG_PTR)id,
+ ALF_HINSTANCE,
+ NULL);
+
+ ALF_AddControl(parent, x, y, hwnd, 12000, 1125, ALF_LAYOUT_TRANSPARENTBG);
+
+ return hwnd;
+}
+
+HWND
+ALF_AddProgressGauge(HWND parent, WORD id, int x, int y)
+{
+ HWND hwnd = ALF_CreateControlWindow(0,
+ TEXT(""),
+ WS_CHILD | WS_VISIBLE,
+ 0, 0, 10, 10,
+ parent,
+ (HMENU)(ULONG_PTR)id,
+ ALF_ProgressGauge_WindowProc,
+ NULL);
+
+ ALF_AddControl(parent, x, y, hwnd, 12000, 1125, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT);
+
+ return hwnd;
+}
+
+HWND
+ALF_AddProgressBar(HWND parent, WORD id, int x, int y)
+{
+ if (ALF_Compat_IsComCtlV6())
+ return ALF_AddNativeProgressBar(parent, id, x, y);
+ else
+ return ALF_AddProgressGauge(parent, id, x, y);
+}
+
+void
+ALF_Progress_Range(HWND progress, int *pMin, int *pMax)
+{
+ PBRANGE r = { 0, 0 };
+ SendMessage(progress, PBM_GETRANGE, 0, (LPARAM)&r);
+
+ if (pMin) *pMin = r.iLow;
+ if (pMax) *pMax = r.iHigh;
+}
+
+void
+ALF_Progress_SetRange(HWND progress, int min, int max)
+{
+ PBRANGE r = { min, max };
+ if (!SendMessage(progress, ALF_WM_PROGRESS_SETRANGE, 0, (LPARAM)&r)) {
+ SendMessage(progress, PBM_SETRANGE32, (WPARAM)min, (LPARAM)max);
+ }
+}
+
+int
+ALF_Progress_Value(HWND progress)
+{
+ return (int)SendMessage(progress, PBM_GETPOS, 0, 0);
+}
+
+void
+ALF_Progress_SetValue(HWND progress, int value)
+{
+ if (!SendMessage(progress, ALF_WM_PROGRESS_SETPOS, 0, (LPARAM)value))
+ SendMessage(progress, PBM_SETPOS, (WPARAM)value, 0);
+}
+
+enum ALFProgressState
+ALF_Progress_State(HWND progress)
+{
+ LRESULT state = SendMessage(progress, /*PBM_GETSTATE*/(WM_USER + 17), 0, 0);
+ BOOL marquee = GetWindowLong(progress, GWL_STYLE) & PBS_MARQUEE;
+
+ if (marquee) {
+ return ALF_PROGRESS_STATE_INDETERMINATE;
+ } else if (state == 0) {
+ // state not supported by this progress bar
+ return ALF_PROGRESS_STATE_NORMAL;
+ } else {
+ // enum values have been chosen to be equal to PBST_*
+ return (enum ALFProgressState)state;
+ }
+}
+
+void
+ALF_Progress_SetState(HWND progress, enum ALFProgressState state)
+{
+ switch (state) {
+ case ALF_PROGRESS_STATE_INDETERMINATE:
+ SetWindowLong(progress, GWL_STYLE, GetWindowLong(progress, GWL_STYLE) | PBS_MARQUEE);
+ SendMessage(progress, WM_USER+16/*PBM_SETSTATE*/, 1/*PBST_NORMAL*/, 0);
+ SendMessage(progress, PBM_SETMARQUEE, TRUE, 0);
+ break;
+ default:
+ if (GetWindowLong(progress, GWL_STYLE) & PBS_MARQUEE) {
+ SendMessage(progress, PBM_SETMARQUEE, FALSE, 0);
+ SetWindowLong(progress, GWL_STYLE, GetWindowLong(progress, GWL_STYLE) & ~PBS_MARQUEE);
+ }
+ // enum values have been chosen to equal to PBST_*
+ SendMessage(progress, WM_USER+16/*PBM_SETSTATE*/, (WPARAM)state, 0);
+ break;
+ }
+}
diff --git a/widgetfactory.cpp b/widgetfactory.cpp
index b2c3396..12c08d9 100644
--- a/widgetfactory.cpp
+++ b/widgetfactory.cpp
@@ -11,6 +11,7 @@ enum {
PANE_GROUPBOX,
PANE_ICONVIEW,
PANE_SPINBOX,
+ PANE_PROGRESS,
PANE__MAX
};
@@ -22,7 +23,8 @@ static const TCHAR *g_paneLabels[PANE__MAX] = {
TEXT("Checkbox"), //PANE_CHECKBOX,
TEXT("GroupBox"), //PANE_GROUPBOX,
TEXT("Icon View"), //PANE_ICONVIEW,
- TEXT("Spin Box") //PANE_SPINBOX
+ TEXT("Spin Box"), //PANE_SPINBOX
+ TEXT("Progress") //PANE_PROGRESS
};
enum {
@@ -34,6 +36,14 @@ enum {
ID_HELLO,
ID_SPINBOX,
ID_SPINBOXOUT,
+ ID_PROGRESS_SPINBOX,
+ ID_PROGRESS_BAR,
+ ID_PROGRESS_GAUGE,
+ ID_PROGRESS_NATIVE_BAR,
+ ID_PROGRESS_NORMAL,
+ ID_PROGRESS_PAUSED,
+ ID_PROGRESS_ERROR,
+ ID_PROGRESS_INDETERMINATE,
IDM_FILE,
IDM_FILE_CLOSE,
IDM_HELP,
@@ -868,6 +878,105 @@ spinboxPanelInit(HWND panel)
ALF_Panel_SetVTable(panel, &spinboxPanelVtbl, priv);
}
+/* progress panel */
+
+static LRESULT
+progressPanelCommand(void *closure, HWND panel, WORD notificationcode, WORD sourceid, HWND control)
+{
+ (void)closure;
+
+ if (notificationcode == EN_CHANGE && sourceid == ID_PROGRESS_SPINBOX) {
+ ALF_Progress_SetValue(ALF_ControlHwndById(panel, ID_PROGRESS_BAR), (int)ALF_SpinBox_Pos(control));
+ ALF_Progress_SetValue(ALF_ControlHwndById(panel, ID_PROGRESS_NATIVE_BAR), (int)ALF_SpinBox_Pos(control));
+ ALF_Progress_SetValue(ALF_ControlHwndById(panel, ID_PROGRESS_GAUGE), (int)ALF_SpinBox_Pos(control));
+
+ TCHAR buf[4];
+ wsprintf(buf, TEXT("%d"), (int)ALF_SpinBox_Pos(control));
+ ALF_SetText(ALF_ControlHwndById(panel, ID_PROGRESS_GAUGE), buf);
+
+ return 1;
+ }
+
+ if (notificationcode == BN_CLICKED) {
+ if (sourceid == ID_PROGRESS_NORMAL) {
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_BAR), ALF_PROGRESS_STATE_NORMAL);
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_NATIVE_BAR), ALF_PROGRESS_STATE_NORMAL);
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_GAUGE), ALF_PROGRESS_STATE_NORMAL);
+ }
+ if (sourceid == ID_PROGRESS_PAUSED) {
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_BAR), ALF_PROGRESS_STATE_PAUSED);
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_NATIVE_BAR), ALF_PROGRESS_STATE_PAUSED);
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_GAUGE), ALF_PROGRESS_STATE_PAUSED);
+ }
+ if (sourceid == ID_PROGRESS_ERROR) {
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_BAR), ALF_PROGRESS_STATE_ERROR);
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_NATIVE_BAR), ALF_PROGRESS_STATE_ERROR);
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_GAUGE), ALF_PROGRESS_STATE_ERROR);
+ }
+ if (sourceid == ID_PROGRESS_INDETERMINATE) {
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_BAR), ALF_PROGRESS_STATE_INDETERMINATE);
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_NATIVE_BAR), ALF_PROGRESS_STATE_INDETERMINATE);
+ ALF_Progress_SetState(ALF_ControlHwndById(panel, ID_PROGRESS_GAUGE), ALF_PROGRESS_STATE_INDETERMINATE);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+progressPanelAttach(void *closure, HWND panel)
+{
+ (void)closure;
+
+ HWND bar = ALF_AddProgressBar(panel, ID_PROGRESS_BAR, 1, 1);
+ ALF_Progress_SetRange(bar, -50, 50);
+ HWND native = ALF_AddNativeProgressBar(panel, ID_PROGRESS_NATIVE_BAR, 1, 3);
+ ALF_Progress_SetRange(native, -50, 50);
+ HWND gauge = ALF_AddProgressGauge(panel, ID_PROGRESS_GAUGE, 1, 5);
+ ALF_Progress_SetRange(gauge, -50, 50);
+ ALF_AddNumericSpinBox(panel, ID_PROGRESS_SPINBOX, 1, 7, 12, -50, 50);
+
+ ALF_AddNativeButton(panel, ID_PROGRESS_NORMAL, 1, 9, TEXT("Normal"));
+ ALF_AddNativeButton(panel, ID_PROGRESS_PAUSED, 1, 11, TEXT("Paused"));
+ ALF_AddNativeButton(panel, ID_PROGRESS_ERROR, 1, 13, TEXT("Error"));
+ ALF_AddNativeButton(panel, ID_PROGRESS_INDETERMINATE, 1, 15, TEXT("Indeterminate"));
+
+ ALF_Layout_SetRowMinSize(panel, 0, 825);
+ ALF_Layout_SetRowMinSize(panel, 2, 825);
+ ALF_Layout_SetRowMinSize(panel, 4, 825);
+ ALF_Layout_SetRowMinSize(panel, 6, 825);
+ ALF_Layout_SetRowMinSize(panel, 8, 825);
+ ALF_Layout_SetRowMinSize(panel, 10, 825);
+ ALF_Layout_SetRowMinSize(panel, 12, 825);
+ ALF_Layout_SetRowMinSize(panel, 14, 825);
+ ALF_Layout_SetRowMinSize(panel, 16, 825);
+ ALF_Layout_SetColumnMinSize(panel, 0, 825);
+ ALF_Layout_SetColumnMinSize(panel, 2, 525);
+ ALF_Layout_SetColumnMinSize(panel, 4, 825);
+ ALF_Layout_SetRowExpandNumerator(panel, 16, 1);
+ ALF_Layout_SetColumnExpandNumerator(panel, 1, 1);
+ ALF_Layout_SetColumnExpandNumerator(panel, 3, 1);
+}
+
+static ALFPanelVTable progressPanelVtbl = {
+ progressPanelAttach,
+ commonPanelDestroy,
+ commonPanelMessage,
+ progressPanelCommand,
+ NULL,
+ commonPanelPaint,
+ NULL
+};
+
+static void
+progressPanelInit(HWND panel)
+{
+ CommonPanelPriv *priv = ALF_New(CommonPanelPriv, 1);
+ ALF_Panel_SetVTable(panel, &progressPanelVtbl, priv);
+}
+
void (*g_paneInitTable[PANE__MAX])(HWND) = {
buttonPanelInit, //PANE_BUTTONS
labelPanelInit, //PANE_LABEL,
@@ -876,7 +985,8 @@ void (*g_paneInitTable[PANE__MAX])(HWND) = {
checkboxPanelInit, //PANE_CHECKBOX,
groupboxPanelInit, //PANE_GROUPBOX,
iconviewPanelInit, //PANE_ICONVIEW,
- spinboxPanelInit //PANE_SPINBOX
+ spinboxPanelInit, //PANE_SPINBOX
+ progressPanelInit //PANE_PROGRESS
};
static void
@@ -1156,6 +1266,7 @@ WinMain
addPaneToNotebook(hwndNtbk, PANE_GROUPBOX);
addPaneToNotebook(hwndNtbk, PANE_ICONVIEW);
addPaneToNotebook(hwndNtbk, PANE_SPINBOX);
+ addPaneToNotebook(hwndNtbk, PANE_PROGRESS);
ALF_AddNativeButton(win, ID_HELLO, 1, 3, TEXT("&Hello World!"));
ALF_AddNativeButton(win, (WORD)-1, 3, 3, TEXT("Goodbye, World"));