Added patch to use root dialog for DM_SETDEFID/DM_GETDEFID in DefDlgProc.

This commit is contained in:
Sebastian Lackner 2016-06-16 23:52:44 +02:00
parent 243a9f7b89
commit 3cb1c835bc
5 changed files with 291 additions and 0 deletions

View File

@ -326,6 +326,7 @@ patch_enable_all ()
enable_user_exe16_CONTAINING_RECORD="$1"
enable_user_exe16_DlgDirList="$1"
enable_user32_CharToOem="$1"
enable_user32_DM_SETDEFID="$1"
enable_user32_DeferWindowPos="$1"
enable_user32_DialogBoxParam="$1"
enable_user32_Dialog_Paint_Event="$1"
@ -1159,6 +1160,9 @@ patch_enable ()
user32-CharToOem)
enable_user32_CharToOem="$2"
;;
user32-DM_SETDEFID)
enable_user32_DM_SETDEFID="$2"
;;
user32-DeferWindowPos)
enable_user32_DeferWindowPos="$2"
;;
@ -6736,6 +6740,25 @@ if test "$enable_user32_CharToOem" -eq 1; then
) >> "$patchlist"
fi
# Patchset user32-DM_SETDEFID
# |
# | This patchset fixes the following Wine bugs:
# | * [#22764] Use root dialog for DM_SETDEFID/DM_GETDEFID in DefDlgProc
# |
# | Modified files:
# | * dlls/user32/defdlg.c, dlls/user32/dialog.c, dlls/user32/tests/win.c
# |
if test "$enable_user32_DM_SETDEFID" -eq 1; then
patch_apply user32-DM_SETDEFID/0001-user32-Do-not-initialize-dialog-info-for-every-windo.patch
patch_apply user32-DM_SETDEFID/0002-user32-Use-root-dialog-for-DM_SETDEFID-DM_GETDEFID-i.patch
patch_apply user32-DM_SETDEFID/0003-user32-tests-Add-a-bunch-of-tests-for-DM_SETDEFID-DM.patch
(
echo '+ { "Dmitry Timoshkov", "user32: Do not initialize dialog info for every window passed to DefDlgProc.", 1 },';
echo '+ { "Dmitry Timoshkov", "user32: Use root dialog for DM_SETDEFID/DM_GETDEFID in DefDlgProc.", 1 },';
echo '+ { "Dmitry Timoshkov", "user32/tests: Add a bunch of tests for DM_SETDEFID/DM_GETDEFID handling by a DefDlgProc.", 1 },';
) >> "$patchlist"
fi
# Patchset user32-DeferWindowPos
# |
# | This patchset fixes the following Wine bugs:

View File

