win32u: Return LRESULT from NtUserMessageCall.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-04-04 16:57:23 +02:00 committed by Alexandre Julliard
parent cbbe8ad73a
commit 177eb908c9
8 changed files with 138 additions and 31 deletions

View File

@ -377,5 +377,6 @@ void SPY_EnterMessage( INT flag, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
void SPY_ExitMessage( INT flag, HWND hwnd, UINT msg, LRESULT lreturn, WPARAM wparam, LPARAM lparam ) void SPY_ExitMessage( INT flag, HWND hwnd, UINT msg, LRESULT lreturn, WPARAM wparam, LPARAM lparam )
{ {
if (TRACE_ON(message)) NtUserMessageCall( hwnd, msg, wparam, lparam, lreturn, FNID_SPYEXIT, flag ); if (TRACE_ON(message)) NtUserMessageCall( hwnd, msg, wparam, lparam, (void *)lreturn,
FNID_SPYEXIT, flag );
} }

View File

@ -1332,7 +1332,7 @@ LRESULT WINAPI CallWindowProcA( WNDPROC func, HWND hwnd, UINT msg, WPARAM wParam
params.func = func; params.func = func;
params.result = &result; params.result = &result;
if (!NtUserMessageCall( hwnd, msg, wParam, lParam, (ULONG_PTR)&params, FNID_CALLWNDPROC, TRUE )) if (!NtUserMessageCall( hwnd, msg, wParam, lParam, &params, FNID_CALLWNDPROC, TRUE ))
return 0; return 0;
dispatch_win_proc_params( &params ); dispatch_win_proc_params( &params );
return result; return result;
@ -1351,7 +1351,7 @@ LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg, WPARAM wParam
params.func = func; params.func = func;
params.result = &result; params.result = &result;
if (!NtUserMessageCall( hwnd, msg, wParam, lParam, (ULONG_PTR)&params, FNID_CALLWNDPROC, FALSE )) if (!NtUserMessageCall( hwnd, msg, wParam, lParam, &params, FNID_CALLWNDPROC, FALSE ))
return 0; return 0;
dispatch_win_proc_params( &params ); dispatch_win_proc_params( &params );
return result; return result;

View File

@ -2133,23 +2133,19 @@ BOOL kill_system_timer( HWND hwnd, UINT_PTR id )
return ret; return ret;
} }
static BOOL send_window_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, static LRESULT send_window_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi )
LRESULT *result, BOOL ansi )
{ {
/* FIXME: move implementation from user32 */ /* FIXME: move implementation from user32 */
if (!user_callbacks) return FALSE; if (!user_callbacks) return FALSE;
*result = ansi return ansi
? user_callbacks->pSendMessageA( hwnd, msg, wparam, lparam ) ? user_callbacks->pSendMessageA( hwnd, msg, wparam, lparam )
: user_callbacks->pSendMessageW( hwnd, msg, wparam, lparam ); : user_callbacks->pSendMessageW( hwnd, msg, wparam, lparam );
return TRUE;
} }
/* see SendMessageW */ /* see SendMessageW */
LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{ {
LRESULT result = 0; return send_window_message( hwnd, msg, wparam, lparam, FALSE );
send_window_message( hwnd, msg, wparam, lparam, &result, FALSE );
return result;
} }
/* see SendNotifyMessageW */ /* see SendNotifyMessageW */
@ -2166,8 +2162,8 @@ LRESULT post_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
return user_callbacks->pPostMessageW( hwnd, msg, wparam, lparam ); return user_callbacks->pPostMessageW( hwnd, msg, wparam, lparam );
} }
BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
ULONG_PTR result_info, DWORD type, BOOL ansi ) void *result_info, DWORD type, BOOL ansi )
{ {
switch (type) switch (type)
{ {
@ -2175,17 +2171,17 @@ BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam
return init_win_proc_params( (struct win_proc_params *)result_info, hwnd, msg, return init_win_proc_params( (struct win_proc_params *)result_info, hwnd, msg,
wparam, lparam, ansi ); wparam, lparam, ansi );
case FNID_SENDMESSAGE: case FNID_SENDMESSAGE:
return send_window_message( hwnd, msg, wparam, lparam, (LRESULT *)result_info, ansi ); return send_window_message( hwnd, msg, wparam, lparam, ansi );
case FNID_SENDNOTIFYMESSAGE: case FNID_SENDNOTIFYMESSAGE:
return send_notify_message( hwnd, msg, wparam, lparam, ansi ); return send_notify_message( hwnd, msg, wparam, lparam, ansi );
case FNID_SPYENTER: case FNID_SPYENTER:
spy_enter_message( ansi, hwnd, msg, wparam, lparam ); spy_enter_message( ansi, hwnd, msg, wparam, lparam );
return 0; return 0;
case FNID_SPYEXIT: case FNID_SPYEXIT:
spy_exit_message( ansi, hwnd, msg, result_info, wparam, lparam ); spy_exit_message( ansi, hwnd, msg, (LPARAM)result_info, wparam, lparam );
return 0; return 0;
default: default:
FIXME( "%p %x %lx %lx %lx %x %x\n", hwnd, msg, wparam, lparam, result_info, type, ansi ); FIXME( "%p %x %lx %lx %p %x %x\n", hwnd, msg, wparam, lparam, result_info, type, ansi );
} }
return 0; return 0;
} }

