From 9640990e43e351ff2702713cde9fae7203a8ed9d Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 14 Feb 2018 08:37:06 +0300 Subject: [PATCH] user32: Don't convert message arguments when calling dialog procedure. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/user32/tests/dialog.c | 108 ++++++++++++++++++++++++++++++------- dlls/user32/winproc.c | 54 ++++++++++++++----- 2 files changed, 130 insertions(+), 32 deletions(-) diff --git a/dlls/user32/tests/dialog.c b/dlls/user32/tests/dialog.c index 33e755b0b7d..ab3eec88bc1 100644 --- a/dlls/user32/tests/dialog.c +++ b/dlls/user32/tests/dialog.c @@ -1277,12 +1277,10 @@ static INT_PTR CALLBACK test_aw_conversion_dlgprocA(HWND hdlg, UINT msg, WPARAM switch (mode) { case DLGPROCTEXT_DLGPROCA: - todo_wine_if(!IsWindowUnicode(hdlg)) ok(textA == testtext, "%s: %s, unexpected text %s.\n", IsWindowUnicode(hdlg) ? "U" : "A", testmodes[mode], textA); break; case DLGPROCTEXT_DLGPROCW: - todo_wine_if(IsWindowUnicode(hdlg)) ok(text == testtextW, "%s: %s, unexpected text %s.\n", IsWindowUnicode(hdlg) ? "U" : "A", testmodes[mode], wine_dbgstr_w(text)); break; @@ -1290,27 +1288,19 @@ static INT_PTR CALLBACK test_aw_conversion_dlgprocA(HWND hdlg, UINT msg, WPARAM case DLGPROCTEXT_SETTEXTA: if (IsWindowUnicode(hdlg)) { - todo_wine ok(text != testtextW && !lstrcmpW(text, testtextW), "U: %s, unexpected text %s.\n", testmodes[mode], wine_dbgstr_w(text)); } else - { - todo_wine ok(textA == testtext, "A: %s, unexpected text %s.\n", testmodes[mode], textA); - } break; case DLGPROCTEXT_SNDMSGW: case DLGPROCTEXT_SETTEXTW: if (IsWindowUnicode(hdlg)) - todo_wine ok(text == testtextW, "U: %s, unexpected text %s.\n", testmodes[mode], wine_dbgstr_w(text)); else - { - todo_wine ok(textA != testtext && !strcmp(textA, testtext), "A: %s, unexpected text %s.\n", testmodes[mode], textA); - } break; } break; @@ -1337,12 +1327,10 @@ static INT_PTR CALLBACK test_aw_conversion_dlgprocW(HWND hdlg, UINT msg, WPARAM switch (mode) { case DLGPROCTEXT_DLGPROCA: - todo_wine_if(IsWindowUnicode(hdlg)) ok(textA == testtext, "%s: %s, unexpected text %s.\n", IsWindowUnicode(hdlg) ? "U" : "A", testmodes[mode], textA); break; case DLGPROCTEXT_DLGPROCW: - todo_wine_if(!IsWindowUnicode(hdlg)) ok(text == testtextW, "%s: %s, unexpected text %s.\n", IsWindowUnicode(hdlg) ? "U" : "A", testmodes[mode], wine_dbgstr_w(text)); break; @@ -1433,13 +1421,11 @@ static INT_PTR CALLBACK test_aw_conversion_dlgproc(HWND hdlg, UINT msg, WPARAM w memset(buff, 'A', sizeof(buff)); len = GetWindowTextA(hdlg, buff, sizeof(buff)); - todo_wine ok(buff[0] == 0 && buff[1] == 'A' && len == 0, "Unexpected window text %#x, %#x, len %d\n", (BYTE)buff[0], (BYTE)buff[1], len); memset(buffW, 0xff, sizeof(buffW)); len = GetWindowTextW(hdlg, buffW, 64); - todo_wine ok(!lstrcmpW(buffW, testtextW) && len == 0, "Unexpected window text %s, len %d\n", wine_dbgstr_w(buffW), len); dlg_test_aw_message(hdlg, WM_WININICHANGE); @@ -1542,7 +1528,7 @@ static INT_PTR CALLBACK test_aw_conversion_dlgproc2(HWND hdlg, UINT msg, WPARAM memset(buff, 'A', sizeof(buff)); len = GetWindowTextA(hdlg, buff, sizeof(buff)); - ok(!strcmp(buff, "WndText") && len == 0, "Unexpected window text %s, len %d\n", buff, len); + ok(!strcmp(buff, testtext) && len == 0, "Unexpected window text %s, len %d\n", buff, len); memset(buffW, 0xff, sizeof(buffW)); len = GetWindowTextW(hdlg, buffW, 64); @@ -1578,12 +1564,10 @@ static INT_PTR CALLBACK test_aw_conversion_dlgproc2(HWND hdlg, UINT msg, WPARAM memset(buff, 'A', sizeof(buff)); len = GetWindowTextA(hdlg, buff, sizeof(buff)); - todo_wine - ok(!strcmp(buff, "WndText") && len == 0, "Unexpected window text %s, len %d\n", buff, len); + ok(!strcmp(buff, testtext) && len == 0, "Unexpected window text %s, len %d\n", buff, len); memset(buffW, 0xff, sizeof(buffW)); len = GetWindowTextW(hdlg, buffW, sizeof(buffW)/sizeof(buffW[0])); - todo_wine ok(buffW[0] == 0 && buffW[1] == 0xffff && len == 0, "Unexpected window text %#x, %#x, len %d\n", buffW[0], buffW[1], len); @@ -1602,6 +1586,88 @@ static INT_PTR CALLBACK test_aw_conversion_dlgproc2(HWND hdlg, UINT msg, WPARAM return FALSE; } +static LRESULT CALLBACK test_aw_conversion_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + int mode = HandleToULong(GetPropA(hwnd, "test_mode")); + WCHAR *text = (WCHAR *)lparam; + char *textA = (char *)lparam; + + switch (msg) + { + case WM_SETTEXT: + case WM_WININICHANGE: + case WM_DEVMODECHANGE: + case CB_DIR: + case LB_DIR: + case LB_ADDFILE: + case EM_REPLACESEL: + switch (mode) + { + case DLGPROCTEXT_SNDMSGA: + if (IsWindowUnicode(hwnd)) + ok(text != testtextW && !lstrcmpW(text, testtextW), + "U: %s, unexpected text %s.\n", testmodes[mode], wine_dbgstr_w(text)); + else + ok(textA == testtext, "A: %s, unexpected text %s.\n", testmodes[mode], textA); + break; + case DLGPROCTEXT_SNDMSGW: + if (IsWindowUnicode(hwnd)) + ok(text == testtextW, "U: %s, unexpected text %s.\n", testmodes[mode], wine_dbgstr_w(text)); + else + ok(textA != testtext && !strcmp(textA, testtext), "A: %s, unexpected text %s.\n", + testmodes[mode], textA); + break; + default: + ok(0, "Unexpected test mode %d.\n", mode); + } + break; + } + + return IsWindowUnicode(hwnd) ? CallWindowProcW(oldproc, hwnd, msg, wparam, lparam) : + CallWindowProcA(oldproc, hwnd, msg, wparam, lparam); +} + +static INT_PTR CALLBACK test_aw_conversion_dlgproc3(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) +{ + BOOL is_unicode = !!lparam; + LONG_PTR oldproc; + + switch (msg) + { + case WM_INITDIALOG: + ok(is_unicode == IsWindowUnicode(hdlg), "Unexpected unicode window property.\n"); + + oldproc = SetWindowLongPtrA(hdlg, GWLP_WNDPROC, (LONG_PTR)test_aw_conversion_wndproc); + SetWindowLongPtrA(hdlg, GWLP_USERDATA, oldproc); + ok(!IsWindowUnicode(hdlg), "Unexpected unicode window.\n"); + + dlg_test_aw_message(hdlg, WM_WININICHANGE); + dlg_test_aw_message(hdlg, WM_DEVMODECHANGE); + dlg_test_aw_message(hdlg, CB_DIR); + dlg_test_aw_message(hdlg, LB_DIR); + dlg_test_aw_message(hdlg, LB_ADDFILE); + dlg_test_aw_message(hdlg, EM_REPLACESEL); + dlg_test_aw_message(hdlg, WM_SETTEXT); + + SetWindowLongPtrW(hdlg, GWLP_WNDPROC, (LONG_PTR)test_aw_conversion_wndproc); + ok(IsWindowUnicode(hdlg), "Expected unicode window.\n"); + + dlg_test_aw_message(hdlg, WM_WININICHANGE); + dlg_test_aw_message(hdlg, WM_DEVMODECHANGE); + dlg_test_aw_message(hdlg, CB_DIR); + dlg_test_aw_message(hdlg, LB_DIR); + dlg_test_aw_message(hdlg, LB_ADDFILE); + dlg_test_aw_message(hdlg, EM_REPLACESEL); + dlg_test_aw_message(hdlg, WM_SETTEXT); + + SetWindowLongPtrA(hdlg, GWLP_WNDPROC, oldproc); + EndDialog(hdlg, -123); + return TRUE; + } + return FALSE; +} + static void test_DialogBoxParam(void) { static const WCHAR nameW[] = {'T','E','S','T','_','E','M','P','T','Y','_','D','I','A','L','O','G',0}; @@ -1665,6 +1731,12 @@ static void test_DialogBoxParam(void) ret = DialogBoxParamA(GetModuleHandleA(NULL), "TEST_EMPTY_DIALOG", 0, test_aw_conversion_dlgproc2, 0); ok(ret == -123, "Unexpected ret value %ld.\n", ret); + + ret = DialogBoxParamW(GetModuleHandleA(NULL), nameW, 0, test_aw_conversion_dlgproc3, 1); + ok(ret == -123, "Unexpected ret value %ld.\n", ret); + + ret = DialogBoxParamA(GetModuleHandleA(NULL), "TEST_EMPTY_DIALOG", 0, test_aw_conversion_dlgproc3, 0); + ok(ret == -123, "Unexpected ret value %ld.\n", ret); } static void test_DisabledDialogTest(void) diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index 73bbe95028e..e07971cec30 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -869,10 +869,10 @@ BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result, BOOL unicode, enum wm_char_mapping mapping ) { struct user_thread_info *thread_info = get_user_thread_info(); + BOOL unicode_win, is_dialog; WND *wndPtr; WNDPROC func; WINDOWPROC *proc; - BOOL unicode_win; if (!(wndPtr = WIN_GetPtr( hwnd ))) return FALSE; if (wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return FALSE; @@ -884,6 +884,7 @@ BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, func = wndPtr->winproc; proc = handle_to_proc( wndPtr->winproc ); unicode_win = wndPtr->flags & WIN_ISUNICODE; + is_dialog = wndPtr->dlgInfo != NULL; WIN_ReleasePtr( wndPtr ); if (thread_info->recursion_count > MAX_WINPROC_RECURSION) return FALSE; @@ -893,6 +894,23 @@ BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, { if (proc == WINPROC_PROC16) WINPROC_CallProcWtoA( wow_handlers.call_window_proc, hwnd, msg, wParam, lParam, result, func ); + else if (is_dialog) + { + if (unicode_win) + { + if (proc && proc->procW) + call_window_proc( hwnd, msg, wParam, lParam, result, proc->procW ); + else + call_window_proc( hwnd, msg, wParam, lParam, result, func ); + } + else + { + if (proc && proc->procA) + WINPROC_CallProcWtoA( call_window_proc, hwnd, msg, wParam, lParam, result, proc->procA ); + else + WINPROC_CallProcWtoA( call_window_proc, hwnd, msg, wParam, lParam, result, func ); + } + } else if (proc && proc->procW) call_window_proc( hwnd, msg, wParam, lParam, result, proc->procW ); else if (proc) @@ -906,6 +924,23 @@ BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, { if (proc == WINPROC_PROC16) wow_handlers.call_window_proc( hwnd, msg, wParam, lParam, result, func ); + else if (is_dialog) + { + if (unicode_win) + { + if (proc && proc->procW) + WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, result, proc->procW, mapping ); + else + WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, result, func, mapping ); + } + else + { + if (proc && proc->procA) + call_window_proc( hwnd, msg, wParam, lParam, result, proc->procA ); + else + call_window_proc( hwnd, msg, wParam, lParam, result, func ); + } + } else if (proc && proc->procA) call_window_proc( hwnd, msg, wParam, lParam, result, proc->procA ); else if (proc) @@ -1012,14 +1047,9 @@ INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, ret = wow_handlers.call_dialog_proc( hwnd, msg, wParam, lParam, &result, func ); SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result ); } - else if (proc->procW) - { - ret = WINPROC_CallProcAtoW( call_dialog_proc, hwnd, msg, wParam, lParam, &result, - proc->procW, WMCHAR_MAP_CALLWINDOWPROC ); - SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result ); - } else - ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procA ); + ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procW ? proc->procW : proc->procA ); + return ret; } @@ -1042,13 +1072,9 @@ INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam, ret = WINPROC_CallProcWtoA( wow_handlers.call_dialog_proc, hwnd, msg, wParam, lParam, &result, func ); SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result ); } - else if (proc->procA) - { - ret = WINPROC_CallProcWtoA( call_dialog_proc, hwnd, msg, wParam, lParam, &result, proc->procA ); - SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result ); - } else - ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procW ); + ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procW ? proc->procW : proc->procA ); + return ret; }