summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--alf/alf.h4
-rw-r--r--alf/alftoplevel.cpp87
-rw-r--r--widgetfactory.cpp80
3 files changed, 131 insertions, 40 deletions
diff --git a/alf/alf.h b/alf/alf.h
index cb2e48e..6f42f35 100644
--- a/alf/alf.h
+++ b/alf/alf.h
@@ -10,7 +10,7 @@ extern "C" {
typedef struct {
BOOL (*initialize)(void * /*closure*/, HWND /*window*/); // return FALSE if you set the focus, TRUE if you want default initial focus
void (*destroy)(void * /*closure*/, HWND /*window*/);
- BOOL (*close)(void * /*closure*/, HWND /*window*/);
+ void (*close)(void * /*closure*/, HWND /*window*/);
void (*postdestroy)(void * /*closure*/);
LRESULT (*message)(void * /*closure*/, HWND, UINT, WPARAM, LPARAM);
LRESULT (*command)(void * /*closure*/, HWND /*window*/, WORD /*notificationcode*/, WORD /*sourceid*/, HWND /*control*/);
@@ -304,7 +304,7 @@ ALF_DestroyWidget(HWND win, WORD id);
// toplevel window
HWND
-ALF_CreateToplevelWindow(HWND hwndParent, ALFToplevelVTable *vtbl, void *closure);
+ALF_CreateToplevelWindow(DWORD exstyle, DWORD style, HWND hwndOwner, ALFToplevelVTable *vtbl, void *closure);
void
ALF_Toplevel_Resize(HWND win, int cptWidth, int cptHeight);
diff --git a/alf/alftoplevel.cpp b/alf/alftoplevel.cpp
index 99f78e5..161a738 100644
--- a/alf/alftoplevel.cpp
+++ b/alf/alftoplevel.cpp
@@ -1,8 +1,11 @@
#include "alfpriv.h"
+#define ALF_TOPLEVEL_FLAG_MODALEND ((DWORD)1)
+
typedef struct {
ALFToplevelVTable *vtbl;
void *closure;
+ DWORD flags;
LPARAM modalResult;
ALFLayout layout;
HWND hwndFocus;
@@ -74,19 +77,14 @@ ALF_UpdateFontsPriv(HWND win, ALFToplevelPriv *priv)
}
-/*static BOOL
-ALF_PreTranslateMessagePriv(HWND win, ALFToplevelPriv *priv, MSG *message)
+BOOL
+ALF_Toplevel_PreTranslateMessage(HWND toplevel, MSG *message)
{
- BOOL ret = FALSE;
-
- if (priv->vtbl->pretranslatemessage)
- ret = priv->vtbl->pretranslatemessage(priv->closure, win, message);
+ ALFToplevelPriv *priv = (ALFToplevelPriv *)GetWindowLongPtr(toplevel, DLGWINDOWEXTRA);
- if (!ret)
- ret = IsDialogMessage(win, message);
-
- return ret;
-}*/
+ return (priv->vtbl && priv->vtbl->pretranslatemessage && priv->vtbl->pretranslatemessage(priv->closure, toplevel, message))
+ || IsDialogMessage(toplevel, message);
+}
void
ALF_Toplevel_EnsureBigEnough(HWND toplevel)
@@ -184,6 +182,7 @@ ALF_Toplevel_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
}
if (msg == ALF_WM_SETMODALRESULT) {
priv->modalResult = lparam;
+ priv->flags |= ALF_TOPLEVEL_FLAG_MODALEND;
return 0;
}
@@ -319,11 +318,10 @@ ALF_Toplevel_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
}
if (msg == WM_CLOSE) {
- if (!priv->vtbl || !priv->vtbl->close || !priv->vtbl->close(priv->closure, hwnd)) {
- priv->modalResult = 2;
- ShowWindow(hwnd, FALSE);
- }
- return TRUE;
+ if (priv->vtbl && priv->vtbl->close)
+ priv->vtbl->close(priv->closure, hwnd);
+
+ return 0;
}
if (msg == WM_NCDESTROY) {
@@ -399,7 +397,7 @@ ALF_UnregisterToplevelClass(void)
}
HWND
-ALF_CreateToplevelWindow(HWND hwndParent, ALFToplevelVTable *vtbl, void *closure)
+ALF_CreateToplevelWindow(DWORD exstyle, DWORD style, HWND hwndOwner, ALFToplevelVTable *vtbl, void *closure)
{
#pragma pack(push, 1)
struct {
@@ -408,8 +406,8 @@ ALF_CreateToplevelWindow(HWND hwndParent, ALFToplevelVTable *vtbl, void *closure
} t;
#pragma pack(pop)
ZeroMemory(&t, sizeof(t));
- t.t.style = WS_OVERLAPPEDWINDOW;
- t.t.dwExtendedStyle = 0;
+ t.t.style = style;
+ t.t.dwExtendedStyle = exstyle;
t.t.x = 0;
t.t.y = 0;
t.t.cx = 10;
@@ -421,10 +419,16 @@ ALF_CreateToplevelWindow(HWND hwndParent, ALFToplevelVTable *vtbl, void *closure
t.s[i+1] = _alf_toplevelClass[i];
}
+ if (hwndOwner == GetDesktopWindow())
+ hwndOwner = NULL;
+
+ if (hwndOwner && GetWindowLong(hwndOwner, GWL_STYLE) & WS_CHILD)
+ hwndOwner = GetParent(hwndOwner);
+
struct ALFToplevel_CreateParams params;
params.vtbl = vtbl;
params.closure = closure;
- return CreateDialogIndirectParam(ALF_HINSTANCE, &t.t, hwndParent, ALF_Toplevel_DlgProc, (LPARAM)&params);
+ return CreateDialogIndirectParam(ALF_HINSTANCE, &t.t, hwndOwner, ALF_Toplevel_DlgProc, (LPARAM)&params);
}
void
@@ -434,30 +438,41 @@ ALF_Toplevel_SetDefaultButton(HWND win, WORD id)
}
LPARAM
-ALF_Toplevel_ShowModal(HWND win)
+ALF_Toplevel_ShowModal(HWND toplevel)
{
- MSG msg;
+ ALFToplevelPriv *priv = (ALFToplevelPriv *)GetWindowLongPtr(toplevel, DLGWINDOWEXTRA);
- ALF_Toplevel_SetModalResult(win, 0);
+ priv->flags &= ~ALF_TOPLEVEL_FLAG_MODALEND;
+ priv->modalResult = 0;
- // TODO: disable parent window
- ShowWindow(win, SW_SHOW);
+ HWND owner = GetWindow(toplevel, GW_OWNER);
+ BOOL ownerEnabled = FALSE;
- while (GetMessage(&msg, NULL, 0, 0) > 0) {
- // TODO: call application message hooks
- // TODO: call preprocess message hook
+ ShowWindow(toplevel, SW_SHOW);
- if (!IsDialogMessage(win, &msg)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
+ if (owner)
+ ownerEnabled = !EnableWindow(owner, FALSE);
- int mr = ALF_Toplevel_GetModalResult(win);
- if (mr)
- return mr;
+ while (!(priv->flags & ALF_TOPLEVEL_FLAG_MODALEND)) {
+ MSG msg;
+ if (GetMessage(&msg, NULL, 0, 0)) {
+ // TODO: call app-level message filter
+ if (!ALF_Toplevel_PreTranslateMessage(toplevel, &msg)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ } else {
+ PostQuitMessage((int)msg.wParam);
+ break;
+ }
}
- return 0;
+ if (owner)
+ EnableWindow(owner, ownerEnabled);
+
+ ShowWindow(toplevel, SW_HIDE);
+
+ return priv->modalResult;
}
diff --git a/widgetfactory.cpp b/widgetfactory.cpp
index c7f5f8d..060544b 100644
--- a/widgetfactory.cpp
+++ b/widgetfactory.cpp
@@ -38,7 +38,9 @@ enum {
IDM_BACKGROUND_GREEN,
IDM_BACKGROUND_BLUE,
IDM_PANES,
- IDM_PANES__MAX = IDM_PANES + PANE__MAX
+ IDM_PANES__MAX = IDM_PANES + PANE__MAX,
+ IDM_MODALDIALOG_PANES,
+ IDM_MODALDIALOG_PANES__MAX = IDM_MODALDIALOG_PANES + PANE__MAX
};
BOOL (WINAPI *fnGradientFill)(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG) = NULL;
@@ -52,6 +54,8 @@ enum PanelBackgroundMode {
#define FM_PANEL_SET_BGMODE (ALF_WM_USER + 1)
+static void wfModalDialogRun(HWND owner, int pane);
+
/* common stuff */
typedef struct {
DWORD bgmode;
@@ -740,6 +744,14 @@ addPaneToNotebook(HWND hwndNotebook, int paneId)
g_paneInitTable[paneId](panel);
}
+static void
+handleClose(void *closure, HWND window)
+{
+ (void)closure;
+
+ ALF_Toplevel_SetModalResult(window, 0);
+}
+
static LRESULT
handleCommand(void *closure, HWND window, WORD notificationcode, WORD sourceid, HWND control)
{
@@ -802,9 +814,67 @@ handleCommand(void *closure, HWND window, WORD notificationcode, WORD sourceid,
addPaneToNotebook(nb, paneId);
}
+ if (sourceid >= IDM_MODALDIALOG_PANES && sourceid < IDM_MODALDIALOG_PANES__MAX) {
+ int paneId = sourceid - IDM_MODALDIALOG_PANES;
+ wfModalDialogRun(window, paneId);
+ }
+
return 0;
}
+static BOOL
+wfModalDialogInit(void *closure, HWND dialog)
+{
+ HWND panel = ALF_AddPanel(dialog, (WORD)-1, 1, 1);
+ int paneid = (int)(LONG_PTR)closure;
+ g_paneInitTable[paneid](panel);
+
+ ALF_SetText(dialog, g_paneLabels[paneid]);
+
+ ALF_LayoutSetColumnExpandNumerator(dialog, 1, 1);
+ ALF_LayoutSetRowExpandNumerator(dialog, 1, 1);
+ ALF_LayoutSetRowMinSize(dialog, 0, 525);
+ ALF_LayoutSetRowMinSize(dialog, 2, 525);
+ ALF_LayoutSetColumnMinSize(dialog, 0, 525);
+ ALF_LayoutSetColumnMinSize(dialog, 2, 525);
+
+ return TRUE;
+}
+
+static LRESULT
+wfModalDialogWindowProc(void *closure, HWND dialog, UINT msg, WPARAM wp, LPARAM lp)
+{
+ (void)closure;
+
+ if (msg == WM_CLOSE) {
+ ALF_Toplevel_SetModalResult(dialog, 0);
+ }
+
+ return ALF_Toplevel_DefWindowProc(dialog, msg, wp, lp);
+}
+
+static ALFToplevelVTable g_wfModalDialogVtbl;
+
+static void
+wfModalDialogPrepareVtbl(void)
+{
+ ZeroMemory(&g_wfModalDialogVtbl, sizeof(g_wfModalDialogVtbl));
+ g_wfModalDialogVtbl.message = wfModalDialogWindowProc;
+ g_wfModalDialogVtbl.initialize = wfModalDialogInit;
+}
+
+static void
+wfModalDialogRun(HWND owner, int pane)
+{
+ HWND dlg = ALF_CreateToplevelWindow(WS_EX_DLGMODALFRAME,
+ WS_POPUPWINDOW | WS_CAPTION | WS_THICKFRAME,
+ owner,
+ &g_wfModalDialogVtbl,
+ (void*)(LONG_PTR)pane);
+ ALF_Toplevel_ShowModal(dlg);
+ DestroyWindow(dlg);
+}
+
int CALLBACK
#ifdef UNICODE
wWinMain
@@ -827,14 +897,17 @@ WinMain
}
}
+ wfModalDialogPrepareVtbl();
+
ALFToplevelVTable vtbl;
ZeroMemory(&vtbl, sizeof(vtbl));
vtbl.command = handleCommand;
+ vtbl.close = handleClose;
ALF_Initialize();
- HWND win = ALF_CreateToplevelWindow(NULL, &vtbl, NULL);
+ HWND win = ALF_CreateToplevelWindow(0, WS_OVERLAPPEDWINDOW, NULL, &vtbl, NULL);
if (!win) {
MessageBox(0, TEXT("couldn't create main window!"), 0, MB_ICONHAND|MB_OK);
return 1;
@@ -870,12 +943,14 @@ WinMain
HMENU mainmenu = CreateMenu();
HMENU filemenu = CreateMenu();
HMENU newtabmn = CreateMenu();
+ HMENU modwndmn = CreateMenu();
HMENU helpmenu = CreateMenu();
HMENU bgmenu = CreateMenu();
AppendMenu(filemenu, MF_STRING, ID_HELLO, TEXT("Hello"));
AppendMenu(filemenu, MF_SEPARATOR, 0, 0);
AppendMenu(filemenu, MF_POPUP, (UINT_PTR)newtabmn, TEXT("New Tab"));
+ AppendMenu(filemenu, MF_POPUP, (UINT_PTR)modwndmn, TEXT("Show Modal"));
AppendMenu(filemenu, MF_SEPARATOR, 0, 0);
AppendMenu(filemenu, MF_STRING, IDM_FILE_CLOSE, TEXT("&Close\tAlt+F4"));
@@ -892,6 +967,7 @@ WinMain
for (int i = 0; i < PANE__MAX; ++i) {
AppendMenu(newtabmn, MF_STRING, IDM_PANES + (UINT)i, g_paneLabels[i]);
+ AppendMenu(modwndmn, MF_STRING, IDM_MODALDIALOG_PANES + (UINT)i, g_paneLabels[i]);
}
SetMenu(win, mainmenu);