View File

@ -381,6 +381,102 @@ static void test_cursoricon(void)
ok(ret, "Destroy icon failed, error %lu.\n", GetLastError()); ok(ret, "Destroy icon failed, error %lu.\n", GetLastError());
} }
static LRESULT WINAPI test_message_call_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
switch (msg)
{
case WM_SETTEXT:
ok( !wcscmp( (const WCHAR *)lparam, L"test" ),
"lparam = %s\n", wine_dbgstr_w( (const WCHAR *)lparam ));
return 6;
case WM_USER:
ok( wparam == 1, "wparam = %Iu\n", wparam );
ok( lparam == 2, "lparam = %Iu\n", lparam );
return 3;
case WM_USER + 1:
return lparam;
}
return DefWindowProcW( hwnd, msg, wparam, lparam );
}
static void WINAPI test_message_callback( HWND hwnd, UINT msg, ULONG_PTR data, LRESULT result )
{
ok( msg == WM_USER, "msg = %u\n", msg );
ok( data == 10, "data = %Iu\n", data );
ok( result == 3, "result = %Iu\n", result );
}
static void test_message_call(void)
{
const LPARAM large_lparam = (LPARAM)(3 + ((ULONGLONG)1 << 60));
struct send_message_callback_params callback_params = {
.callback = test_message_callback,
.data = 10,
};
struct send_message_timeout_params smp;
WNDCLASSW cls = { 0 };
LRESULT res;
HWND hwnd;
cls.lpfnWndProc = test_message_call_proc;
cls.lpszClassName = L"TestClass";
RegisterClassW( &cls );
hwnd = CreateWindowExW( 0, L"TestClass", NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL );
res = NtUserMessageCall( hwnd, WM_USER, 1, 2, (void *)0xdeadbeef, FNID_SENDMESSAGE, FALSE );
ok( res == 3, "res = %Iu\n", res );
res = NtUserMessageCall( hwnd, WM_USER, 1, 2, (void *)0xdeadbeef, FNID_SENDMESSAGE, TRUE );
ok( res == 3, "res = %Iu\n", res );
res = NtUserMessageCall( hwnd, WM_SETTEXT, 0, (LPARAM)L"test", NULL, FNID_SENDMESSAGE, FALSE );
ok( res == 6, "res = %Iu\n", res );
res = NtUserMessageCall( hwnd, WM_SETTEXT, 0, (LPARAM)"test", NULL, FNID_SENDMESSAGE, TRUE );
ok( res == 6, "res = %Iu\n", res );
SetLastError( 0xdeadbeef );
res = NtUserMessageCall( UlongToHandle(0xdeadbeef), WM_USER, 1, 2, 0, FNID_SENDMESSAGE, TRUE );
ok( !res, "res = %Iu\n", res );
ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "GetLastError() = %lu\n", GetLastError());
res = NtUserMessageCall( hwnd, WM_USER + 1, 0, large_lparam, 0, FNID_SENDMESSAGE, FALSE );
ok( res == large_lparam, "res = %Iu\n", res );
smp.flags = 0;
smp.timeout = 10;
smp.result = 0xdeadbeef;
res = NtUserMessageCall( hwnd, WM_USER, 1, 2, &smp, FNID_SENDMESSAGEWTOOPTION, FALSE );
todo_wine
ok( res == 3, "res = %Iu\n", res );
todo_wine
ok( smp.result == 1, "smp.result = %Iu\n", smp.result );
smp.flags = 0;
smp.timeout = 10;
smp.result = 0xdeadbeef;
res = NtUserMessageCall( hwnd, WM_USER + 1, 0, large_lparam,
&smp, FNID_SENDMESSAGEWTOOPTION, FALSE );
todo_wine
ok( res == large_lparam, "res = %Iu\n", res );
todo_wine
ok( smp.result == 1, "smp.result = %Iu\n", smp.result );
res = NtUserMessageCall( hwnd, WM_USER, 1, 2, (void *)0xdeadbeef,
FNID_SENDNOTIFYMESSAGE, FALSE );
ok( res == 1, "res = %Iu\n", res );
res = NtUserMessageCall( hwnd, WM_USER, 1, 2, &callback_params,
FNID_SENDMESSAGECALLBACK, FALSE );
todo_wine
ok( res == 1, "res = %Iu\n", res );
DestroyWindow( hwnd );
UnregisterClassW( L"TestClass", NULL );
}
START_TEST(win32u) START_TEST(win32u)
{ {
/* native win32u.dll fails if user32 is not loaded, so make sure it's fully initialized */ /* native win32u.dll fails if user32 is not loaded, so make sure it's fully initialized */
@ -391,6 +487,7 @@ START_TEST(win32u)
test_class(); test_class();
test_NtUserBuildHwndList(); test_NtUserBuildHwndList();
test_cursoricon(); test_cursoricon();
test_message_call();
test_NtUserCloseWindowStation(); test_NtUserCloseWindowStation();
} }

