summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.mingw7
-rw-r--r--Makefile.vc65
-rw-r--r--Makefile.vc6-ansi5
-rw-r--r--Makefile.vc6-ansi-315
-rw-r--r--Makefile.vc6-nt315
-rw-r--r--alf/alf.cpp427
-rw-r--r--alf/alfpriv.h20
-rw-r--r--alf/alfwindow.cpp439
8 files changed, 460 insertions, 453 deletions
diff --git a/Makefile.mingw b/Makefile.mingw
index e80648a..f3c52ed 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/alf.o out/alfdpiaware.o out/alfedit.o out/alflabel.o out/alflayout.o out/alfnotebook.o out/alfpanel.o
+out/widgetfactory.exe: out/widgetfactory.o out/alfbutton.o out/alfcombobox.o out/alfcompat.o out/alf.o out/alfdpiaware.o out/alfedit.o out/alflabel.o out/alflayout.o out/alfnotebook.o out/alfpanel.o out/alfwindow.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
@@ -41,10 +41,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
+ $(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/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfnotebook.cpp alf/alfpanel.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/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfwindow.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 8eea563..3f09e24 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/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.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
@@ -37,6 +37,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/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/widgetfactory.obj: widgetfactory.cpp alf/alf.h
$(CXX) $(CFLAGS) -c -Fo$@ widgetfactory.cpp
diff --git a/Makefile.vc6-ansi b/Makefile.vc6-ansi
index fb6b416..69a1d11 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 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/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.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
@@ -37,6 +37,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/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/widgetfactory.obj: widgetfactory.cpp alf/alf.h
$(CXX) $(CFLAGS) -c -Fo$@ widgetfactory.cpp
diff --git a/Makefile.vc6-ansi-31 b/Makefile.vc6-ansi-31
index 173e32c..3069c08 100644
--- a/Makefile.vc6-ansi-31
+++ b/Makefile.vc6-ansi-31
@@ -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 /subsystem:windows,3.10 /entry:_entry /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/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.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
@@ -37,6 +37,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/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/widgetfactory.obj: widgetfactory.cpp alf/alf.h
$(CXX) $(CFLAGS) -c -Fo$@ widgetfactory.cpp
diff --git a/Makefile.vc6-nt31 b/Makefile.vc6-nt31
index 85dd083..782ada0 100644
--- a/Makefile.vc6-nt31
+++ b/Makefile.vc6-nt31
@@ -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 /subsystem:windows,3.10 /entry:_entry 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/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.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
@@ -37,6 +37,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/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/widgetfactory.obj: widgetfactory.cpp alf/alf.h
$(CXX) $(CFLAGS) -c -Fo$@ widgetfactory.cpp
diff --git a/alf/alf.cpp b/alf/alf.cpp
index fc441bf..d40522f 100644
--- a/alf/alf.cpp
+++ b/alf/alf.cpp
@@ -5,37 +5,6 @@
static LONG _alf_initLock = 0;
static LONG _alf_initCounter = 0;
-/* ALF App and Window */
-
-static void
-ALF_InitializeWindowPriv(HWND hwnd, ALFWindowPriv *priv, void *closure)
-{
- priv->vtbl = (ALFWindowVTable*)GetClassLongPtr(hwnd, 0);
- priv->closure = closure;
- priv->defid = (WORD)-1;
- ALF_Layout_Init(&priv->layout);
-}
-
-static void
-ALF_DestroyWindowPriv(ALFWindowPriv *priv)
-{
- if (priv->vtbl->postdestroy)
- priv->vtbl->postdestroy(priv->closure);
-
- ALF_Layout_Clear(&priv->layout);
-
- if (priv->fonts.hMessageFont)
- DeleteObject(priv->fonts.hMessageFont);
-
- ALF_Free(priv);
-}
-
-int
-ALF_CentipointsToPxPriv(ALFWindowPriv *priv, int cptValue)
-{
- return MulDiv(cptValue, (int)priv->fonts.dpi, 7200);
-}
-
void
ALF_UpdateFonts(HWND win)
{
@@ -43,302 +12,11 @@ ALF_UpdateFonts(HWND win)
}
void
-ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv)
-{
- priv->fonts.dpi = ALF_Compat_GetDpiForWindow(win);
-
- // XXX: SystemParametersInfoForDpi is Unicode-only and needs Vista+ NONCLIENTMETRICS,
- ALF_NONCLIENTMETRICSW_VISTA ncm;
- ZeroMemory(&ncm, sizeof(ncm));
- ncm.cbSize = sizeof(ncm);
-
- if (ALF_Compat_SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, priv->fonts.dpi)) {
-#ifdef UNICODE
- priv->fonts.lfMessageFont = ncm.lfMessageFont;
-#else
- ALF_Compat_LogFontWtoA(&ncm.lfMessageFont, &priv->fonts.lfMessageFont);
-#endif
- } else {
- // FIXME! fallback to default font, 8pt MS Shell Dlg
- ZeroMemory(&priv->fonts.lfMessageFont, sizeof(priv->fonts.lfMessageFont));
-
- priv->fonts.lfMessageFont.lfHeight = -MulDiv(8, (int)priv->fonts.dpi, 72);
- lstrcpy(priv->fonts.lfMessageFont.lfFaceName, TEXT("MS Shell Dlg"));
- }
-
- if (priv->fonts.hMessageFont) {
- DeleteObject(priv->fonts.hMessageFont);
- }
- priv->fonts.hMessageFont = CreateFontIndirect(&priv->fonts.lfMessageFont);
-
- SendMessage(win, WM_SETFONT, (WPARAM)priv->fonts.hMessageFont, (LPARAM)1);
-}
-
-void
ALF_InvalidateLayout(HWND hwnd)
{
SendMessage(hwnd, ALF_WM_INVALIDATELAYOUT, 0, 0);
}
-static void
-ALF_ApplyFocus(HWND hwnd, ALFWindowPriv *priv, BOOL restoringFocus)
-{
- if (priv->hwndFocus) {
- if (!restoringFocus && SendMessage(priv->hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_HASSETSEL)
- SendMessage(priv->hwndFocus, EM_SETSEL, 0, -1);
-
- if (GetForegroundWindow() == hwnd) {
- HWND oldFocus = SetFocus(priv->hwndFocus);
-
- // FIXME! restore default button state
- if (oldFocus && SendMessage(oldFocus, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) {
- SendMessage(oldFocus, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
- }
-
- if (priv->defid != (WORD)-1) {
- HWND hwndOld = ALF_WidgetHwndById(hwnd, priv->defid);
- if (hwndOld && SendMessage(hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) {
- SendMessage(hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
- }
- }
-
- if (priv->hwndFocus && SendMessage(priv->hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_UNDEFPUSHBUTTON) {
- SendMessage(priv->hwndFocus, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
- } else {
- HWND hwndDef = ALF_WidgetHwndById(hwnd, priv->defid);
- if (hwndDef && SendMessage(hwndDef, WM_GETDLGCODE, 0, 0) & DLGC_UNDEFPUSHBUTTON) {
- SendMessage(hwndDef, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
- }
- }
- }
- } else {
- priv->hwndFocus = GetNextDlgTabItem(hwnd, NULL, FALSE);
- if (priv->hwndFocus)
- ALF_ApplyFocus(hwnd, priv, FALSE);
- }
-}
-
-LRESULT
-ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
-{
- ALFWindowPriv *priv = (ALFWindowPriv*)GetWindowLongPtr(hwnd, 0);
-
- if (msg == ALF_WM_GETMODALRESULT) {
- return (LRESULT)priv->modalResult;
- }
- if (msg == ALF_WM_SETMODALRESULT) {
- priv->modalResult = (int)wparam;
- return 0;
- }
-
- if (msg == ALF_WM_CENTIPOINTTOPX) {
- return (LRESULT)ALF_CentipointsToPxPriv(priv, (int)wparam);
- }
-
- if (msg == ALF_WM_SETFOCUS) {
- priv->hwndFocus = (HWND)lparam;
- ALF_ApplyFocus(hwnd, priv, FALSE);
- return 0;
- }
-
- if (msg == ALF_WM_UPDATEFONTS) {
- ALF_UpdateFontsPriv(hwnd, priv);
- return 0;
- }
-
- if (msg == WM_SETFONT) {
- priv->font = (HFONT)wparam;
- if (LOWORD(lparam) != 0)
- InvalidateRect(hwnd, NULL, TRUE);
-
- // fallthrough to layout, will propagate font to children
- }
-
- if (msg == WM_GETFONT) {
- return (LRESULT)priv->font;
- }
-
- if (msg == ALF_WM_PRETRANSLATEMSG) {
- return (LRESULT)ALF_PreTranslateMessagePriv(hwnd, priv, (MSG *)lparam);
- }
-
- if (msg == WM_COMMAND) {
- HWND source = (HWND)lparam;
- WORD code = HIWORD(wparam);
- WORD id = LOWORD(wparam);
- LRESULT ret = 0;
- if (source != 0)
- ret = SendMessage(source, 0x2000 + WM_COMMAND, wparam, lparam);
-
- if (ret == 0 && priv->vtbl->command)
- ret = priv->vtbl->command(priv->closure, hwnd, code, id, source);
-
- return ret;
- }
-
- if (msg == WM_NOTIFY) {
- NMHDR *nmhdr = (NMHDR *)lparam;
- LRESULT ret = 0;
-
- if (nmhdr->hwndFrom)
- ret = SendMessage(nmhdr->hwndFrom, 0x2000 + WM_NOTIFY, wparam, lparam);
-
- if (ret == 0 && priv->vtbl->notify)
- ret = priv->vtbl->notify(priv->closure, hwnd, wparam, nmhdr);
-
- return ret;
- }
-
- if (msg == WM_DRAWITEM) {
- LPDRAWITEMSTRUCT dis = (DRAWITEMSTRUCT *)lparam;
- LRESULT ret = 0;
- if (wparam && dis->hwndItem) {
- ret = SendMessage(dis->hwndItem, 0x2000 + WM_DRAWITEM, wparam, lparam);
- }
-
- if (ret)
- return ret;
- }
-
- if (msg == WM_ACTIVATE) {
- if (!HIWORD(wparam)) { // if !minimized
- if (LOWORD(wparam)) {
- ALF_ApplyFocus(hwnd, priv, TRUE);
- } else {
- priv->hwndFocus = GetFocus();
-
- // FIXME! remove default button state
- // there has to be a better way to do this
- if (priv->defid != (WORD)-1) {
- HWND hwndDefBtn = ALF_WidgetHwndById(hwnd, priv->defid);
- if (hwndDefBtn && SendMessage(hwndDefBtn, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) {
- SendMessage(hwndDefBtn, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
- }
- }
-
- if (priv->hwndFocus && SendMessage(priv->hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) {
- SendMessage(priv->hwndFocus, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
- }
- }
- }
- return 0;
- }
-
- if (msg == WM_SIZE) {
- ALF_Layout_Apply(&priv->layout, hwnd);
- }
-
- if (msg == WM_SHOWWINDOW) {
- if (wparam)
- ALF_Layout_Validate(&priv->layout, hwnd);
- }
-
- if (msg == WM_GETMINMAXINFO) {
- RECT tmp;
- ZeroMemory(&tmp, sizeof(tmp));
-
- SIZE s;
- ZeroMemory(&s, sizeof(s));
- ALF_Layout_GetMinSize(&priv->layout, hwnd, &s);
-
- tmp.right = s.cx;
- tmp.bottom = s.cy;
-
- if (ALF_Compat_AdjustWindowRectExForDpi(
- &tmp,
- (DWORD)GetWindowLong(hwnd, GWL_STYLE),
- GetMenu(hwnd) != NULL,
- (DWORD)GetWindowLong(hwnd, GWL_EXSTYLE),
- priv->fonts.dpi)) {
- MINMAXINFO *i = (MINMAXINFO *)lparam;
- i->ptMinTrackSize.x = tmp.right - tmp.left;
- i->ptMinTrackSize.y = tmp.bottom - tmp.top;
- return 0;
- }
- }
-
- if (msg == WM_CREATE) {
- ALF_UpdateFontsPriv(hwnd, priv);
- if (priv->vtbl->create) {
- priv->vtbl->create(priv->closure, hwnd);
- }
- BOOL alwaysUnderline = FALSE;
- SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &alwaysUnderline, 0);
- if (!alwaysUnderline) {
- SendMessage(hwnd, WM_UPDATEUISTATE, MAKEWPARAM(UIS_INITIALIZE, 0), 0);
- }
- ALF_Layout_Apply(&priv->layout, hwnd);
- }
-
- if (msg == WM_DESTROY && priv->vtbl->destroy) {
- priv->vtbl->destroy(priv->closure, hwnd);
- }
-
- if (msg == WM_CLOSE) {
- if (!priv->vtbl->close || !priv->vtbl->close(priv->closure, hwnd)) {
- priv->modalResult = 2;
- ShowWindow(hwnd, FALSE);
- }
- return TRUE;
- }
-
- if (msg == WM_NCDESTROY) {
- SetWindowLongPtr(hwnd, 0, 0);
- ALF_DestroyWindowPriv(priv);
- }
-
- if (msg == WM_DPICHANGED) {
- ALF_UpdateFontsPriv(hwnd, priv);
- ALF_Layout_Invalidate(&priv->layout, hwnd);
- RECT *r = (RECT*)lparam;
- SetWindowPos(hwnd, NULL, r->left, r->top, r->right-r->left, r->bottom-r->top, SWP_NOACTIVATE|SWP_NOZORDER);
- }
-
- if (msg == WM_THEMECHANGED || msg == WM_SETTINGCHANGE) {
- ALF_UpdateFontsPriv(hwnd, priv);
- ALF_Layout_Invalidate(&priv->layout, hwnd);
- }
-
- if (msg == DM_GETDEFID) {
- if (priv->defid == (WORD)-1) {
- return 0;
- } else {
- return MAKELONG(priv->defid, DC_HASDEFID);
- }
- }
- if (msg == DM_SETDEFID) {
- if (priv->defid != (WORD)-1) {
- HWND hwndOld = ALF_WidgetHwndById(hwnd, priv->defid);
- if (hwndOld && SendMessage(hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) {
- SendMessage(hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
- }
- }
-
- priv->defid = (WORD)wparam;
- HWND hwndNew = ALF_WidgetHwndById(hwnd, priv->defid);
- if (hwndNew && SendMessage(hwndNew, WM_GETDLGCODE, 0, 0) & DLGC_UNDEFPUSHBUTTON) {
- SendMessage(hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
- }
- return TRUE;
- }
-
- LRESULT ret = 0;
- if (ALF_Layout_HandleMessage(&priv->layout, hwnd, msg, wparam, lparam, &ret)) {
- // if the layout was changed, our current size might be too small
- // windows will call WM_GETMINMAXINFO and fix it
- if (msg == ALF_WM_VALIDATELAYOUT) {
- RECT r;
- if (GetWindowRect(hwnd, &r)) {
- SetWindowPos(hwnd, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER);
- }
- }
-
- return ret;
- }
-
- return DefWindowProc(hwnd, msg, wparam, lparam);
-}
-
void
ALF_AddWidget(HWND win, int x, int y, HWND widget, int minWidth, int minHeight, DWORD flags)
{
@@ -353,30 +31,6 @@ ALF_AddWidget(HWND win, int x, int y, HWND widget, int minWidth, int minHeight,
SendMessage(win, ALF_WM_ADDWIDGET, 0, (LPARAM)&params);
}
-static LRESULT CALLBACK
-ALF_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
-{
- if (msg == WM_NCCREATE) {
- CREATESTRUCT *cs = (CREATESTRUCT*)(void*)lparam;
- if (cs->lpCreateParams) {
- ALFWindowPriv *priv = ALF_New(ALFWindowPriv, 1);
- SetWindowLongPtr(hwnd, 0, (LONG_PTR)priv);
- ALF_InitializeWindowPriv(hwnd, priv, *((void**)cs->lpCreateParams));
- }
- }
-
- ALFWindowPriv *priv = (ALFWindowPriv*)(void*)GetWindowLongPtr(hwnd, 0);
- if (priv != NULL) {
- if (priv->vtbl->message) {
- return priv->vtbl->message(priv->closure, hwnd, msg, wparam, lparam);
- } else {
- return ALF_DefWindowProc(hwnd, msg, wparam, lparam);
- }
- } else {
- return DefWindowProc(hwnd, msg, wparam, lparam);
- }
-}
-
void
ALF_Initialize(void)
{
@@ -467,73 +121,6 @@ ALF_BuildUniqueName(TCHAR *buf, const TCHAR *prefix, ULONG_PTR uniquifier)
buf[prefixlen + numlen] = 0;
}
-LPTSTR
-ALF_RegisterWindowClass(HINSTANCE hInstance, const ALFWindowClassParams *params)
-{
- WNDCLASS cls;
- ZeroMemory(&cls, sizeof(cls));
-
- ALFWindowVTable *pvtbl = ALF_New(ALFWindowVTable, 1);
- *pvtbl = params->vtbl;
-
- const TCHAR *classNamePtr = params->className;
- TCHAR classNameBuf[256];
- if (!classNamePtr) {
- ZeroMemory(classNameBuf, sizeof(classNameBuf));
- classNamePtr = classNameBuf;
-
- ALF_BuildUniqueName(classNameBuf, TEXT("ALFWindow."), (ULONG_PTR)pvtbl);
- }
-
- cls.style = params->classStyle;
- cls.hInstance = hInstance;
- cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW);
- cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
- cls.lpszClassName = classNamePtr;
- cls.cbWndExtra = sizeof(void*);
- cls.cbClsExtra = sizeof(void*);
- cls.lpfnWndProc = ALF_WindowProc;
-
- ATOM classatom = RegisterClass(&cls);
- if (!classatom) {
- ALF_Free(pvtbl);
- return NULL;
- }
-
- // XXX: This could have been a HWND_MESSAGE window, but Win95 doesn't support these
- HWND tmp = CreateWindowEx(0, MAKEINTATOM(classatom), TEXT("dummy"), 0, 0, 0, 0, 0, NULL, 0, hInstance, 0);
- SetClassLongPtr(tmp, 0, (LONG_PTR)pvtbl);
- DestroyWindow(tmp);
-
- return MAKEINTATOM(classatom);
-}
-
-void
-ALF_UnregisterWindowClass(HINSTANCE hinstance, LPCTSTR className)
-{
- HWND tmp = CreateWindowEx(0, className, TEXT("dummy"), 0, 0, 0, 0, 0, NULL, 0, hinstance, 0);
- ALFWindowVTable *pvtbl = (ALFWindowVTable*)GetClassLongPtr(tmp, 0);
- DestroyWindow(tmp);
-
- ALF_Free(pvtbl);
-
- UnregisterClass(className, hinstance);
-}
-
-HWND ALF_InstantiateWindow(HINSTANCE hinstance, LPCTSTR className, HWND hwndParent, void *closure)
-{
- return CreateWindowEx(0,
- className,
- TEXT("Window"),
- WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
- CW_USEDEFAULT, CW_USEDEFAULT,
- 300, 100, //FIXME
- hwndParent,
- NULL,
- hinstance,
- &closure);
-}
-
void
ALF_DestroyWindow(HWND win)
{
@@ -546,20 +133,6 @@ ALF_PreTranslateMessage(HWND hwnd, MSG *message)
return (BOOL)SendMessage(hwnd, ALF_WM_PRETRANSLATEMSG, 0, (LPARAM)message);
}
-BOOL
-ALF_PreTranslateMessagePriv(HWND win, ALFWindowPriv *priv, MSG *message)
-{
- BOOL ret = FALSE;
-
- if (priv->vtbl->pretranslatemessage)
- ret = priv->vtbl->pretranslatemessage(priv->closure, win, message);
-
- if (!ret)
- ret = IsDialogMessage(win, message);
-
- return ret;
-}
-
int
ALF_ShowModal(HWND win)
{
diff --git a/alf/alfpriv.h b/alf/alfpriv.h
index a145f8f..d539baf 100644
--- a/alf/alfpriv.h
+++ b/alf/alfpriv.h
@@ -17,31 +17,11 @@
#include "alfcompat.h"
#include "alflayout.h"
-typedef struct {
- ALFWindowVTable *vtbl;
- void *closure;
- ALFWindowFonts fonts;
- int modalResult;
- ALFLayout layout;
- WORD defid;
- HWND hwndFocus;
- HFONT font;
-} ALFWindowPriv;
-
extern TCHAR *_alf_comboClass;
extern TCHAR *_alf_panelClass;
extern TCHAR *_alf_labelClass;
extern TCHAR *_alf_notebookClass;
-int
-ALF_CentipointsToPxPriv(ALFWindowPriv *priv, int cptValue);
-
-void
-ALF_UpdateFontsPriv(HWND hwnd, ALFWindowPriv *priv);
-
-BOOL
-ALF_PreTranslateMessagePriv(HWND win, ALFWindowPriv *priv, MSG *message);
-
void
ALF_RegisterComboClass(void);
diff --git a/alf/alfwindow.cpp b/alf/alfwindow.cpp
new file mode 100644
index 0000000..0b395b6
--- /dev/null
+++ b/alf/alfwindow.cpp
@@ -0,0 +1,439 @@
+#include "alfpriv.h"
+
+typedef struct {
+ ALFWindowVTable *vtbl;
+ void *closure;
+ ALFWindowFonts fonts;
+ int modalResult;
+ ALFLayout layout;
+ WORD defid;
+ HWND hwndFocus;
+ HFONT font;
+} ALFWindowPriv;
+
+static void
+ALF_InitializeWindowPriv(HWND hwnd, ALFWindowPriv *priv, void *closure)
+{
+ priv->vtbl = (ALFWindowVTable*)GetClassLongPtr(hwnd, 0);
+ priv->closure = closure;
+ priv->defid = (WORD)-1;
+ ALF_Layout_Init(&priv->layout);
+}
+
+static void
+ALF_DestroyWindowPriv(ALFWindowPriv *priv)
+{
+ if (priv->vtbl->postdestroy)
+ priv->vtbl->postdestroy(priv->closure);
+
+ ALF_Layout_Clear(&priv->layout);
+
+ if (priv->fonts.hMessageFont)
+ DeleteObject(priv->fonts.hMessageFont);
+
+ ALF_Free(priv);
+}
+
+static void
+ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv)
+{
+ priv->fonts.dpi = ALF_Compat_GetDpiForWindow(win);
+
+ // XXX: SystemParametersInfoForDpi is Unicode-only and needs Vista+ NONCLIENTMETRICS,
+ ALF_NONCLIENTMETRICSW_VISTA ncm;
+ ZeroMemory(&ncm, sizeof(ncm));
+ ncm.cbSize = sizeof(ncm);
+
+ if (ALF_Compat_SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, priv->fonts.dpi)) {
+#ifdef UNICODE
+ priv->fonts.lfMessageFont = ncm.lfMessageFont;
+#else
+ ALF_Compat_LogFontWtoA(&ncm.lfMessageFont, &priv->fonts.lfMessageFont);
+#endif
+ } else {
+ // FIXME! fallback to default font, 8pt MS Shell Dlg
+ ZeroMemory(&priv->fonts.lfMessageFont, sizeof(priv->fonts.lfMessageFont));
+
+ priv->fonts.lfMessageFont.lfHeight = -MulDiv(8, (int)priv->fonts.dpi, 72);
+ lstrcpy(priv->fonts.lfMessageFont.lfFaceName, TEXT("MS Shell Dlg"));
+ }
+
+ if (priv->fonts.hMessageFont) {
+ DeleteObject(priv->fonts.hMessageFont);
+ }
+ priv->fonts.hMessageFont = CreateFontIndirect(&priv->fonts.lfMessageFont);
+
+ SendMessage(win, WM_SETFONT, (WPARAM)priv->fonts.hMessageFont, (LPARAM)1);
+}
+
+static int
+ALF_CentipointsToPxPriv(ALFWindowPriv *priv, int cptValue)
+{
+ return MulDiv(cptValue, (int)priv->fonts.dpi, 7200);
+}
+
+static void
+ALF_ApplyFocus(HWND hwnd, ALFWindowPriv *priv, BOOL restoringFocus)
+{
+ if (priv->hwndFocus) {
+ if (!restoringFocus && SendMessage(priv->hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_HASSETSEL)
+ SendMessage(priv->hwndFocus, EM_SETSEL, 0, -1);
+
+ if (GetForegroundWindow() == hwnd) {
+ HWND oldFocus = SetFocus(priv->hwndFocus);
+
+ // FIXME! restore default button state
+ if (oldFocus && SendMessage(oldFocus, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) {
+ SendMessage(oldFocus, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
+ }
+
+ if (priv->defid != (WORD)-1) {
+ HWND hwndOld = ALF_WidgetHwndById(hwnd, priv->defid);
+ if (hwndOld && SendMessage(hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) {
+ SendMessage(hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
+ }
+ }
+
+ if (priv->hwndFocus && SendMessage(priv->hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_UNDEFPUSHBUTTON) {
+ SendMessage(priv->hwndFocus, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
+ } else {
+ HWND hwndDef = ALF_WidgetHwndById(hwnd, priv->defid);
+ if (hwndDef && SendMessage(hwndDef, WM_GETDLGCODE, 0, 0) & DLGC_UNDEFPUSHBUTTON) {
+ SendMessage(hwndDef, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
+ }
+ }
+ }
+ } else {
+ priv->hwndFocus = GetNextDlgTabItem(hwnd, NULL, FALSE);
+ if (priv->hwndFocus)
+ ALF_ApplyFocus(hwnd, priv, FALSE);
+ }
+}
+
+static BOOL
+ALF_PreTranslateMessagePriv(HWND win, ALFWindowPriv *priv, MSG *message)
+{
+ BOOL ret = FALSE;
+
+ if (priv->vtbl->pretranslatemessage)
+ ret = priv->vtbl->pretranslatemessage(priv->closure, win, message);
+
+ if (!ret)
+ ret = IsDialogMessage(win, message);
+
+ return ret;
+}
+
+static LRESULT CALLBACK
+ALF_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ if (msg == WM_NCCREATE) {
+ CREATESTRUCT *cs = (CREATESTRUCT*)(void*)lparam;
+ if (cs->lpCreateParams) {
+ ALFWindowPriv *priv = ALF_New(ALFWindowPriv, 1);
+ SetWindowLongPtr(hwnd, 0, (LONG_PTR)priv);
+ ALF_InitializeWindowPriv(hwnd, priv, *((void**)cs->lpCreateParams));
+ }
+ }
+
+ ALFWindowPriv *priv = (ALFWindowPriv*)(void*)GetWindowLongPtr(hwnd, 0);
+ if (priv != NULL) {
+ if (priv->vtbl->message) {
+ return priv->vtbl->message(priv->closure, hwnd, msg, wparam, lparam);
+ } else {
+ return ALF_DefWindowProc(hwnd, msg, wparam, lparam);
+ }
+ } else {
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ }
+}
+
+LRESULT
+ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ ALFWindowPriv *priv = (ALFWindowPriv*)GetWindowLongPtr(hwnd, 0);
+
+ if (msg == ALF_WM_GETMODALRESULT) {
+ return (LRESULT)priv->modalResult;
+ }
+ if (msg == ALF_WM_SETMODALRESULT) {
+ priv->modalResult = (int)wparam;
+ return 0;
+ }
+
+ if (msg == ALF_WM_CENTIPOINTTOPX) {
+ return (LRESULT)ALF_CentipointsToPxPriv(priv, (int)wparam);
+ }
+
+ if (msg == ALF_WM_SETFOCUS) {
+ priv->hwndFocus = (HWND)lparam;
+ ALF_ApplyFocus(hwnd, priv, FALSE);
+ return 0;
+ }
+
+ if (msg == ALF_WM_UPDATEFONTS) {
+ ALF_UpdateFontsPriv(hwnd, priv);
+ return 0;
+ }
+
+ if (msg == WM_SETFONT) {
+ priv->font = (HFONT)wparam;
+ if (LOWORD(lparam) != 0)
+ InvalidateRect(hwnd, NULL, TRUE);
+
+ // fallthrough to layout, will propagate font to children
+ }
+
+ if (msg == WM_GETFONT) {
+ return (LRESULT)priv->font;
+ }
+
+ if (msg == ALF_WM_PRETRANSLATEMSG) {
+ return (LRESULT)ALF_PreTranslateMessagePriv(hwnd, priv, (MSG *)lparam);
+ }
+
+ if (msg == WM_COMMAND) {
+ HWND source = (HWND)lparam;
+ WORD code = HIWORD(wparam);
+ WORD id = LOWORD(wparam);
+ LRESULT ret = 0;
+ if (source != 0)
+ ret = SendMessage(source, 0x2000 + WM_COMMAND, wparam, lparam);
+
+ if (ret == 0 && priv->vtbl->command)
+ ret = priv->vtbl->command(priv->closure, hwnd, code, id, source);
+
+ return ret;
+ }
+
+ if (msg == WM_NOTIFY) {
+ NMHDR *nmhdr = (NMHDR *)lparam;
+ LRESULT ret = 0;
+
+ if (nmhdr->hwndFrom)
+ ret = SendMessage(nmhdr->hwndFrom, 0x2000 + WM_NOTIFY, wparam, lparam);
+
+ if (ret == 0 && priv->vtbl->notify)
+ ret = priv->vtbl->notify(priv->closure, hwnd, wparam, nmhdr);
+
+ return ret;
+ }
+
+ if (msg == WM_DRAWITEM) {
+ LPDRAWITEMSTRUCT dis = (DRAWITEMSTRUCT *)lparam;
+ LRESULT ret = 0;
+ if (wparam && dis->hwndItem) {
+ ret = SendMessage(dis->hwndItem, 0x2000 + WM_DRAWITEM, wparam, lparam);
+ }
+
+ if (ret)
+ return ret;
+ }
+
+ if (msg == WM_ACTIVATE) {
+ if (!HIWORD(wparam)) { // if !minimized
+ if (LOWORD(wparam)) {
+ ALF_ApplyFocus(hwnd, priv, TRUE);
+ } else {
+ priv->hwndFocus = GetFocus();
+
+ // FIXME! remove default button state
+ // there has to be a better way to do this
+ if (priv->defid != (WORD)-1) {
+ HWND hwndDefBtn = ALF_WidgetHwndById(hwnd, priv->defid);
+ if (hwndDefBtn && SendMessage(hwndDefBtn, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) {
+ SendMessage(hwndDefBtn, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
+ }
+ }
+
+ if (priv->hwndFocus && SendMessage(priv->hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) {
+ SendMessage(priv->hwndFocus, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
+ }
+ }
+ }
+ return 0;
+ }
+
+ if (msg == WM_SIZE) {
+ ALF_Layout_Apply(&priv->layout, hwnd);
+ }
+
+ if (msg == WM_SHOWWINDOW) {
+ if (wparam)
+ ALF_Layout_Validate(&priv->layout, hwnd);
+ }
+
+ if (msg == WM_GETMINMAXINFO) {
+ RECT tmp;
+ ZeroMemory(&tmp, sizeof(tmp));
+
+ SIZE s;
+ ZeroMemory(&s, sizeof(s));
+ ALF_Layout_GetMinSize(&priv->layout, hwnd, &s);
+
+ tmp.right = s.cx;
+ tmp.bottom = s.cy;
+
+ if (ALF_Compat_AdjustWindowRectExForDpi(
+ &tmp,
+ (DWORD)GetWindowLong(hwnd, GWL_STYLE),
+ GetMenu(hwnd) != NULL,
+ (DWORD)GetWindowLong(hwnd, GWL_EXSTYLE),
+ priv->fonts.dpi)) {
+ MINMAXINFO *i = (MINMAXINFO *)lparam;
+ i->ptMinTrackSize.x = tmp.right - tmp.left;
+ i->ptMinTrackSize.y = tmp.bottom - tmp.top;
+ return 0;
+ }
+ }
+
+ if (msg == WM_CREATE) {
+ ALF_UpdateFontsPriv(hwnd, priv);
+ if (priv->vtbl->create) {
+ priv->vtbl->create(priv->closure, hwnd);
+ }
+ BOOL alwaysUnderline = FALSE;
+ SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &alwaysUnderline, 0);
+ if (!alwaysUnderline) {
+ SendMessage(hwnd, WM_UPDATEUISTATE, MAKEWPARAM(UIS_INITIALIZE, 0), 0);
+ }
+ ALF_Layout_Apply(&priv->layout, hwnd);
+ }
+
+ if (msg == WM_DESTROY && priv->vtbl->destroy) {
+ priv->vtbl->destroy(priv->closure, hwnd);
+ }
+
+ if (msg == WM_CLOSE) {
+ if (!priv->vtbl->close || !priv->vtbl->close(priv->closure, hwnd)) {
+ priv->modalResult = 2;
+ ShowWindow(hwnd, FALSE);
+ }
+ return TRUE;
+ }
+
+ if (msg == WM_NCDESTROY) {
+ SetWindowLongPtr(hwnd, 0, 0);
+ ALF_DestroyWindowPriv(priv);
+ }
+
+ if (msg == WM_DPICHANGED) {
+ ALF_UpdateFontsPriv(hwnd, priv);
+ ALF_Layout_Invalidate(&priv->layout, hwnd);
+ RECT *r = (RECT*)lparam;
+ SetWindowPos(hwnd, NULL, r->left, r->top, r->right-r->left, r->bottom-r->top, SWP_NOACTIVATE|SWP_NOZORDER);
+ }
+
+ if (msg == WM_THEMECHANGED || msg == WM_SETTINGCHANGE) {
+ ALF_UpdateFontsPriv(hwnd, priv);
+ ALF_Layout_Invalidate(&priv->layout, hwnd);
+ }
+
+ if (msg == DM_GETDEFID) {
+ if (priv->defid == (WORD)-1) {
+ return 0;
+ } else {
+ return MAKELONG(priv->defid, DC_HASDEFID);
+ }
+ }
+ if (msg == DM_SETDEFID) {
+ if (priv->defid != (WORD)-1) {
+ HWND hwndOld = ALF_WidgetHwndById(hwnd, priv->defid);
+ if (hwndOld && SendMessage(hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) {
+ SendMessage(hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
+ }
+ }
+
+ priv->defid = (WORD)wparam;
+ HWND hwndNew = ALF_WidgetHwndById(hwnd, priv->defid);
+ if (hwndNew && SendMessage(hwndNew, WM_GETDLGCODE, 0, 0) & DLGC_UNDEFPUSHBUTTON) {
+ SendMessage(hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
+ }
+ return TRUE;
+ }
+
+ LRESULT ret = 0;
+ if (ALF_Layout_HandleMessage(&priv->layout, hwnd, msg, wparam, lparam, &ret)) {
+ // if the layout was changed, our current size might be too small
+ // windows will call WM_GETMINMAXINFO and fix it
+ if (msg == ALF_WM_VALIDATELAYOUT) {
+ RECT r;
+ if (GetWindowRect(hwnd, &r)) {
+ SetWindowPos(hwnd, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER);
+ }
+ }
+
+ return ret;
+ }
+
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+LPTSTR
+ALF_RegisterWindowClass(HINSTANCE hInstance, const ALFWindowClassParams *params)
+{
+ WNDCLASS cls;
+ ZeroMemory(&cls, sizeof(cls));
+
+ ALFWindowVTable *pvtbl = ALF_New(ALFWindowVTable, 1);
+ *pvtbl = params->vtbl;
+
+ const TCHAR *classNamePtr = params->className;
+ TCHAR classNameBuf[256];
+ if (!classNamePtr) {
+ ZeroMemory(classNameBuf, sizeof(classNameBuf));
+ classNamePtr = classNameBuf;
+
+ ALF_BuildUniqueName(classNameBuf, TEXT("ALFWindow."), (ULONG_PTR)pvtbl);
+ }
+
+ cls.style = params->classStyle;
+ cls.hInstance = hInstance;
+ cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW);
+ cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
+ cls.lpszClassName = classNamePtr;
+ cls.cbWndExtra = sizeof(void*);
+ cls.cbClsExtra = sizeof(void*);
+ cls.lpfnWndProc = ALF_WindowProc;
+
+ ATOM classatom = RegisterClass(&cls);
+ if (!classatom) {
+ ALF_Free(pvtbl);
+ return NULL;
+ }
+
+ // XXX: This could have been a HWND_MESSAGE window, but Win95 doesn't support these
+ HWND tmp = CreateWindowEx(0, MAKEINTATOM(classatom), TEXT("dummy"), 0, 0, 0, 0, 0, NULL, 0, hInstance, 0);
+ SetClassLongPtr(tmp, 0, (LONG_PTR)pvtbl);
+ DestroyWindow(tmp);
+
+ return MAKEINTATOM(classatom);
+}
+
+void
+ALF_UnregisterWindowClass(HINSTANCE hinstance, LPCTSTR className)
+{
+ HWND tmp = CreateWindowEx(0, className, TEXT("dummy"), 0, 0, 0, 0, 0, NULL, 0, hinstance, 0);
+ ALFWindowVTable *pvtbl = (ALFWindowVTable*)GetClassLongPtr(tmp, 0);
+ DestroyWindow(tmp);
+
+ ALF_Free(pvtbl);
+
+ UnregisterClass(className, hinstance);
+}
+
+HWND ALF_InstantiateWindow(HINSTANCE hinstance, LPCTSTR className, HWND hwndParent, void *closure)
+{
+ return CreateWindowEx(0,
+ className,
+ TEXT("Window"),
+ WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 300, 100, //FIXME
+ hwndParent,
+ NULL,
+ hinstance,
+ &closure);
+}
+
+