win32u: Move SendMessageTimeoutW implementation from user32.

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:43 +02:00 committed by Alexandre Julliard
parent dca49630a9
commit 74da33b791
9 changed files with 141 additions and 27 deletions

View File

@ -2183,17 +2183,12 @@ static BOOL send_message( struct send_message_info *info, DWORD_PTR *res_ptr, BO
LRESULT WINAPI SendMessageTimeoutW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
UINT flags, UINT timeout, PDWORD_PTR res_ptr )
{
struct send_message_info info;
struct send_message_timeout_params params = { .flags = flags, .timeout = timeout };
LRESULT res;
info.type = MSG_UNICODE;
info.hwnd = hwnd;
info.msg = msg;
info.wparam = wparam;
info.lparam = lparam;
info.flags = flags;
info.timeout = timeout;
return send_message( &info, res_ptr, TRUE );
res = NtUserMessageCall( hwnd, msg, wparam, lparam, &params, FNID_SENDMESSAGEWTOOPTION, FALSE );
if (res_ptr) *res_ptr = res;
return params.result;
}
/***********************************************************************

View File

@ -165,7 +165,6 @@ static const struct user_callbacks user_funcs =
EndMenu,
HideCaret,
PostMessageW,
SendMessageTimeoutW,
SendMessageA,
SendMessageW,
SendNotifyMessageW,

View File

@ -1352,9 +1352,9 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
if (hwnd)
{
/* send palette messages */
if (send_message( hwnd, WM_QUERYNEWPALETTE, 0, 0 ) && user_callbacks)
user_callbacks->pSendMessageTimeoutW( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)hwnd, 0,
SMTO_ABORTIFHUNG, 2000, NULL );
if (send_message( hwnd, WM_QUERYNEWPALETTE, 0, 0 ))
send_message_timeout( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)hwnd, 0,
SMTO_ABORTIFHUNG, 2000, NULL, FALSE );
if (!is_window(hwnd)) return FALSE;
}

View File

@ -2035,6 +2035,105 @@ LRESULT WINAPI NtUserDispatchMessage( const MSG *msg )
return dispatch_message( msg, FALSE );
}
static BOOL is_message_broadcastable( UINT msg )
{
return msg < WM_USER || msg >= 0xc000;
}
/***********************************************************************
* broadcast_message
*/
static BOOL broadcast_message( struct send_message_info *info, DWORD_PTR *res_ptr )
{
if (is_message_broadcastable( info->msg ))
{
HWND *list = list_window_children( 0, get_desktop_window(), NULL, 0 );
int i;
for (i = 0; list[i]; i++)
{
if (!is_window(list[i])) continue;
if ((get_window_long( list[i], GWL_STYLE ) & (WS_POPUP|WS_CHILD)) == WS_CHILD)
continue;
switch(info->type)
{
case MSG_UNICODE:
send_message_timeout( list[i], info->msg, info->wparam, info->lparam,
info->flags, info->timeout, NULL, FALSE );
break;
case MSG_ASCII:
send_message_timeout( list[i], info->msg, info->wparam, info->lparam,
info->flags, info->timeout, NULL, TRUE );
break;
case MSG_NOTIFY:
NtUserMessageCall( list[i], info->msg, info->wparam, info->lparam,
0, FNID_SENDNOTIFYMESSAGE, FALSE );
break;
case MSG_CALLBACK:
{
struct send_message_callback_params params =
{ .callback = info->callback, .data = info->data };
NtUserMessageCall( list[i], info->msg, info->wparam, info->lparam,
&params, FNID_SENDMESSAGECALLBACK, FALSE );
break;
}
case MSG_POSTED:
NtUserPostMessage( list[i], info->msg, info->wparam, info->lparam );
break;
default:
ERR( "bad type %d\n", info->type );
break;
}
}
}
if (res_ptr) *res_ptr = 1;
return TRUE;
}
/***********************************************************************
* process_message
*
* Backend implementation of the various SendMessage functions.
*/
static BOOL process_message( struct send_message_info *info, DWORD_PTR *res_ptr, BOOL ansi )
{
struct user_thread_info *thread_info = get_user_thread_info();
INPUT_MESSAGE_SOURCE prev_source = thread_info->msg_source;
DWORD dest_pid;
BOOL ret;
LRESULT result;
if (is_broadcast( info->hwnd )) return broadcast_message( info, res_ptr );
if (!(info->dest_tid = get_window_thread( info->hwnd, &dest_pid ))) return FALSE;
if (is_exiting_thread( info->dest_tid )) return FALSE;
thread_info->msg_source = msg_source_unavailable;
spy_enter_message( SPY_SENDMESSAGE, info->hwnd, info->msg, info->wparam, info->lparam );
if (info->dest_tid == GetCurrentThreadId())
{
result = call_window_proc( info->hwnd, info->msg, info->wparam, info->lparam,
!ansi, TRUE, info->wm_char, FALSE, NULL, 0 );
if (info->type == MSG_CALLBACK)
call_sendmsg_callback( info->callback, info->hwnd, info->msg, info->data, result );
ret = TRUE;
}
else
{
if (dest_pid != GetCurrentProcessId() && (info->type == MSG_ASCII || info->type == MSG_UNICODE))
info->type = MSG_OTHER_PROCESS;
ret = send_inter_thread_message( info, &result );
}
spy_exit_message( SPY_RESULT_OK, info->hwnd, info->msg, result, info->wparam, info->lparam );
thread_info->msg_source = prev_source;
if (ret && res_ptr) *res_ptr = result;
return ret;
}
/***********************************************************************
* NtUserSetTimer (win32u.@)
*/
@ -2142,6 +2241,24 @@ static LRESULT send_window_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
: user_callbacks->pSendMessageW( hwnd, msg, wparam, lparam );
}
/* see SendMessageTimeoutW */
LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
UINT flags, UINT timeout, DWORD_PTR *res_ptr, BOOL ansi )
{
struct send_message_info info;
info.type = ansi ? MSG_ASCII : MSG_UNICODE;
info.hwnd = hwnd;
info.msg = msg;
info.wparam = wparam;
info.lparam = lparam;
info.flags = flags;
info.timeout = timeout;
info.wm_char = WMCHAR_MAP_SENDMESSAGETIMEOUT;
return process_message( &info, res_ptr, ansi );
}
/* see SendMessageW */
LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
@ -2174,6 +2291,14 @@ LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa
wparam, lparam, ansi );
case FNID_SENDMESSAGE:
return send_window_message( hwnd, msg, wparam, lparam, ansi );
case FNID_SENDMESSAGEWTOOPTION:
{
struct send_message_timeout_params *params = (void *)result_info;
DWORD_PTR res = 0;
params->result = send_message_timeout( hwnd, msg, wparam, lparam, params->flags,
params->timeout, &res, ansi );
return res;
}
case FNID_SENDNOTIFYMESSAGE:
return send_notify_message( hwnd, msg, wparam, lparam, ansi );
case FNID_SPYENTER:

