summaryrefslogtreecommitdiff
path: root/alf/alftoplevel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'alf/alftoplevel.cpp')
-rw-r--r--alf/alftoplevel.cpp87
1 files changed, 51 insertions, 36 deletions
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;
}