summaryrefslogtreecommitdiff
path: root/alf
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2020-05-30 16:16:50 +0200
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2020-05-30 16:17:38 +0200
commit379e9fd3a72fbf5f136443284bc6a2d81bb828fa (patch)
tree74c0874be87dd342e7baf36a60b60b1c8f49f9ce /alf
parentf9cfbb8870a023478d52fd03c90abcbed9c49304 (diff)
toplevel: rename and reorganize functions
Diffstat (limited to 'alf')
-rw-r--r--alf/alf.cpp82
-rw-r--r--alf/alf.h148
-rw-r--r--alf/alfbutton.cpp6
-rw-r--r--alf/alfpriv.h6
-rw-r--r--alf/alftoplevel.cpp (renamed from alf/alfwindow.cpp)157
5 files changed, 207 insertions, 192 deletions
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;
diff --git a/alf/alf.h b/alf/alf.h
index aab0f00..cb2e48e 100644
--- a/alf/alf.h
+++ b/alf/alf.h
@@ -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)&params);
+ return CreateDialogIndirectParam(ALF_HINSTANCE, &t.t, hwndParent, ALF_Toplevel_DlgProc, (LPARAM)&params);
}
+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);
+}