diff options
| -rw-r--r-- | Makefile.mingw | 6 | ||||
| -rw-r--r-- | Makefile.mingw-amd64 | 6 | ||||
| -rw-r--r-- | Makefile.vc6 | 6 | ||||
| -rw-r--r-- | Makefile.vc6-ansi | 6 | ||||
| -rw-r--r-- | alf/alf.cpp | 82 | ||||
| -rw-r--r-- | alf/alf.h | 148 | ||||
| -rw-r--r-- | alf/alfbutton.cpp | 6 | ||||
| -rw-r--r-- | alf/alfpriv.h | 6 | ||||
| -rw-r--r-- | alf/alftoplevel.cpp (renamed from alf/alfwindow.cpp) | 157 | ||||
| -rw-r--r-- | widgetfactory.cpp | 10 |
10 files changed, 224 insertions, 209 deletions
diff --git a/Makefile.mingw b/Makefile.mingw index 8c29c5d..cf2ba63 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/alflabel.o out/alflayout.o out/alfnativebtn.o out/alfnotebook.o out/alfpanel.o out/alfwindow.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/alflabel.o out/alflayout.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 @@ -50,13 +50,13 @@ 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/alfwindow.o: alf/alfwindow.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h +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/alflabel.cpp alf/alflayout.cpp alf/alfnativebtn.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfwindow.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/alflabel.cpp alf/alflayout.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 17e7aea..b723180 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/alflabel.amd64.o out/alflayout.amd64.o out/alfnativebtn.amd64.o out/alfnotebook.amd64.o out/alfpanel.amd64.o out/alfwindow.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/alflabel.amd64.o out/alflayout.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 @@ -50,13 +50,13 @@ 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/alfwindow.amd64.o: alf/alfwindow.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h +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/alflabel.cpp alf/alflayout.cpp alf/alfnativebtn.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfwindow.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/alflabel.cpp alf/alflayout.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 c850e7d..95a6681 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/alflabel.obj out/alflayout.obj out/alfnativebtn.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.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/alflabel.obj out/alflayout.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 @@ -46,8 +46,8 @@ 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/alfwindow.obj: alf/alfwindow.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h - $(CXX) $(CFLAGS) -c -Fo$@ alf/alfwindow.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 out/widgetfactory.obj: widgetfactory.cpp alf/alf.h $(CXX) $(CFLAGS) -c -Fo$@ widgetfactory.cpp diff --git a/Makefile.vc6-ansi b/Makefile.vc6-ansi index 8a6cb3f..adf38bf 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/alflabel.obj out/alflayout.obj out/alfnativebtn.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.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/alflabel.obj out/alflayout.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 @@ -46,8 +46,8 @@ 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/alfwindow.obj: alf/alfwindow.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h - $(CXX) $(CFLAGS) -c -Fo$@ alf/alfwindow.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 out/widgetfactory.obj: widgetfactory.cpp alf/alf.h $(CXX) $(CFLAGS) -c -Fo$@ widgetfactory.cpp diff --git a/alf/alf.cpp b/alf/alf.cpp index de23784..84ba71d 100644 --- a/alf/alf.cpp +++ b/alf/alf.cpp @@ -45,7 +45,7 @@ ALF_Initialize(void) ALF_LoadCompatFunctions(); - ALF_RegisterWindowClass(); + ALF_RegisterToplevelClass(); ALF_RegisterControlClass(); ALF_Compat_BufferedPaintInit(); @@ -67,7 +67,8 @@ ALF_UnInitialize(void) if (!--_alf_initCounter) { ALF_Compat_BufferedPaintUnInit(); - UnregisterClass(_alf_windowClass, ALF_HINSTANCE); + ALF_UnregisterToplevelClass(); + UnregisterClass(_alf_controlClass, ALF_HINSTANCE); ALF_UnloadCompatFunctions(); @@ -104,52 +105,6 @@ ALF_Free(const void *p) HeapFree(GetProcessHeap(), 0, (void*)p); } -void -ALF_DestroyWindow(HWND win) -{ - DestroyWindow(win); -} - -int -ALF_ShowModal(HWND win) -{ - MSG msg; - - ALF_SetModalResult(win, 0); - - // TODO: disable parent window - ShowWindow(win, SW_SHOW); - - while (GetMessage(&msg, NULL, 0, 0) > 0) { - // TODO: call application message hooks - // TODO: call preprocess message hook - - if (!IsDialogMessage(win, &msg)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - int mr = ALF_GetModalResult(win); - if (mr) - return mr; - } - - return 0; -} - - -void -ALF_SetModalResult(HWND win, int result) -{ - SendMessage(win, ALF_WM_SETMODALRESULT, (WPARAM)result, 0); -} - -int -ALF_GetModalResult(HWND win) -{ - return (int)SendMessage(win, ALF_WM_GETMODALRESULT, 0, 0); -} - int ALF_CentipointsToPixels(int cptValue, int dpi) { @@ -162,37 +117,6 @@ ALF_GetDpi(HWND window) return (int)SendMessage(window, ALF_WM_GETDPI, 0, 0); } -void -ALF_ResizeWindow(HWND win, int cptWidth, int cptHeight) -{ - int dpi = ALF_GetDpi(win); - - int pxwidth = ALF_CentipointsToPixels(cptWidth, dpi); - int pxheight = ALF_CentipointsToPixels(cptHeight, dpi); - - ALF_ResizeWindowPx(win, pxwidth, pxheight); -} - -void -ALF_ResizeWindowPx(HWND win, int pxwidth, int pxheight) -{ - MINMAXINFO tmp = { - { 0, 0 }, - { pxwidth, pxheight }, - { 0, 0 }, - { pxwidth, pxheight }, - { pxwidth, pxheight } - }; - SendMessage(win, WM_GETMINMAXINFO, 0, (LPARAM)&tmp); - - if (tmp.ptMinTrackSize.x > pxwidth) - pxwidth = tmp.ptMinTrackSize.x; - if (tmp.ptMinTrackSize.y > pxheight) - pxheight = tmp.ptMinTrackSize.y; - - SetWindowPos(win, NULL, 0, 0, pxwidth, pxheight, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER); -} - struct ALF_WidgetHwndById_Closure { HWND result; WORD needle; @@ -18,7 +18,7 @@ typedef struct { BOOL (*pretranslatemessage)(void * /*closure*/, HWND /*window*/, MSG * /*message*/); void (*paint)(void * /*closure*/, HWND, HDC, RECT *); void (*windowposchanged)(void * /*closure*/, HWND, WINDOWPOS *); -} ALFWindowVTable; +} ALFToplevelVTable; typedef struct { void (*attachvtbl)(void * /*closure*/, HWND /*panel*/); @@ -159,62 +159,12 @@ ALF_Free(const void *p); COLORREF ALF_ColorToGdi(ALFColor color); -HWND -ALF_CreateToplevelWindow(HWND hwndParent, ALFWindowVTable *vtbl, void *closure); - -void -ALF_DestroyWindow(HWND win); - int ALF_CentipointsToPixels(int cptValue, int dpi); int ALF_GetDpi(HWND hwnd); -LRESULT -ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); - -void -ALF_EnsureWindowBigEnough(HWND toplevel); - -HWND -ALF_AddLabel(HWND win, WORD id, int x, int y, const TCHAR *text); - -DWORD -ALF_LabelStyle(HWND hwndLabel); - -void -ALF_LabelSetStyle(HWND hwndLabel, DWORD style); - -HWND -ALF_AddEdit(HWND win, WORD id, int x, int y, const TCHAR *text); - -HWND -ALF_AddButton(HWND win, WORD id, int x, int y, const TCHAR *text); - -// NOTE about default buttons: -// -// - If no default button is specified, the default button will be the button -// with the id IDOK. A WM_COMMAND message on pressing the return key will be -// sent even if no widget with the default id can be found. -// - In NT 3.51, the default button must be a direct child of the window. Otherwise -// the default button effect will not work. -// - In Win32s on Win3.1, the default button should be a direct child of the window. -// Otherwise the default button effect will be buggy when setting the focus -// via WM_NEXTDLGCTL or ALF_SetFocus(), but it will work correctly when using -// the TAB key. -// - Changing the default button will only fully take effect after a focus change. -// It might temporarily lead to artifacts such as having two or no default buttons. -// -// Recommendation: Set the default button during window initialization, and then -// immediately set the focus via ALF_SetFocus(). If you want to support NT 3.51 -// or Win32s, ensure that the default button is a direct child of the toplevel window. -void -ALF_SetDefaultButton(HWND win, WORD id); - -void -ALF_DestroyWidget(HWND win, WORD id); - void ALF_AddWidget(HWND win, int x, int y, HWND widget, int width, int height, DWORD flags); @@ -256,21 +206,6 @@ void ALF_SetTextColor(HWND win, ALFColor color); void -ALF_ResizeWindow(HWND win, int cptWidth, int cptHeight); - -void -ALF_ResizeWindowPx(HWND win, int pxWidth, int pxHeight); - -int -ALF_ShowModal(HWND win); - -void -ALF_SetModalResult(HWND win, int result); - -int -ALF_GetModalResult(HWND win); - -void ALF_SetFocus(HWND target); void @@ -360,10 +295,89 @@ ALF_LayoutColumnExpandNumerator(HWND parent, int colno); BOOL ALF_LayoutSetColumnExpandNumerator(HWND parent, int colno, int expand); - void ALF_FillRect(HDC dc, const RECT *rc, ALFColor color); +void +ALF_DestroyWidget(HWND win, WORD id); + +// toplevel window + +HWND +ALF_CreateToplevelWindow(HWND hwndParent, ALFToplevelVTable *vtbl, void *closure); + +void +ALF_Toplevel_Resize(HWND win, int cptWidth, int cptHeight); + +void +ALF_Toplevel_ResizePx(HWND win, int pxWidth, int pxHeight); + + +// To add to your message loop like IsDialogMessage +// NOT TREAD SAFE: Only call from the thread owning the window +// (accesses internal data structures directly for performance) +BOOL +ALF_Toplevel_PreTranslateMessage(HWND toplevel, MSG *msg); + +// Shows the window as a modal window (i.e. disabling the owner window) +// returns once the modal window has been ended via ALF_Toplevel_SetModalResult +// NOT THREAD SAFE: Only call from the thread owning the window +// (accesses internal data structures directly for performance) +LPARAM +ALF_Toplevel_ShowModal(HWND toplevel); + +void +ALF_Toplevel_SetModalResult(HWND win, LRESULT result); + +LRESULT +ALF_Toplevel_GetModalResult(HWND win); + +LRESULT +ALF_Toplevel_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); + +void +ALF_Toplevel_EnsureBigEnough(HWND toplevel); + +// NOTE about default buttons: +// +// - If no default button is specified, the default button will be the button +// with the id IDOK. A WM_COMMAND message on pressing the return key will be +// sent even if no widget with the default id can be found. +// - In NT 3.51, the default button must be a direct child of the window. Otherwise +// the default button effect will not work. +// - In Win32s on Win3.1, the default button should be a direct child of the window. +// Otherwise the default button effect will be buggy when setting the focus +// via WM_NEXTDLGCTL or ALF_SetFocus(), but it will work correctly when using +// the TAB key. +// - Changing the default button will only fully take effect after a focus change. +// It might temporarily lead to artifacts such as having two or no default buttons. +// +// Recommendation: Set the default button during window initialization, and then +// immediately set the focus via ALF_SetFocus(). If you want to support NT 3.51 +// or Win32s, ensure that the default button is a direct child of the toplevel window. +void +ALF_Toplevel_SetDefaultButton(HWND win, WORD id); + +// label + +HWND +ALF_AddLabel(HWND win, WORD id, int x, int y, const TCHAR *text); + +DWORD +ALF_LabelStyle(HWND hwndLabel); + +void +ALF_LabelSetStyle(HWND hwndLabel, DWORD style); + +// edit + +HWND +ALF_AddEdit(HWND win, WORD id, int x, int y, const TCHAR *text); + +// button + +HWND +ALF_AddButton(HWND win, WORD id, int x, int y, const TCHAR *text); // combo box diff --git a/alf/alfbutton.cpp b/alf/alfbutton.cpp index 6d7d319..00bd3fb 100644 --- a/alf/alfbutton.cpp +++ b/alf/alfbutton.cpp @@ -1415,9 +1415,3 @@ ALF_AddRadioButton(HWND parent, WORD id, int x, int y, const TCHAR *text) } } -void -ALF_SetDefaultButton(HWND win, WORD id) -{ - SendMessage(win, DM_SETDEFID, (WPARAM)id, 0); -} - diff --git a/alf/alfpriv.h b/alf/alfpriv.h index 0c5cc25..586bbba 100644 --- a/alf/alfpriv.h +++ b/alf/alfpriv.h @@ -17,11 +17,13 @@ #include "alfcompat.h" #include "alflayout.h" -extern TCHAR _alf_windowClass[]; extern TCHAR _alf_controlClass[]; void -ALF_RegisterWindowClass(void); +ALF_RegisterToplevelClass(void); + +void +ALF_UnregisterToplevelClass(void); void ALF_RegisterControlClass(void); diff --git a/alf/alfwindow.cpp b/alf/alftoplevel.cpp index f59e784..99f78e5 100644 --- a/alf/alfwindow.cpp +++ b/alf/alftoplevel.cpp @@ -1,23 +1,23 @@ #include "alfpriv.h" typedef struct { - ALFWindowVTable *vtbl; + ALFToplevelVTable *vtbl; void *closure; - int modalResult; + LPARAM modalResult; ALFLayout layout; HWND hwndFocus; HFONT hMessageFont; -} ALFWindowPriv; +} ALFToplevelPriv; -struct ALFWindow_CreateParams{ - ALFWindowVTable *vtbl; - void *closure; +struct ALFToplevel_CreateParams{ + ALFToplevelVTable *vtbl; + void *closure; }; -TCHAR _alf_windowClass[28] = {0}; +static TCHAR _alf_toplevelClass[28] = {0}; static void -ALF_InitializeWindowPriv(HWND hwnd, ALFWindowPriv *priv) +ALF_InitializeToplevelPriv(HWND hwnd, ALFToplevelPriv *priv) { (void)hwnd; @@ -26,7 +26,7 @@ ALF_InitializeWindowPriv(HWND hwnd, ALFWindowPriv *priv) } static void -ALF_DestroyWindowPriv(ALFWindowPriv *priv) +ALF_DestroyToplevelPriv(ALFToplevelPriv *priv) { if (priv->vtbl && priv->vtbl->postdestroy) priv->vtbl->postdestroy(priv->closure); @@ -40,7 +40,7 @@ ALF_DestroyWindowPriv(ALFWindowPriv *priv) } static void -ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv) +ALF_UpdateFontsPriv(HWND win, ALFToplevelPriv *priv) { // XXX: SystemParametersInfoForDpi is Unicode-only and needs Vista+ NONCLIENTMETRICS, ALF_NONCLIENTMETRICSW_VISTA ncm; @@ -75,7 +75,7 @@ ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv) /*static BOOL -ALF_PreTranslateMessagePriv(HWND win, ALFWindowPriv *priv, MSG *message) +ALF_PreTranslateMessagePriv(HWND win, ALFToplevelPriv *priv, MSG *message) { BOOL ret = FALSE; @@ -89,7 +89,7 @@ ALF_PreTranslateMessagePriv(HWND win, ALFWindowPriv *priv, MSG *message) }*/ void -ALF_EnsureWindowBigEnough(HWND toplevel) +ALF_Toplevel_EnsureBigEnough(HWND toplevel) { MINMAXINFO i; ZeroMemory(&i, sizeof(i)); @@ -113,7 +113,7 @@ ALF_EnsureWindowBigEnough(HWND toplevel) } static INT_PTR CALLBACK -ALF_Window_DlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +ALF_Toplevel_DlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { (void)hwnd; (void)msg; @@ -125,23 +125,23 @@ ALF_Window_DlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) static LRESULT CALLBACK -ALF_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +ALF_Toplevel_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { if (msg == WM_CREATE) { - ALFWindowPriv *priv = ALF_New(ALFWindowPriv, 1); + ALFToplevelPriv *priv = ALF_New(ALFToplevelPriv, 1); SetWindowLongPtr(hwnd, DLGWINDOWEXTRA, (LONG_PTR)priv); - ALF_InitializeWindowPriv(hwnd, priv); + ALF_InitializeToplevelPriv(hwnd, priv); int dpi = (int)ALF_Compat_GetDpiForWindow(hwnd); SendMessage(hwnd, ALF_WM_DPICHANGE, 0, (LPARAM)dpi); // will also update fonts } - ALFWindowPriv *priv = (ALFWindowPriv*)(void*)GetWindowLongPtr(hwnd, DLGWINDOWEXTRA); + ALFToplevelPriv *priv = (ALFToplevelPriv*)(void*)GetWindowLongPtr(hwnd, DLGWINDOWEXTRA); if (priv != NULL) { if (priv->vtbl && priv->vtbl->message) { return priv->vtbl->message(priv->closure, hwnd, msg, wparam, lparam); } else { - return ALF_DefWindowProc(hwnd, msg, wparam, lparam); + return ALF_Toplevel_DefWindowProc(hwnd, msg, wparam, lparam); } } else { return DefDlgProc(hwnd, msg, wparam, lparam); @@ -149,7 +149,7 @@ ALF_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) } static void -ALF_Window_Paint(ALFWindowPriv *priv, HWND hwnd, HDC dc, RECT *r) +ALF_Toplevel_Paint(ALFToplevelPriv *priv, HWND hwnd, HDC dc, RECT *r) { if (priv->vtbl && priv->vtbl->paint) { priv->vtbl->paint(priv->closure, hwnd, dc, r); @@ -159,12 +159,12 @@ ALF_Window_Paint(ALFWindowPriv *priv, HWND hwnd, HDC dc, RECT *r) } LRESULT -ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +ALF_Toplevel_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - ALFWindowPriv *priv = (ALFWindowPriv*)GetWindowLongPtr(hwnd, DLGWINDOWEXTRA); + ALFToplevelPriv *priv = (ALFToplevelPriv*)GetWindowLongPtr(hwnd, DLGWINDOWEXTRA); if (msg == WM_INITDIALOG) { - struct ALFWindow_CreateParams *params = (struct ALFWindow_CreateParams *)lparam; + struct ALFToplevel_CreateParams *params = (struct ALFToplevel_CreateParams *)lparam; priv->vtbl = params->vtbl; priv->closure = params->closure; @@ -174,7 +174,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) retval = priv->vtbl->initialize(priv->closure, hwnd); } - ALF_EnsureWindowBigEnough(hwnd); + ALF_Toplevel_EnsureBigEnough(hwnd); return retval; } @@ -183,7 +183,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) return (LRESULT)priv->modalResult; } if (msg == ALF_WM_SETMODALRESULT) { - priv->modalResult = (int)wparam; + priv->modalResult = lparam; return 0; } @@ -204,7 +204,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) RECT r = { 0, 0, 0, 0 }; GetClientRect(hwnd, &r); - ALF_Window_Paint(priv, hwnd, (HDC)wparam, &r); + ALF_Toplevel_Paint(priv, hwnd, (HDC)wparam, &r); return TRUE; } @@ -212,7 +212,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) PAINTSTRUCT ps; HDC dc = BeginPaint(hwnd, &ps); - ALF_Window_Paint(priv, hwnd, dc, &ps.rcPaint); + ALF_Toplevel_Paint(priv, hwnd, dc, &ps.rcPaint); EndPaint(hwnd, &ps); @@ -328,7 +328,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) if (msg == WM_NCDESTROY) { SetWindowLongPtr(hwnd, DLGWINDOWEXTRA, 0); - ALF_DestroyWindowPriv(priv); + ALF_DestroyToplevelPriv(priv); } if (msg == WM_DPICHANGED) { @@ -347,7 +347,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) } if (msg == WM_WINDOWPOSCHANGED) { - if (priv->vtbl->windowposchanged) { + if (priv->vtbl && priv->vtbl->windowposchanged) { priv->vtbl->windowposchanged(priv->closure, hwnd, (WINDOWPOS *)lparam); } } @@ -356,7 +356,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) if (ALF_Layout_HandleMessage(&priv->layout, hwnd, msg, wparam, lparam, &ret)) { // if the layout was changed, our current size might be too small if (msg == ALF_WM_VALIDATELAYOUT) { - ALF_EnsureWindowBigEnough(hwnd); + ALF_Toplevel_EnsureBigEnough(hwnd); } if (msg == ALF_WM_DPICHANGE) { @@ -370,21 +370,21 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) } void -ALF_RegisterWindowClass(void) +ALF_RegisterToplevelClass(void) { WNDCLASS cls; ZeroMemory(&cls, sizeof(cls)); - wsprintf(_alf_windowClass, TEXT("ALFWindow.%p"), (ULONG_PTR)&_alf_windowClass[0]); + wsprintf(_alf_toplevelClass, TEXT("ALFWindow.%p"), (ULONG_PTR)&_alf_toplevelClass[0]); cls.style = 0; cls.hInstance = ALF_HINSTANCE; cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW); cls.hbrBackground = NULL; - cls.lpszClassName = _alf_windowClass; + cls.lpszClassName = _alf_toplevelClass; cls.cbWndExtra = DLGWINDOWEXTRA + sizeof(void*); cls.cbClsExtra = 0; - cls.lpfnWndProc = ALF_WindowProc; + cls.lpfnWndProc = ALF_Toplevel_WindowProc; ATOM classatom = RegisterClass(&cls); if (!classatom) { @@ -392,8 +392,14 @@ ALF_RegisterWindowClass(void) } } +void +ALF_UnregisterToplevelClass(void) +{ + UnregisterClass(_alf_toplevelClass, ALF_HINSTANCE); +} + HWND -ALF_CreateToplevelWindow(HWND hwndParent, ALFWindowVTable *vtbl, void *closure) +ALF_CreateToplevelWindow(HWND hwndParent, ALFToplevelVTable *vtbl, void *closure) { #pragma pack(push, 1) struct { @@ -411,14 +417,89 @@ ALF_CreateToplevelWindow(HWND hwndParent, ALFWindowVTable *vtbl, void *closure) t.t.cdit = 0; // NOTE: this only works because we know the window class name is all ascii - for (int i = 0; _alf_windowClass[i]; ++i) { - t.s[i+1] = _alf_windowClass[i]; + for (int i = 0; _alf_toplevelClass[i]; ++i) { + t.s[i+1] = _alf_toplevelClass[i]; } - struct ALFWindow_CreateParams params; + struct ALFToplevel_CreateParams params; params.vtbl = vtbl; params.closure = closure; - return CreateDialogIndirectParam(ALF_HINSTANCE, &t.t, hwndParent, ALF_Window_DlgProc, (LPARAM)¶ms); + return CreateDialogIndirectParam(ALF_HINSTANCE, &t.t, hwndParent, ALF_Toplevel_DlgProc, (LPARAM)¶ms); } +void +ALF_Toplevel_SetDefaultButton(HWND win, WORD id) +{ + SendMessage(win, DM_SETDEFID, (WPARAM)id, 0); +} + +LPARAM +ALF_Toplevel_ShowModal(HWND win) +{ + MSG msg; + + ALF_Toplevel_SetModalResult(win, 0); + + // TODO: disable parent window + ShowWindow(win, SW_SHOW); + + while (GetMessage(&msg, NULL, 0, 0) > 0) { + // TODO: call application message hooks + // TODO: call preprocess message hook + + if (!IsDialogMessage(win, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + int mr = ALF_Toplevel_GetModalResult(win); + if (mr) + return mr; + } + + return 0; +} + +void +ALF_Toplevel_SetModalResult(HWND win, LPARAM result) +{ + SendMessage(win, ALF_WM_SETMODALRESULT, 0, result); +} + +LPARAM +ALF_Toplevel_GetModalResult(HWND win) +{ + return (LPARAM)SendMessage(win, ALF_WM_GETMODALRESULT, 0, 0); +} + +void +ALF_Toplevel_Resize(HWND win, int cptWidth, int cptHeight) +{ + int dpi = ALF_GetDpi(win); + + int pxwidth = ALF_CentipointsToPixels(cptWidth, dpi); + int pxheight = ALF_CentipointsToPixels(cptHeight, dpi); + + ALF_Toplevel_ResizePx(win, pxwidth, pxheight); +} + +void +ALF_Toplevel_ResizePx(HWND win, int pxwidth, int pxheight) +{ + MINMAXINFO tmp = { + { 0, 0 }, + { pxwidth, pxheight }, + { 0, 0 }, + { pxwidth, pxheight }, + { pxwidth, pxheight } + }; + SendMessage(win, WM_GETMINMAXINFO, 0, (LPARAM)&tmp); + + if (tmp.ptMinTrackSize.x > pxwidth) + pxwidth = tmp.ptMinTrackSize.x; + if (tmp.ptMinTrackSize.y > pxheight) + pxheight = tmp.ptMinTrackSize.y; + + SetWindowPos(win, NULL, 0, 0, pxwidth, pxheight, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER); +} diff --git a/widgetfactory.cpp b/widgetfactory.cpp index 69d0c48..c7f5f8d 100644 --- a/widgetfactory.cpp +++ b/widgetfactory.cpp @@ -827,7 +827,7 @@ WinMain } } - ALFWindowVTable vtbl; + ALFToplevelVTable vtbl; ZeroMemory(&vtbl, sizeof(vtbl)); vtbl.command = handleCommand; @@ -864,7 +864,7 @@ WinMain ALF_LayoutSetRowExpandNumerator(win, 1, 1); ALF_LayoutSetColumnExpandNumerator(win, 4, 1); - ALF_SetDefaultButton(win, ID_HELLO); + ALF_Toplevel_SetDefaultButton(win, ID_HELLO); ALF_SetFocus(GetNextDlgTabItem(win, win, FALSE)); HMENU mainmenu = CreateMenu(); @@ -896,10 +896,10 @@ WinMain SetMenu(win, mainmenu); - ALF_EnsureWindowBigEnough(win); - ALF_ShowModal(win); + ALF_Toplevel_EnsureBigEnough(win); + ALF_Toplevel_ShowModal(win); - ALF_DestroyWindow(win); + DestroyWindow(win); ALF_UnInitialize(); return 0; |