@ -0,0 +1,57 @@
From c40265799ed2dd422b06cce9560b7b855304cbf1 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 15 Jun 2016 14:57:10 +0800
Subject: user32: Do not initialize dialog info for every window passed to
DefDlgProc.
The tests in the last patch in the series use
DefDlgProcA(parent, DM_GETDEFID, 0, 0);
as a simple dialog detector, and that call leads to dialog info being
created for a not dialog window, which later makes this window being
treated as a dialog.
DIALOG_CreateControls32() gets called after the dialog info creation
has been forced, so passing TRUE to DIALOG_get_info() is redundant there.
---
dlls/user32/defdlg.c | 4 ++--
dlls/user32/dialog.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/defdlg.c b/dlls/user32/defdlg.c
index 00a73c6..258c3a9 100644
--- a/dlls/user32/defdlg.c
+++ b/dlls/user32/defdlg.c
@@ -364,7 +364,7 @@ LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
LRESULT result = 0;
/* Perform DIALOGINFO initialization if not done */
- if(!(dlgInfo = DIALOG_get_info( hwnd, TRUE ))) return 0;
+ if (!(dlgInfo = DIALOG_get_info( hwnd, msg == WM_NCCREATE ))) return 0;
SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, 0 );
@@ -422,7 +422,7 @@ LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
LRESULT result = 0;
/* Perform DIALOGINFO initialization if not done */
- if(!(dlgInfo = DIALOG_get_info( hwnd, TRUE ))) return 0;
+ if (!(dlgInfo = DIALOG_get_info( hwnd, msg == WM_NCCREATE ))) return 0;
SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, 0 );
diff --git a/dlls/user32/dialog.c b/dlls/user32/dialog.c
index 9cb4b8d..b84784f 100644
--- a/dlls/user32/dialog.c
+++ b/dlls/user32/dialog.c
@@ -216,7 +216,7 @@ static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info,
static BOOL DIALOG_CreateControls32( HWND hwnd, LPCSTR template, const DLG_TEMPLATE *dlgTemplate,
HINSTANCE hInst, BOOL unicode )
{
- DIALOGINFO *dlgInfo = DIALOG_get_info( hwnd, TRUE );
+ DIALOGINFO *dlgInfo = DIALOG_get_info( hwnd, FALSE );
DLG_CONTROL_INFO info;
HWND hwndCtrl, hwndDefButton = 0;
INT items = dlgTemplate->nbItems;
--
2.8.0

View File

@ -0,0 +1,62 @@
From d068cb5331e7dee5ceb0c14a3eff9ef2c273865d Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 15 Jun 2016 15:07:39 +0800
Subject: user32: Use root dialog for DM_SETDEFID/DM_GETDEFID in DefDlgProc.
This patch fixes DM_SETDEFID/DM_GETDEFID handling in complex dialog
structures such as a property sheet.
---
dlls/user32/defdlg.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/dlls/user32/defdlg.c b/dlls/user32/defdlg.c
index 258c3a9..6765a51 100644
--- a/dlls/user32/defdlg.c
+++ b/dlls/user32/defdlg.c
@@ -209,6 +209,25 @@ static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo, HWND hwndNew
}
+static HWND root_dialog(HWND hwnd)
+{
+ while ((GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_CONTROLPARENT) &&
+ (GetWindowLongA(hwnd, GWL_STYLE) & (WS_CHILD|WS_POPUP)) == WS_CHILD)
+ {
+ HWND parent = GetParent(hwnd);
+
+ if (!DIALOG_get_info(parent, FALSE))
+ break;
+
+ hwnd = parent;
+
+ if (!(GetWindowLongA(hwnd, GWL_STYLE) & DS_CONTROL))
+ break;
+ }
+
+ return hwnd;
+}
+
/***********************************************************************
* DEFDLG_Proc
*
@@ -264,11 +283,17 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
return 0;
case DM_SETDEFID:
+ hwnd = root_dialog( hwnd );
+ dlgInfo = DIALOG_get_info( hwnd, FALSE );
+
if (dlgInfo && !(dlgInfo->flags & DF_END))
DEFDLG_SetDefId( hwnd, dlgInfo, wParam );
return 1;
case DM_GETDEFID:
+ hwnd = root_dialog( hwnd );
+ dlgInfo = DIALOG_get_info( hwnd, FALSE );
+
if (dlgInfo && !(dlgInfo->flags & DF_END))
{
HWND hwndDefId;
--
2.8.0

View File

@ -0,0 +1,148 @@
From 44670a4e2f5d3434d8546ed32724b58a24b4399e Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 15 Jun 2016 15:09:46 +0800
Subject: user32/tests: Add a bunch of tests for DM_SETDEFID/DM_GETDEFID
handling by a DefDlgProc.
---
dlls/user32/tests/win.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index c135fdf..23e98e0 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -4228,15 +4228,65 @@ static void test_window_styles(void)
}
}
+static HWND root_dialog(HWND hwnd)
+{
+ while ((GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_CONTROLPARENT) &&
+ (GetWindowLongA(hwnd, GWL_STYLE) & (WS_CHILD|WS_POPUP)) == WS_CHILD)
+ {
+ HWND parent = GetParent(hwnd);
+
+ /* simple detector for a window being a dialog */
+ if (!DefDlgProcA(parent, DM_GETDEFID, 0, 0))
+ break;
+
+ hwnd = parent;
+
+ if (!(GetWindowLongA(hwnd, GWL_STYLE) & DS_CONTROL))
+ break;
+ }
+
+ return hwnd;
+}
+
static INT_PTR WINAPI empty_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
return 0;
}
+static LRESULT expected_id;
+
static INT_PTR WINAPI empty_dlg_proc3(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if (msg == WM_INITDIALOG)
+ {
+ HWND parent = GetParent(hwnd);
+ LRESULT id, ret;
+
+ id = DefDlgProcA(parent, DM_GETDEFID, 0, 0);
+ if (!id || root_dialog(hwnd) == hwnd)
+ parent = 0;
+
+ id = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0);
+ if (!parent)
+ ok(id == MAKELONG(IDOK,DC_HASDEFID), "expected (IDOK,DC_HASDEFID), got %08lx\n", id);
+ else
+ ok(id == expected_id, "expected %08lx, got %08lx\n", expected_id, id);
+
+ ret = DefDlgProcA(hwnd, DM_SETDEFID, 0x3333, 0);
+ ok(ret, "DefDlgProc(DM_SETDEFID) failed\n");
+ id = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0);
+ ok(id == MAKELONG(0x3333,DC_HASDEFID), "expected (0x3333,DC_HASDEFID), got %08lx\n", id);
+
+ if (parent)
+ {
+ id = DefDlgProcA(parent, DM_GETDEFID, 0, 0);
+ ok(id == MAKELONG(0x3333,DC_HASDEFID), "expected (0x3333,DC_HASDEFID), got %08lx\n", id);
+
+ expected_id = MAKELONG(0x3333,DC_HASDEFID);
+ }
+
EndDialog(hwnd, 0);
+ }
return 0;
}
@@ -4255,6 +4305,16 @@ static INT_PTR WINAPI empty_dlg_proc2(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
struct dialog_param *param = (struct dialog_param *)lparam;
BOOL parent_is_child;
HWND disabled_hwnd;
+ LRESULT id, ret;
+
+ id = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0);
+ ok(id == MAKELONG(IDOK,DC_HASDEFID), "expected (IDOK,DC_HASDEFID), got %08lx\n", id);
+ ret = DefDlgProcA(hwnd, DM_SETDEFID, 0x2222, 0);
+ ok(ret, "DefDlgProc(DM_SETDEFID) failed\n");
+ id = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0);
+ ok(id == MAKELONG(0x2222,DC_HASDEFID), "expected (0x2222,DC_HASDEFID), got %08lx\n", id);
+
+ expected_id = MAKELONG(0x2222,DC_HASDEFID);
parent_is_child = (GetWindowLongA(param->parent, GWL_STYLE) & (WS_POPUP | WS_CHILD)) == WS_CHILD;
@@ -4296,6 +4356,25 @@ static INT_PTR WINAPI empty_dlg_proc2(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
DialogBoxIndirectParamA(GetModuleHandleA(NULL), param->dlg_data, hwnd, empty_dlg_proc3, 0);
ok(IsWindowEnabled(hwnd), "wrong state for %p (%08x)\n", hwnd, style);
+ param->dlg_data->style |= DS_CONTROL;
+ DialogBoxIndirectParamA(GetModuleHandleA(NULL), param->dlg_data, hwnd, empty_dlg_proc3, 0);
+ ok(IsWindowEnabled(hwnd), "wrong state for %p (%08x)\n", hwnd, style);
+
+ param->dlg_data->dwExtendedStyle |= WS_EX_CONTROLPARENT;
+ SetWindowLongA(hwnd, GWL_EXSTYLE, GetWindowLongA(hwnd, GWL_EXSTYLE) | WS_EX_CONTROLPARENT);
+ SetWindowLongA(hwnd, GWL_STYLE, style & ~DS_CONTROL);
+ param->dlg_data->style &= ~DS_CONTROL;
+ DialogBoxIndirectParamA(GetModuleHandleA(NULL), param->dlg_data, hwnd, empty_dlg_proc3, 0);
+ ok(IsWindowEnabled(hwnd), "wrong state for %p (%08x)\n", hwnd, style);
+
+ SetWindowLongA(hwnd, GWL_STYLE, style | DS_CONTROL);
+ DialogBoxIndirectParamA(GetModuleHandleA(NULL), param->dlg_data, hwnd, empty_dlg_proc3, 0);
+ ok(IsWindowEnabled(hwnd), "wrong state for %p (%08x)\n", hwnd, style);
+
+ param->dlg_data->style |= DS_CONTROL;
+ DialogBoxIndirectParamA(GetModuleHandleA(NULL), param->dlg_data, hwnd, empty_dlg_proc3, 0);
+ ok(IsWindowEnabled(hwnd), "wrong state for %p (%08x)\n", hwnd, style);
+
EndDialog(hwnd, 0);
}
return 0;
@@ -4314,6 +4393,7 @@ static void check_dialog_style(DWORD style_in, DWORD ex_style_in, DWORD style_ou
DWORD style, ex_style;
HWND hwnd, grand_parent = 0, parent = 0;
struct dialog_param param;
+ LRESULT id, ret;
if (style_in & WS_CHILD)
{
@@ -4341,6 +4421,13 @@ static void check_dialog_style(DWORD style_in, DWORD ex_style_in, DWORD style_ou
hwnd = CreateDialogIndirectParamA(GetModuleHandleA(NULL), &dlg_data.dt, parent, empty_dlg_proc, 0);
ok(hwnd != 0, "dialog creation failed, style %#x, exstyle %#x\n", style_in, ex_style_in);
+ id = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0);
+ ok(id == MAKELONG(IDOK,DC_HASDEFID), "expected (IDOK,DC_HASDEFID), got %08lx\n", id);
+ ret = DefDlgProcA(hwnd, DM_SETDEFID, 0x1111, 0);
+ ok(ret, "DefDlgProc(DM_SETDEFID) failed\n");
+ id = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0);
+ ok(id == MAKELONG(0x1111,DC_HASDEFID), "expected (0x1111,DC_HASDEFID), got %08lx\n", id);
+
flush_events( TRUE );
style = GetWindowLongA(hwnd, GWL_STYLE);
--
2.8.0

View File

@ -0,0 +1 @@
Fixes: [22764] Use root dialog for DM_SETDEFID/DM_GETDEFID in DefDlgProc