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.cpp25
-rw-r--r--alf/alf.h45
-rw-r--r--alf/alfcompat.cpp14
-rw-r--r--alf/alfcompat.h7
-rw-r--r--alf/alfmessagedlg.cpp438
-rw-r--r--widgetfactory.cpp44
10 files changed, 591 insertions, 6 deletions
diff --git a/Makefile.mingw b/Makefile.mingw
index 5b8fe5d..def3fa3 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/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/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
@@ -44,6 +44,9 @@ out/alflabel.o: alf/alflabel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/
out/alflayout.o: alf/alflayout.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
+out/alfmessagedlg.o: alf/alfmessagedlg.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CXXFLAGS) -c -o $@ $<
+
out/alfnativebtn.o: alf/alfnativebtn.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
@@ -59,7 +62,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/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/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 2ad5eb8..57b79c4 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/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/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
@@ -44,6 +44,9 @@ out/alflabel.amd64.o: alf/alflabel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.
out/alflayout.amd64.o: alf/alflayout.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
+out/alfmessagedlg.amd64.o: alf/alfmessagedlg.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CXXFLAGS) -c -o $@ $<
+
out/alfnativebtn.amd64.o: alf/alfnativebtn.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
@@ -59,7 +62,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/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/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 fad4fa0..635e5eb 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/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/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
@@ -40,6 +40,9 @@ out/alflabel.obj: alf/alflabel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h al
out/alflayout.obj: alf/alflayout.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alflayout.cpp
+out/alfmessagedlg.obj: alf/alfmessagedlg.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfmessagedlg.cpp
+
out/alfnativebtn.obj: alf/alfnativebtn.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alfnativebtn.cpp
diff --git a/Makefile.vc6-ansi b/Makefile.vc6-ansi
index 8d534e6..174532f 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/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/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
@@ -40,6 +40,9 @@ out/alflabel.obj: alf/alflabel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h al
out/alflayout.obj: alf/alflayout.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alflayout.cpp
+out/alfmessagedlg.obj: alf/alfmessagedlg.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfmessagedlg.cpp
+
out/alfnativebtn.obj: alf/alfnativebtn.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alfnativebtn.cpp
diff --git a/alf/alf.cpp b/alf/alf.cpp
index 1bcbce3..c2f99ce 100644
--- a/alf/alf.cpp
+++ b/alf/alf.cpp
@@ -75,6 +75,31 @@ ALF_Free(const void *p)
HeapFree(GetProcessHeap(), 0, (void*)p);
}
+TCHAR *
+ALF_StrDup(const TCHAR *psz)
+{
+ int l = lstrlen(psz);
+ TCHAR *r = ALF_New(TCHAR, (SIZE_T)l + 1);
+ CopyMemory(r, psz, ((SIZE_T)l + 1) * sizeof(TCHAR));
+ return r;
+}
+
+TCHAR *
+ALF_StrOrIntresourceDup(const TCHAR *psz)
+{
+ if (IS_INTRESOURCE(psz))
+ return (TCHAR *)psz;
+ else
+ return ALF_StrDup(psz);
+}
+
+void
+ALF_StrOrIntresourceFree(const TCHAR *psz)
+{
+ if (!IS_INTRESOURCE(psz))
+ ALF_Free(psz);
+}
+
int
ALF_CentipointsToPixels(int cptValue, int dpi)
{
diff --git a/alf/alf.h b/alf/alf.h
index 6140e60..8969ee1 100644
--- a/alf/alf.h
+++ b/alf/alf.h
@@ -160,6 +160,15 @@ ALF_ReAlloc(void *ptr, SIZE_T nmemb, SIZE_T size);
void
ALF_Free(const void *p);
+TCHAR *
+ALF_StrDup(const TCHAR *psz);
+
+TCHAR *
+ALF_StrOrIntresourceDup(const TCHAR *psz);
+
+void
+ALF_StrOrIntresourceFree(const TCHAR *psz);
+
COLORREF
ALF_ColorToGdi(ALFColor color);
@@ -611,6 +620,42 @@ ALF_LoadIcon(HINSTANCE hinst, const TCHAR *name, int cx, int cy);
SIZE
ALF_IconSize(HICON icon);
+// custom message box
+HWND
+ALF_MessageDlg_Create(HWND owner);
+
+void
+ALF_MessageDlg_SetCaption(HWND msg, const TCHAR *caption);
+
+void
+ALF_MessageDlg_SetText(HWND msg, const TCHAR *text);
+
+void
+ALF_MessageDlg_SetIcon(HWND msg, HINSTANCE hinst, const TCHAR *name);
+
+void
+ALF_MessageDlg_AddButton(HWND msg, WORD id, const TCHAR *text);
+
+WORD
+ALF_MessageDlg_Run(HWND msg);
+
+// message box shortcuts
+void
+ALF_MessageDlg_Error(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText);
+
+void
+ALF_MessageDlg_Warning(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText);
+
+void
+ALF_MessageDlg_Information(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText);
+
+WORD // IDOK or IDCANCEL
+ALF_MessageDlg_Confirm(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText, const TCHAR *cancelBtnText);
+
+// like ALF_MessageDlg_Confirm, but shows an exclamation icon and preselects the cancel button
+WORD
+ALF_MessageDlg_ConfirmDanger(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText, const TCHAR *cancelBtnText);
+
#ifdef __cplusplus
} // extern C
diff --git a/alf/alfcompat.cpp b/alf/alfcompat.cpp
index 31c3eaa..f5bed22 100644
--- a/alf/alfcompat.cpp
+++ b/alf/alfcompat.cpp
@@ -533,6 +533,17 @@ static HMONITOR WINAPI ALF_Compat_fallbackMonitorFromWindow(HWND window, DWORD f
return (HMONITOR)0x12340042; // like multimon.h
}
+static BOOL WINAPI
+ALF_Compat_fallbackSetDialogDpiChangeBehavior(HWND hDlg,
+ ALF_Compat_DIALOG_DPI_CHANGE_BEHAVIORS mask,
+ ALF_Compat_DIALOG_DPI_CHANGE_BEHAVIORS values)
+{
+ (void)hDlg; (void)mask; (void)values;
+
+ SetLastError(ERROR_NOT_SUPPORTED);
+ return FALSE;
+}
+
static BOOL CALLBACK
ALF_Compat_DrawDisabledText_DrawStateProc(HDC hdc,
@@ -647,6 +658,7 @@ void ALF_LoadCompatFunctions(void)
LOAD_FUNC(user32, GetMonitorInfoA);
LOAD_FUNC(user32, MonitorFromPoint);
LOAD_FUNC(user32, MonitorFromWindow);
+ LOAD_FUNC(user32, SetDialogDpiChangeBehavior);
*((FARPROC*)&ALF_Compat_TrackMouseEvent) = GetProcAddress(_alf_dll_comctl32, "_TrackMouseEvent");
if (!ALF_Compat_TrackMouseEvent)
@@ -767,6 +779,7 @@ void ALF_UnloadCompatFunctions(void)
UNLOAD_FUNC(GetThemeColor);
UNLOAD_FUNC(GetThemeMargins);
UNLOAD_FUNC(LoadIconWithScaleDown);
+ UNLOAD_FUNC(SetDialogDpiChangeBehavior);
FreeLibrary(_alf_dll_uxtheme);
FreeLibrary(_alf_dll_user32);
@@ -808,3 +821,4 @@ HRESULT (WINAPI *ALF_Compat_LoadIconWithScaleDown)(HINSTANCE,PCWSTR,int,int,HICO
BOOL (WINAPI *ALF_Compat_GetMonitorInfoA)(HMONITOR,MONITORINFO *) = NULL;
HMONITOR (WINAPI *ALF_Compat_MonitorFromPoint)(POINT,DWORD) = NULL;
HMONITOR (WINAPI *ALF_Compat_MonitorFromWindow)(HWND,DWORD) = NULL;
+BOOL (WINAPI *ALF_Compat_SetDialogDpiChangeBehavior)(HWND, ALF_Compat_DIALOG_DPI_CHANGE_BEHAVIORS, ALF_Compat_DIALOG_DPI_CHANGE_BEHAVIORS) = NULL;
diff --git a/alf/alfcompat.h b/alf/alfcompat.h
index 8acdbc6..8f6b80f 100644
--- a/alf/alfcompat.h
+++ b/alf/alfcompat.h
@@ -86,6 +86,12 @@ typedef struct {
int cyBottomHeight;
} ALF_Compat_MARGINS;
+typedef enum {
+ ALF_Compat_DDC_DEFAULT,
+ ALF_Compat_DDC_DISABLE_ALL,
+ ALF_Compat_DDC_DISABLE_RESIZE,
+ ALF_Compat_DDC_DISABLE_CONTROL_RELAYOUT
+} ALF_Compat_DIALOG_DPI_CHANGE_BEHAVIORS;
#ifndef TMT_TRANSITIONDURATION
#define TMT_TRANSITIONDURATION 6000
@@ -141,6 +147,7 @@ extern HRESULT (WINAPI *ALF_Compat_LoadIconWithScaleDown)(HINSTANCE,PCWSTR,int,i
extern BOOL (WINAPI *ALF_Compat_GetMonitorInfoA)(HMONITOR,MONITORINFO *);
extern HMONITOR (WINAPI *ALF_Compat_MonitorFromPoint)(POINT,DWORD);
extern HMONITOR (WINAPI *ALF_Compat_MonitorFromWindow)(HWND,DWORD);
+extern BOOL (WINAPI *ALF_Compat_SetDialogDpiChangeBehavior)(HWND, ALF_Compat_DIALOG_DPI_CHANGE_BEHAVIORS, ALF_Compat_DIALOG_DPI_CHANGE_BEHAVIORS);
// compatibility bits
diff --git a/alf/alfmessagedlg.cpp b/alf/alfmessagedlg.cpp
new file mode 100644
index 0000000..554d55d
--- /dev/null
+++ b/alf/alfmessagedlg.cpp
@@ -0,0 +1,438 @@
+#include "alfpriv.h"
+
+#define ALF_WM_MESSAGEDLG_SETCAPTION (ALF_WM_USER + 1)
+#define ALF_WM_MESSAGEDLG_SETTEXT (ALF_WM_USER + 2)
+#define ALF_WM_MESSAGEDLG_ADDBUTTON (ALF_WM_USER + 3)
+#define ALF_WM_MESSAGEDLG_SETICON (ALF_WM_USER + 4)
+#define ALF_WM_MESSAGEDLG_BEEP (ALF_WM_USER + 5)
+
+typedef struct {
+ HINSTANCE hIconInstance;
+ PCTSTR pszIconName;
+ HWND hwndIconView;
+ HWND hwndIconWrapper;
+ HWND hwndText;
+ HWND hwndTextWrapper;
+ int nButtons;
+} ALFMessageDlgPriv;
+
+static BOOL
+ALF_MessageDlg_Initialize(void *closure, HWND hwnd)
+{
+ ALFMessageDlgPriv *priv = (ALFMessageDlgPriv *)closure;
+
+ priv->hwndIconWrapper = ALF_AddPanel(hwnd, (WORD)-1, 0, 0);
+ priv->hwndTextWrapper = ALF_AddPanel(hwnd, (WORD)-1, 1, 0);
+ priv->hwndIconView = ALF_AddIconView(priv->hwndIconWrapper, (WORD)-1, 1, 1, NULL);
+ priv->hwndText = ALF_AddLabel(priv->hwndTextWrapper, (WORD)-1, 0, 1, TEXT(""));
+
+ ALF_SetBackgroundColor(priv->hwndIconWrapper, ALF_COLOR_SYS(COLOR_WINDOW));
+ ALF_SetBackgroundColor(priv->hwndTextWrapper, ALF_COLOR_SYS(COLOR_WINDOW));
+
+ ALF_SetTextColor(priv->hwndText, ALF_COLOR_SYS(COLOR_WINDOWTEXT));
+ ALF_Label_SetStyle(priv->hwndText, ALF_LABEL_ALIGN_LEFT | ALF_LABEL_ALIGN_VCENTER);
+
+ ALF_Layout_SetColumnMinSize(priv->hwndIconWrapper, 0, 1650);
+ ALF_Layout_SetColumnMinSize(priv->hwndIconWrapper, 2, 825);
+ ALF_Layout_SetRowMinSize(priv->hwndIconWrapper, 0, 1650);
+ ALF_Layout_SetRowMinSize(priv->hwndIconWrapper, 2, 1650);
+ ALF_Layout_SetRowExpandNumerator(priv->hwndIconWrapper, 2, 1);
+ ALF_Layout_SetColumnExpandNumerator(priv->hwndIconWrapper, 1, 1);
+
+ ALF_Layout_SetColumnMinSize(priv->hwndTextWrapper, 1, 1650);
+ ALF_Layout_SetRowMinSize(priv->hwndTextWrapper, 0, 1650);
+ ALF_Layout_SetRowMinSize(priv->hwndTextWrapper, 2, 1650);
+ ALF_Layout_SetColumnExpandNumerator(priv->hwndTextWrapper, 1, 1);
+ ALF_Layout_SetRowExpandNumerator(priv->hwndTextWrapper, 2, 1);
+ ALF_Layout_SetRowFlags(priv->hwndTextWrapper, 1, ALF_LAYOUT_SIZE_PX);
+
+ ALF_Layout_SetRowMinSize(hwnd, 1, 825);
+ ALF_Layout_SetRowMinSize(hwnd, 3, 825);
+ ALF_Layout_SetRowExpandNumerator(hwnd, 0, 1);
+ ALF_Layout_SetColumnExpandNumerator(hwnd, 1, 1);
+
+ return FALSE;
+}
+
+static void
+ALF_MessageDlg_HandleAddButton(ALFMessageDlgPriv *priv, HWND hwnd, WORD id, const TCHAR *text)
+{
+ (void)hwnd;
+
+ HWND hwndBtn = ALF_AddNativeButton(hwnd, id, 2 * priv->nButtons + 2, 2, text);
+ ALF_Layout_SetColumnMinSize(hwnd, 2 * priv->nButtons + 3, 525);
+ ALF_Layout_SetControlSpan(hwnd, priv->hwndTextWrapper, priv->nButtons * 2 + 3, 1);
+
+ if (priv->nButtons == 0)
+ ALF_SetFocus(hwndBtn);
+
+ priv->nButtons += 1;
+}
+
+static void
+ALF_MessageDlg_Destroy(void *closure, HWND hwnd)
+{
+ (void)hwnd;
+ ALFMessageDlgPriv *priv = (ALFMessageDlgPriv *)closure;
+
+ HICON hicon = ALF_IconView_Icon(priv->hwndIconView);
+ DestroyIcon(hicon);
+}
+
+static void
+ALF_MessageDlg_PostDestroy(void *closure)
+{
+ ALFMessageDlgPriv *priv = (ALFMessageDlgPriv *)closure;
+
+ ALF_StrOrIntresourceFree(priv->pszIconName);
+ ALF_Free(priv);
+}
+
+static void
+ALF_MessageDlg_UpdateIcon(ALFMessageDlgPriv *priv, HWND hwnd)
+{
+ UINT dpi = (UINT)ALF_GetDpi(hwnd);
+ HICON n = ALF_LoadIcon(priv->hIconInstance, priv->pszIconName,
+ ALF_Compat_GetSystemMetricsForDpi(SM_CXICON, dpi),
+ ALF_Compat_GetSystemMetricsForDpi(SM_CYICON, dpi));
+ HICON o = ALF_IconView_SetIcon(priv->hwndIconView, n);
+ DestroyIcon(o);
+
+ SIZE s = { 0, 0 };
+ SendMessage(priv->hwndIconView, ALF_WM_QUERYSIZE, 0, (LPARAM)&s);
+ ALF_Layout_SetRowMinSize(priv->hwndTextWrapper, 1, s.cy);
+}
+
+static void
+ALF_MessageDlg_HandleFontsDpiChange(void *closure, HWND hwnd)
+{
+ ALFMessageDlgPriv *priv = (ALFMessageDlgPriv *)closure;
+
+ ALF_MessageDlg_UpdateIcon(priv, hwnd);
+ ALF_Toplevel_SetDefaultFont(hwnd);
+}
+
+static LRESULT
+ALF_MessageDlg_HandleCommand(void *closure, HWND hwnd, WORD code, WORD sourceid, HWND control)
+{
+ (void)closure;
+
+ if (control && code == BN_CLICKED) {
+ ALF_Toplevel_SetModalResult(hwnd, sourceid);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+ALF_MessageDlg_HandleSetIcon(ALFMessageDlgPriv *priv, HWND hwnd, HINSTANCE inst, const TCHAR *iconName)
+{
+ priv->hIconInstance = inst;
+ ALF_StrOrIntresourceFree(priv->pszIconName);
+ priv->pszIconName = ALF_StrOrIntresourceDup(iconName);
+
+ ALF_MessageDlg_UpdateIcon(priv, hwnd);
+}
+
+static void
+ALF_MessageDlg_HandleSetCaption(ALFMessageDlgPriv *priv, HWND hwnd, const TCHAR *caption)
+{
+ (void)priv;
+
+ ALF_SetText(hwnd, caption);
+}
+
+static void
+ALF_MessageDlg_HandleSetText(ALFMessageDlgPriv *priv, HWND hwnd, const TCHAR *text)
+{
+ (void)hwnd;
+ ALF_SetText(priv->hwndText, text);
+}
+
+static void
+ALF_MessageDlg_HandleBeep(ALFMessageDlgPriv *priv, HWND hwnd)
+{
+ (void)hwnd;
+
+ if (priv->hIconInstance == NULL && priv->pszIconName == IDI_EXCLAMATION)
+ MessageBeep(MB_ICONEXCLAMATION);
+ else if (priv->hIconInstance == NULL && priv->pszIconName == IDI_HAND)
+ MessageBeep(MB_ICONHAND);
+ else if (priv->hIconInstance == NULL && priv->pszIconName == IDI_QUESTION)
+ MessageBeep(MB_ICONQUESTION);
+ else
+ MessageBeep(MB_ICONASTERISK);
+}
+
+static LRESULT
+ALF_MessageDlg_HandleWindowPosChanging(ALFMessageDlgPriv *priv, HWND hwnd, WPARAM wparam, WINDOWPOS *wp)
+{
+ (void)priv;
+
+ // XXX: for WS_THICKFRAME windows this is done automatically, but we need to do it ourselves
+ // investigate whether it should be done in ALFToplevel
+ if (!(wp->flags & SWP_NOSIZE)) {
+ MINMAXINFO tmp = {
+ { 0, 0 },
+ { wp->cx, wp->cy},
+ { 0, 0 },
+ { wp->cx, wp->cy },
+ { wp->cx, wp->cy }
+ };
+ SendMessage(hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&tmp);
+
+ if (tmp.ptMinTrackSize.x > wp->cx)
+ wp->cx = tmp.ptMinTrackSize.x;
+
+ if (tmp.ptMinTrackSize.y > wp->cy)
+ wp->cy = tmp.ptMinTrackSize.y;
+ }
+
+ return ALF_Toplevel_DefWindowProc(hwnd, WM_WINDOWPOSCHANGING, wparam, (LPARAM)wp);
+}
+
+static int
+ALF_MessageDlg_AsTextLength(ALFMessageDlgPriv *priv, HWND hwnd)
+{
+ int l = 0;
+
+ int titlelength = GetWindowTextLength(hwnd);
+
+ l += titlelength;
+ l += 2; //\r\n
+ l += titlelength; // underline
+ l += 4; //\r\n\r\n
+ l += GetWindowTextLength(priv->hwndText);
+ l += 4; //\r\n\r\n
+
+ for (int i = 0; i < priv->nButtons; ++i) {
+ l += GetWindowTextLength(ALF_Layout_ControlAtPosition(hwnd, i * 2 + 2, 2));
+ l += 3; // [] <space> or \r
+ }
+
+ l += 1; // \n
+ return l;
+}
+
+static void
+ALF_MessageDlg_AsText(ALFMessageDlgPriv *priv, HWND hwnd, TCHAR *buf)
+{
+ int titlelength = GetWindowText(hwnd, buf, 0x7fffffff);
+ buf += titlelength;
+ *buf++ = '\r'; *buf++ = '\n';
+
+ for (int i = 0; i < titlelength; ++i)
+ *buf++ = '=';
+
+ *buf++ = '\r'; *buf++ = '\n'; *buf++ = '\r'; *buf++ = '\n';
+ buf += GetWindowText(priv->hwndText, buf, 0x7fffffff);
+ *buf++ = '\r'; *buf++ = '\n'; *buf++ = '\r'; *buf++ = '\n';
+ for (int i = 0; i < priv->nButtons; ++i) {
+ if (i != 0)
+ *buf++ = ' ';
+
+ *buf++ = '[';
+ buf += GetWindowText(ALF_Layout_ControlAtPosition(hwnd, i * 2 + 2, 2), buf, 0x7fffffff);
+ *buf++ = ']';
+ }
+
+ *buf++ = '\r'; *buf++ = '\n';
+ *buf = 0;
+}
+
+static BOOL
+ALF_MessageDlg_PreTranslateMessage(void *closure, HWND hwnd, MSG *msg)
+{
+ ALFMessageDlgPriv *priv = (ALFMessageDlgPriv *)closure;
+
+ if (msg->message == WM_KEYDOWN && (msg->wParam == VK_ESCAPE || msg->wParam == VK_CANCEL)) {
+ ALF_Toplevel_SetModalResult(hwnd, IDCANCEL);
+ return TRUE;
+ } else if (msg->message == WM_KEYDOWN && msg->wParam == 'C' && GetKeyState(VK_CONTROL) & 0x8000) {
+ if (OpenClipboard(hwnd)) {
+ EmptyClipboard();
+
+ int len = ALF_MessageDlg_AsTextLength(priv, hwnd);
+
+ HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, ((SIZE_T)len+1)*sizeof(TCHAR));
+ TCHAR *buf = (TCHAR* )GlobalLock(hMem);
+ ALF_MessageDlg_AsText(priv, hwnd, buf);
+ GlobalUnlock(hMem);
+
+#ifdef UNICODE
+ SetClipboardData(CF_UNICODETEXT, hMem);
+#else
+ SetClipboardData(CF_TEXT, hMem);
+#endif
+
+ CloseClipboard();
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+}
+
+static LRESULT
+ALF_MessageDlg_HandleMessage(void *closure, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ ALFMessageDlgPriv *priv = (ALFMessageDlgPriv *)closure;
+
+ switch (msg) {
+ case ALF_WM_MESSAGEDLG_SETCAPTION:
+ ALF_MessageDlg_HandleSetCaption(priv, hwnd, (const TCHAR *)lparam);
+ return 1;
+ case ALF_WM_MESSAGEDLG_SETTEXT:
+ ALF_MessageDlg_HandleSetText(priv, hwnd, (const TCHAR *)lparam);
+ return 1;
+ case ALF_WM_MESSAGEDLG_ADDBUTTON:
+ ALF_MessageDlg_HandleAddButton(priv, hwnd, (WORD)wparam, (const TCHAR *)lparam);
+ return 1;
+ case ALF_WM_MESSAGEDLG_SETICON:
+ ALF_MessageDlg_HandleSetIcon(priv, hwnd, (HINSTANCE)wparam, (const TCHAR *)lparam);
+ return 1;
+ case ALF_WM_MESSAGEDLG_BEEP:
+ ALF_MessageDlg_HandleBeep(priv, hwnd);
+ return 1;
+ case WM_WINDOWPOSCHANGING:
+ return ALF_MessageDlg_HandleWindowPosChanging(priv, hwnd, wparam, (WINDOWPOS *)lparam);
+ }
+
+ return ALF_Toplevel_DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+static void
+ALF_MessageDlg_HandleClose(void *closure, HWND hwnd)
+{
+ (void)closure;
+
+ ALF_Toplevel_SetModalResult(hwnd, IDCANCEL);
+}
+
+static ALFToplevelVTable _alf_messageDlgVtbl = {
+ ALF_MessageDlg_Initialize, /* initialize */
+ ALF_MessageDlg_Destroy, /* destroy */
+ ALF_MessageDlg_HandleClose, /* close */
+ ALF_MessageDlg_PostDestroy, /* postdestroy */
+ ALF_MessageDlg_HandleMessage, /* message */
+ ALF_MessageDlg_HandleCommand, /* command */
+ NULL, /* notify */
+ ALF_MessageDlg_PreTranslateMessage, /* pretranslatemessage */
+ NULL, /* paint */
+ NULL, /* windowposchanged */
+ ALF_MessageDlg_HandleFontsDpiChange /* updatefontsdpi */
+};
+
+HWND
+ALF_MessageDlg_Create(HWND owner)
+{
+ ALFMessageDlgPriv *priv = ALF_New(ALFMessageDlgPriv, 1);
+ return ALF_CreateToplevelWindow(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE,
+ WS_POPUPWINDOW | WS_DLGFRAME | WS_CAPTION | DS_MODALFRAME,
+ owner, NULL,
+ &_alf_messageDlgVtbl,
+ priv);
+}
+
+void
+ALF_MessageDlg_SetCaption(HWND msg, const TCHAR *caption)
+{
+ SendMessage(msg, ALF_WM_MESSAGEDLG_SETCAPTION, 0, (LPARAM)caption);
+}
+
+void
+ALF_MessageDlg_SetText(HWND msg, const TCHAR *text)
+{
+ SendMessage(msg, ALF_WM_MESSAGEDLG_SETTEXT, 0, (LPARAM)text);
+}
+
+void
+ALF_MessageDlg_SetIcon(HWND msg, HINSTANCE hinst, const TCHAR *name)
+{
+ SendMessage(msg, ALF_WM_MESSAGEDLG_SETICON, (WPARAM)hinst, (LPARAM)name);
+}
+
+void
+ALF_MessageDlg_AddButton(HWND msg, WORD id, const TCHAR *text)
+{
+ SendMessage(msg, ALF_WM_MESSAGEDLG_ADDBUTTON, (WPARAM)id, (LPARAM)text);
+}
+
+WORD
+ALF_MessageDlg_Run(HWND msg)
+{
+ ALF_Toplevel_CenterOnOwnerMonitor(msg);
+ SendMessage(msg, ALF_WM_MESSAGEDLG_BEEP, 0, 0);
+ return (WORD)ALF_Toplevel_ShowModal(msg);
+}
+
+// message box shortcuts
+void
+ALF_MessageDlg_Error(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText)
+{
+ HWND m = ALF_MessageDlg_Create(owner);
+ ALF_MessageDlg_SetCaption(m, caption);
+ ALF_MessageDlg_SetText(m, text);
+ ALF_MessageDlg_SetIcon(m, NULL, IDI_HAND);
+ ALF_MessageDlg_AddButton(m, IDOK, okBtnText ? okBtnText : TEXT("OK"));
+ ALF_MessageDlg_Run(m);
+ DestroyWindow(m);
+}
+
+void
+ALF_MessageDlg_Warning(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText)
+{
+ HWND m = ALF_MessageDlg_Create(owner);
+ ALF_MessageDlg_SetCaption(m, caption);
+ ALF_MessageDlg_SetText(m, text);
+ ALF_MessageDlg_SetIcon(m, NULL, IDI_EXCLAMATION);
+ ALF_MessageDlg_AddButton(m, IDOK, okBtnText ? okBtnText : TEXT("OK"));
+ ALF_MessageDlg_Run(m);
+ DestroyWindow(m);
+}
+
+void
+ALF_MessageDlg_Information(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText)
+{
+ HWND m = ALF_MessageDlg_Create(owner);
+ ALF_MessageDlg_SetCaption(m, caption);
+ ALF_MessageDlg_SetText(m, text);
+ ALF_MessageDlg_SetIcon(m, NULL, IDI_ASTERISK);
+ ALF_MessageDlg_AddButton(m, IDOK, okBtnText ? okBtnText : TEXT("OK"));
+ ALF_MessageDlg_Run(m);
+ DestroyWindow(m);
+}
+
+WORD // IDOK or IDCANCEL
+ALF_MessageDlg_Confirm(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText, const TCHAR *cancelBtnText)
+{
+ HWND m = ALF_MessageDlg_Create(owner);
+ ALF_MessageDlg_SetCaption(m, caption);
+ ALF_MessageDlg_SetText(m, text);
+ ALF_MessageDlg_SetIcon(m, NULL, IDI_QUESTION);
+ ALF_MessageDlg_AddButton(m, IDOK, okBtnText ? okBtnText : TEXT("OK"));
+ ALF_MessageDlg_AddButton(m, IDCANCEL, cancelBtnText ? cancelBtnText : TEXT("Cancel"));
+ WORD r = ALF_MessageDlg_Run(m);
+ DestroyWindow(m);
+ return r;
+}
+
+// like ALF_MessageDlg_Confirm, but shows an exclamation icon and preselects the cancel button
+WORD
+ALF_MessageDlg_ConfirmDanger(HWND owner, const TCHAR *text, const TCHAR *caption, const TCHAR *okBtnText, const TCHAR *cancelBtnText)
+{
+ HWND m = ALF_MessageDlg_Create(owner);
+ ALF_MessageDlg_SetCaption(m, caption);
+ ALF_MessageDlg_SetText(m, text);
+ ALF_MessageDlg_SetIcon(m, NULL, IDI_EXCLAMATION);
+ ALF_MessageDlg_AddButton(m, IDOK, okBtnText ? okBtnText : TEXT("OK"));
+ ALF_MessageDlg_AddButton(m, IDCANCEL, cancelBtnText ? cancelBtnText : TEXT("Cancel"));
+ ALF_Toplevel_SetDefaultButton(m, IDCANCEL);
+ ALF_SetFocus(ALF_ControlHwndById(m, IDCANCEL));
+ WORD r = ALF_MessageDlg_Run(m);
+ DestroyWindow(m);
+ return r;
+}
diff --git a/widgetfactory.cpp b/widgetfactory.cpp
index cc3ede9..3298d81 100644
--- a/widgetfactory.cpp
+++ b/widgetfactory.cpp
@@ -40,6 +40,11 @@ enum {
IDM_BACKGROUND_GREEN,
IDM_BACKGROUND_BLUE,
IDM_CENTER_ON_MONITOR,
+ IDM_MESSAGEDLG_INFO,
+ IDM_MESSAGEDLG_WARNING,
+ IDM_MESSAGEDLG_ERROR,
+ IDM_MESSAGEDLG_QUESTION,
+ IDM_MESSAGEDLG_DANGERQUESTION,
IDM_PANES,
IDM_PANES__MAX = IDM_PANES + PANE__MAX,
IDM_MODALDIALOG_PANES,
@@ -898,6 +903,39 @@ handleCommand(void *closure, HWND window, WORD notificationcode, WORD sourceid,
ALF_Toplevel_CenterOnCurrentMonitor(window);
}
+ if (sourceid == IDM_MESSAGEDLG_INFO) {
+ const TCHAR *text = TEXT("Hello World!\r\n\r\n"
+ "This is a really long text to show that there is no automatic line breaking going on.\r\n"
+ "We also want to demo\r\n\r\n\r\n\r\n\r\n\r\n"
+ "what happens when the text is very high");
+
+ ALF_MessageDlg_Information(window, text, TEXT("Hello"), NULL);
+ }
+
+ if (sourceid == IDM_MESSAGEDLG_WARNING) {
+ ALF_MessageDlg_Warning(window, TEXT("Something noteworthy happened"), TEXT("Warning"), TEXT("Got it!"));
+ }
+
+ if (sourceid == IDM_MESSAGEDLG_ERROR) {
+ ALF_MessageDlg_Error(window, TEXT("Something happened."), TEXT("ERROR"), NULL);
+ }
+
+ if (sourceid == IDM_MESSAGEDLG_QUESTION) {
+ if (ALF_MessageDlg_Confirm(window, TEXT("Continue?"), TEXT("Question"), TEXT("Yes"), TEXT("No")) == IDOK) {
+ ALF_MessageDlg_Information(window, TEXT("You clicked OK"), TEXT("Info"), NULL);
+ } else {
+ ALF_MessageDlg_Information(window, TEXT("You clicked Cancel"), TEXT("Info"), NULL);
+ }
+ }
+
+ if (sourceid == IDM_MESSAGEDLG_DANGERQUESTION) {
+ if (ALF_MessageDlg_ConfirmDanger(window, TEXT("Do you want to format your hard drive?"), TEXT("Question"), TEXT("&Format Drive"), TEXT("Cancel")) == IDOK) {
+ ALF_MessageDlg_Information(window, TEXT("You clicked OK"), TEXT("Info"), NULL);
+ } else {
+ ALF_MessageDlg_Information(window, TEXT("You clicked Cancel"), TEXT("Info"), NULL);
+ }
+ }
+
return 0;
}
@@ -1090,6 +1128,12 @@ WinMain
AppendMenu(helpmenu, MF_STRING, IDM_CENTER_ON_MONITOR, TEXT("Center Window"));
AppendMenu(helpmenu, MF_SEPARATOR, 0, 0);
+ AppendMenu(helpmenu, MF_STRING, IDM_MESSAGEDLG_INFO, TEXT("Information"));
+ AppendMenu(helpmenu, MF_STRING, IDM_MESSAGEDLG_WARNING, TEXT("Warning"));
+ AppendMenu(helpmenu, MF_STRING, IDM_MESSAGEDLG_ERROR, TEXT("Error"));
+ AppendMenu(helpmenu, MF_STRING, IDM_MESSAGEDLG_QUESTION, TEXT("Question"));
+ AppendMenu(helpmenu, MF_STRING, IDM_MESSAGEDLG_DANGERQUESTION, TEXT("Dangerous Question"));
+ AppendMenu(helpmenu, MF_SEPARATOR, 0, 0);
AppendMenu(helpmenu, MF_STRING, IDM_HELP_ABOUT, TEXT("&About"));
AppendMenu(bgmenu, MF_STRING, IDM_BACKGROUND_INHERIT, TEXT("(Default)"));