View File

@ -236,8 +236,8 @@ struct unix_funcs
BOOL (WINAPI *pNtUserGetUpdatedClipboardFormats)( UINT *formats, UINT size, UINT *out_size ); BOOL (WINAPI *pNtUserGetUpdatedClipboardFormats)( UINT *formats, UINT size, UINT *out_size );
BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format ); BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format );
UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout ); UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout );
BOOL (WINAPI *pNtUserMessageCall)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, LRESULT (WINAPI *pNtUserMessageCall)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
ULONG_PTR result_info, DWORD type, BOOL ansi ); void *result_info, DWORD type, BOOL ansi );
BOOL (WINAPI *pNtUserMoveWindow)( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint ); BOOL (WINAPI *pNtUserMoveWindow)( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint );
DWORD (WINAPI *pNtUserMsgWaitForMultipleObjectsEx)( DWORD count, const HANDLE *handles, DWORD (WINAPI *pNtUserMsgWaitForMultipleObjectsEx)( DWORD count, const HANDLE *handles,
DWORD timeout, DWORD mask, DWORD flags ); DWORD timeout, DWORD mask, DWORD flags );

View File

@ -4667,7 +4667,6 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name,
DPI_AWARENESS_CONTEXT context; DPI_AWARENESS_CONTEXT context;
HWND hwnd, owner = 0; HWND hwnd, owner = 0;
INT sw = SW_SHOW; INT sw = SW_SHOW;
LRESULT result;
RECT rect; RECT rect;
WND *win; WND *win;
@ -4846,8 +4845,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name,
TRACE( "hwnd %p cs %d,%d %dx%d %s\n", hwnd, cs.x, cs.y, cs.cx, cs.cy, wine_dbgstr_rect(&rect) ); TRACE( "hwnd %p cs %d,%d %dx%d %s\n", hwnd, cs.x, cs.y, cs.cx, cs.cy, wine_dbgstr_rect(&rect) );
*client_cs = cs; *client_cs = cs;
if (!NtUserMessageCall( hwnd, WM_NCCREATE, 0, (LPARAM)client_cs, (ULONG_PTR)&result, if (!NtUserMessageCall( hwnd, WM_NCCREATE, 0, (LPARAM)client_cs, NULL, FNID_SENDMESSAGE, ansi ))
FNID_SENDMESSAGE, ansi ) || !result)
{ {
WARN( "%p: aborted by WM_NCCREATE\n", hwnd ); WARN( "%p: aborted by WM_NCCREATE\n", hwnd );
goto failed; goto failed;
@ -4879,8 +4877,8 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name,
else goto failed; else goto failed;
/* send WM_CREATE */ /* send WM_CREATE */
if (!NtUserMessageCall( hwnd, WM_CREATE, 0, (LPARAM)client_cs, (ULONG_PTR)&result, if (NtUserMessageCall( hwnd, WM_CREATE, 0, (LPARAM)client_cs, 0, FNID_SENDMESSAGE, ansi ) == -1)
FNID_SENDMESSAGE, ansi ) || result == -1) goto failed; goto failed;
cs = *client_cs; cs = *client_cs;
/* call the driver */ /* call the driver */

View File

@ -957,8 +957,8 @@ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout )
return unix_funcs->pNtUserMapVirtualKeyEx( code, type, layout ); return unix_funcs->pNtUserMapVirtualKeyEx( code, type, layout );
} }
BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
ULONG_PTR result_info, DWORD type, BOOL ansi ) void *result_info, DWORD type, BOOL ansi )
{ {
if (!unix_funcs) return 0; if (!unix_funcs) return 0;
return unix_funcs->pNtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi ); return unix_funcs->pNtUserMessageCall( hwnd, msg, wparam, lparam, result_info, type, ansi );

View File

@ -239,12 +239,27 @@ enum
/* NtUserMessageCall codes */ /* NtUserMessageCall codes */
enum enum
{ {
FNID_CALLWNDPROC = 0x02ab, FNID_CALLWNDPROC = 0x02ab,
FNID_SENDMESSAGE = 0x02b1, FNID_SENDMESSAGE = 0x02b1,
FNID_SENDNOTIFYMESSAGE = 0x02b7, FNID_SENDMESSAGEWTOOPTION = 0x02b3,
FNID_SENDNOTIFYMESSAGE = 0x02b7,
FNID_SENDMESSAGECALLBACK = 0x02b8,
/* Wine-specific exports */ /* Wine-specific exports */
FNID_SPYENTER = 0x0300, FNID_SPYENTER = 0x0300,
FNID_SPYEXIT = 0x0301, FNID_SPYEXIT = 0x0301,
};
struct send_message_timeout_params
{
UINT flags;
UINT timeout;
DWORD_PTR result;
};
struct send_message_callback_params
{
SENDASYNCPROC callback;
ULONG_PTR data;
}; };
/* color index used to retrieve system 55aa brush */ /* color index used to retrieve system 55aa brush */
@ -582,8 +597,8 @@ INT WINAPI NtUserInternalGetWindowText( HWND hwnd, WCHAR *text, INT count );
BOOL WINAPI NtUserIsClipboardFormatAvailable( UINT format ); BOOL WINAPI NtUserIsClipboardFormatAvailable( UINT format );
BOOL WINAPI NtUserKillTimer( HWND hwnd, UINT_PTR id ); BOOL WINAPI NtUserKillTimer( HWND hwnd, UINT_PTR id );
UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout ); UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout );
BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
ULONG_PTR result_info, DWORD type, BOOL ansi ); void *result_info, DWORD type, BOOL ansi );
BOOL WINAPI NtUserMoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint ); BOOL WINAPI NtUserMoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint );
DWORD WINAPI NtUserMsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD WINAPI NtUserMsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
DWORD timeout, DWORD mask, DWORD flags ); DWORD timeout, DWORD mask, DWORD flags );