View File

@ -38,7 +38,6 @@ struct user_callbacks
BOOL (WINAPI *pEndMenu)(void);
BOOL (WINAPI *pHideCaret)( HWND hwnd );
BOOL (WINAPI *pPostMessageW)( HWND, UINT, WPARAM, LPARAM );
LRESULT (WINAPI *pSendMessageTimeoutW)( HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
LRESULT (WINAPI *pSendMessageA)( HWND, UINT, WPARAM, LPARAM );
LRESULT (WINAPI *pSendMessageW)( HWND, UINT, WPARAM, LPARAM );
BOOL (WINAPI *pSendNotifyMessageW)( HWND, UINT, WPARAM, LPARAM );

View File

@ -583,9 +583,8 @@ UINT realize_palette( HDC hdc )
{
/* send palette change notification */
HWND hwnd = NtUserWindowFromDC( hdc );
if (hwnd) user_callbacks->pSendMessageTimeoutW( HWND_BROADCAST, WM_PALETTECHANGED,
HandleToUlong(hwnd), 0, SMTO_ABORTIFHUNG,
2000, NULL );
if (hwnd) send_message_timeout( HWND_BROADCAST, WM_PALETTECHANGED, HandleToUlong(hwnd), 0,
SMTO_ABORTIFHUNG, 2000, NULL, FALSE );
}
return realized;
}

View File

@ -4103,9 +4103,8 @@ BOOL WINAPI NtUserSystemParametersInfo( UINT action, UINT val, void *ptr, UINT w
{
static const WCHAR emptyW[1];
if (winini & (SPIF_SENDWININICHANGE | SPIF_SENDCHANGE))
user_callbacks->pSendMessageTimeoutW( HWND_BROADCAST, WM_SETTINGCHANGE,
action, (LPARAM) emptyW,
SMTO_ABORTIFHUNG, 2000, NULL );
send_message_timeout( HWND_BROADCAST, WM_SETTINGCHANGE, action, (LPARAM) emptyW,
SMTO_ABORTIFHUNG, 2000, NULL, FALSE );
}
TRACE( "(%u, %u, %p, %u) ret %d\n", action, val, ptr, winini, ret );
return ret;
@ -4547,8 +4546,8 @@ BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *va
set_entry( &system_colors[colors[i]], values[i], 0, 0 );
/* Send WM_SYSCOLORCHANGE message to all windows */
user_callbacks->pSendMessageTimeoutW( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0,
SMTO_ABORTIFHUNG, 2000, NULL );
send_message_timeout( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0,
SMTO_ABORTIFHUNG, 2000, NULL, FALSE );
/* Repaint affected portions of all visible windows */
NtUserRedrawWindow( 0, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
return TRUE;

View File

@ -449,9 +449,7 @@ static void test_message_call(void)
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;
@ -459,9 +457,7 @@ static void test_message_call(void)
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,

View File

@ -358,6 +358,8 @@ extern LRESULT send_internal_message_timeout( DWORD dest_pid, DWORD dest_tid, UI
LPARAM lparam, UINT flags, UINT timeout,
PDWORD_PTR res_ptr ) DECLSPEC_HIDDEN;
extern LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
extern LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
UINT flags, UINT timeout, PDWORD_PTR res_ptr, BOOL ansi );
/* sysparams.c */
extern BOOL enable_thunk_lock DECLSPEC_HIDDEN;