[PATCH 0/2] MR8702: user32/tests: Add more SendMessageCallbackA/W() tests with NULL callback.
For React Native. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8702
From: Zhiyi Zhang <zzhang(a)codeweavers.com> The tests are mainly to show that SendMessageCallbackA/W() with NULL callback pointer and callback data being 1 causes message to be posted to window, even when the window is created in the same thread. --- dlls/user32/tests/msg.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 80d900baa1c..1c2d61c7781 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -16499,6 +16499,12 @@ static void test_EndDialog(void) UnregisterClassA(cls.lpszClassName, cls.hInstance); } +static const struct message WmUserSeq[] = +{ + { WM_USER, sent }, + { 0 } +}; + static void test_nullCallback(void) { HWND hwnd; @@ -16507,8 +16513,39 @@ static void test_nullCallback(void) 100, 100, 200, 200, 0, 0, 0, NULL); ok (hwnd != 0, "Failed to create overlapped window\n"); - SendMessageCallbackA(hwnd,WM_NULL,0,0,NULL,0); + /* NULL callback and data being 0 */ + flush_sequence(); + SendMessageCallbackA(hwnd, WM_USER, 0, 0, NULL, 0); + ok_sequence(WmUserSeq, "WM_USER with NULL callback", FALSE); + + flush_sequence(); + SendMessageCallbackW(hwnd, WM_USER, 0, 0, NULL, 0); + ok_sequence(WmUserSeq, "WM_USER with NULL callback", FALSE); + + /* NULL callback and data being 1. The result suggests that the message is posted to the window */ + flush_sequence(); + SendMessageCallbackA(hwnd, WM_USER, 0, 0, NULL, 1); + ok_sequence(WmEmptySeq, "WM_USER with NULL callback", TRUE); flush_events(); + ok_sequence(WmUserSeq, "WM_USER with NULL callback after flushing events", TRUE); + + /* NULL callback and data being 1. The result suggests that the message is posted to the window */ + flush_sequence(); + SendMessageCallbackW(hwnd, WM_USER, 0, 0, NULL, 1); + ok_sequence(WmEmptySeq, "WM_USER with NULL callback", TRUE); + flush_events(); + ok_sequence(WmUserSeq, "WM_USER with NULL callback after flushing events", TRUE); + + /* NULL callback and data being 2 */ + flush_sequence(); + SendMessageCallbackA(hwnd, WM_USER, 0, 0, NULL, 2); + ok_sequence(WmUserSeq, "WM_USER with NULL callback", FALSE); + + /* NULL callback and data being 2 */ + flush_sequence(); + SendMessageCallbackW(hwnd, WM_USER, 0, 0, NULL, 2); + ok_sequence(WmUserSeq, "WM_USER with NULL callback", FALSE); + DestroyWindow(hwnd); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8702
From: Zhiyi Zhang <zzhang(a)codeweavers.com> This is an undocumented behavior needed by React Native apps, based on Nikolay's findings. --- dlls/user32/message.c | 7 +++++++ dlls/user32/tests/msg.c | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 205d3e01c02..3b541959faf 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -640,6 +640,9 @@ BOOL WINAPI SendMessageCallbackA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa { struct send_message_callback_params params = { .callback = callback, .data = data }; + if (!callback && data == 1) + return PostMessageA( hwnd, msg, wparam, lparam ); + if (!WIN_IsCurrentThread( hwnd ) && !map_wparam_AtoW( msg, &wparam, WMCHAR_MAP_SENDMESSAGE )) return FALSE; @@ -654,6 +657,10 @@ BOOL WINAPI SendMessageCallbackW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa SENDASYNCPROC callback, ULONG_PTR data ) { struct send_message_callback_params params = { .callback = callback, .data = data }; + + if (!callback && data == 1) + return PostMessageW( hwnd, msg, wparam, lparam ); + return NtUserMessageCall( hwnd, msg, wparam, lparam, ¶ms, NtUserSendMessageCallback, FALSE ); } diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 1c2d61c7781..9089e96aa84 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -16525,16 +16525,16 @@ static void test_nullCallback(void) /* NULL callback and data being 1. The result suggests that the message is posted to the window */ flush_sequence(); SendMessageCallbackA(hwnd, WM_USER, 0, 0, NULL, 1); - ok_sequence(WmEmptySeq, "WM_USER with NULL callback", TRUE); + ok_sequence(WmEmptySeq, "WM_USER with NULL callback", FALSE); flush_events(); - ok_sequence(WmUserSeq, "WM_USER with NULL callback after flushing events", TRUE); + ok_sequence(WmUserSeq, "WM_USER with NULL callback after flushing events", FALSE); /* NULL callback and data being 1. The result suggests that the message is posted to the window */ flush_sequence(); SendMessageCallbackW(hwnd, WM_USER, 0, 0, NULL, 1); - ok_sequence(WmEmptySeq, "WM_USER with NULL callback", TRUE); + ok_sequence(WmEmptySeq, "WM_USER with NULL callback", FALSE); flush_events(); - ok_sequence(WmUserSeq, "WM_USER with NULL callback after flushing events", TRUE); + ok_sequence(WmUserSeq, "WM_USER with NULL callback after flushing events", FALSE); /* NULL callback and data being 2 */ flush_sequence(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8702
What's the reason for adding duplicate tests? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8702#note_111952
Also, it would be interesting to test the queue status. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8702#note_111953
On Mon Aug 4 07:36:35 2025 +0000, Dmitry Timoshkov wrote:
What's the reason for adding duplicate tests? Both SendMessageCallbackA() and SendMessageCallbackW() are being tested. The main purpose is to test an undocumented behavior, so we need to know that it's not limited only to the A/W() variant.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/8702#note_111954
On Mon Aug 4 07:36:35 2025 +0000, Dmitry Timoshkov wrote:
Also, it would be interesting to test the queue status. Could you please elaborate on the queue status you would like me to test? I've added the message sequence tests.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/8702#note_111955
On Mon Aug 4 07:36:35 2025 +0000, Zhiyi Zhang wrote:
Could you please elaborate on the queue status you would like me to test? I've added the message sequence tests. The queue status would confirm that the message is supposed to be posted and not sent.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/8702#note_111957
On Mon Aug 4 07:36:34 2025 +0000, Zhiyi Zhang wrote:
Both SendMessageCallbackA() and SendMessageCallbackW() are being tested. The main purpose is to test an undocumented behavior, so we need to know that it's not limited only to the A/W() variant. Thanks. Probably a comment that clarifies that would be helpful.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/8702#note_111958
Also it would be interesting to test return value of SendMessageCallback(). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8702#note_111984
participants (3)
-
Dmitry Timoshkov (@dmitry) -
Zhiyi Zhang -
Zhiyi Zhang (@zhiyi)