[PATCH] user32: Don't convert message arguments when calling dialog procedure

Nikolay Sivov nsivov at codeweavers.com
Tue Feb 13 23:37:06 CST 2018


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 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 33e755b0b7..ab3eec88bc 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 73bbe95028..e07971cec3 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;
 }
 
-- 
2.15.1




More information about the wine-devel mailing list