Commit 1e5dc840 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Implement NtUserDispatchMessage.

parent c1a9b0b6
......@@ -3901,30 +3901,7 @@ LRESULT WINAPI DECLSPEC_HOTPATCH DispatchMessageA( const MSG* msg )
return retval;
}
}
if (!msg->hwnd) return 0;
SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message,
msg->wParam, msg->lParam );
if (!WINPROC_call_window( msg->hwnd, msg->message, msg->wParam, msg->lParam,
&retval, FALSE, WMCHAR_MAP_DISPATCHMESSAGE ))
{
if (!IsWindow( msg->hwnd )) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
else SetLastError( ERROR_MESSAGE_SYNC_ONLY );
retval = 0;
}
SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval,
msg->wParam, msg->lParam );
if (msg->message == WM_PAINT)
{
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
NtUserGetUpdateRgn( msg->hwnd, hrgn, TRUE );
DeleteObject( hrgn );
}
return retval;
return NtUserCallOneParam( (UINT_PTR)msg, NtUserDispatchMessageA );
}
......@@ -3972,30 +3949,7 @@ LRESULT WINAPI DECLSPEC_HOTPATCH DispatchMessageW( const MSG* msg )
return retval;
}
}
if (!msg->hwnd) return 0;
SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message,
msg->wParam, msg->lParam );
if (!WINPROC_call_window( msg->hwnd, msg->message, msg->wParam, msg->lParam,
&retval, TRUE, WMCHAR_MAP_DISPATCHMESSAGE ))
{
if (!IsWindow( msg->hwnd )) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
else SetLastError( ERROR_MESSAGE_SYNC_ONLY );
retval = 0;
}
SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval,
msg->wParam, msg->lParam );
if (msg->message == WM_PAINT)
{
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
NtUserGetUpdateRgn( msg->hwnd, hrgn, TRUE );
DeleteObject( hrgn );
}
return retval;
return NtUserDispatchMessage( msg );
}
......
......@@ -195,6 +195,7 @@ static const void *kernel_callback_table[NtUserCallCount] =
{
User32CallEnumDisplayMonitor,
User32CallWinEventHook,
User32CallWindowProc,
User32CallWindowsHook,
User32LoadDriver,
};
......
......@@ -126,6 +126,7 @@ extern ATOM get_class_info( HINSTANCE instance, const WCHAR *name, WNDCLASSEXW *
BOOL WINAPI User32CallEnumDisplayMonitor( struct enum_display_monitor_params *params, ULONG size );
BOOL WINAPI User32CallWinEventHook( const struct win_event_hook_params *params, ULONG size );
BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size );
BOOL WINAPI User32CallWindowsHook( const struct win_hook_params *params, ULONG size );
/* message spy definitions */
......
......@@ -707,8 +707,6 @@ static void dispatch_win_proc_params( struct win_proc_params *params )
{
DPI_AWARENESS_CONTEXT context = SetThreadDpiAwarenessContext( params->dpi_awareness );
USER_CheckNotLock();
if (!params->ansi)
{
if (params->procW == WINPROC_PROC16)
......@@ -791,6 +789,11 @@ static void dispatch_win_proc_params( struct win_proc_params *params )
SetThreadDpiAwarenessContext( context );
}
BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size )
{
dispatch_win_proc_params( params );
return TRUE;
}
/**********************************************************************
* WINPROC_call_window
......@@ -805,6 +808,8 @@ BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
WINDOWPROC *proc;
WND *wndPtr;
USER_CheckNotLock();
if (!(wndPtr = WIN_GetPtr( hwnd ))) return FALSE;
if (wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return FALSE;
if (wndPtr->tid != GetCurrentThreadId())
......
......@@ -1164,6 +1164,7 @@ static struct unix_funcs unix_funcs =
NtUserDeferWindowPosAndBand,
NtUserDestroyCursor,
NtUserDestroyWindow,
NtUserDispatchMessage,
NtUserDrawIconEx,
NtUserEndDeferWindowPosEx,
NtUserEndPaint,
......
......@@ -31,6 +31,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(msg);
#define MAX_WINPROC_RECURSION 64
static BOOL init_win_proc_params( struct win_proc_params *params, HWND hwnd, UINT msg,
WPARAM wparam, LPARAM lparam, BOOL ansi )
......@@ -51,6 +52,53 @@ static BOOL init_win_proc_params( struct win_proc_params *params, HWND hwnd, UIN
return TRUE;
}
static BOOL init_window_call_params( struct win_proc_params *params, HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam, LRESULT *result, BOOL ansi,
enum wm_char_mapping mapping )
{
WND *win;
user_check_not_lock();
if (!(win = get_win_ptr( hwnd ))) return FALSE;
if (win == WND_OTHER_PROCESS || win == WND_DESKTOP) return FALSE;
if (win->tid != GetCurrentThreadId())
{
release_win_ptr( win );
return FALSE;
}
params->func = win->winproc;
params->ansi_dst = !(win->flags & WIN_ISUNICODE);
params->is_dialog = win->dlgInfo != NULL;
release_win_ptr( win );
params->hwnd = get_full_window_handle( hwnd );
get_winproc_params( params );
params->msg = msg;
params->wparam = wParam;
params->lparam = lParam;
params->result = result;
params->ansi = ansi;
params->mapping = mapping;
params->dpi_awareness = get_window_dpi_awareness_context( params->hwnd );
return TRUE;
}
static BOOL dispatch_win_proc_params( struct win_proc_params *params, size_t size )
{
struct user_thread_info *thread_info = get_user_thread_info();
void *ret_ptr;
ULONG ret_len;
if (thread_info->recursion_count > MAX_WINPROC_RECURSION) return FALSE;
thread_info->recursion_count++;
KeUserModeCallback( NtUserCallWindowProc, params, size, &ret_ptr, &ret_len );
thread_info->recursion_count--;
return TRUE;
}
/***********************************************************************
* handle_internal_message
*
......@@ -152,6 +200,63 @@ BOOL WINAPI NtUserGetGUIThreadInfo( DWORD id, GUITHREADINFO *info )
return ret;
}
/**********************************************************************
* dispatch_message
*/
LRESULT dispatch_message( const MSG *msg, BOOL ansi )
{
struct win_proc_params params;
LRESULT retval = 0;
/* Process timer messages */
if (msg->lParam && (msg->message == WM_TIMER || msg->message == WM_SYSTIMER))
{
params.func = (WNDPROC)msg->lParam;
params.result = &retval; /* FIXME */
if (!init_win_proc_params( &params, msg->hwnd, msg->message,
msg->wParam, NtGetTickCount(), ansi ))
return 0;
__TRY
{
dispatch_win_proc_params( &params, sizeof(params) );
}
__EXCEPT
{
retval = 0;
}
__ENDTRY
return retval;
}
if (!msg->hwnd) return 0;
spy_enter_message( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message, msg->wParam, msg->lParam );
if (init_window_call_params( &params, msg->hwnd, msg->message, msg->wParam, msg->lParam,
&retval, ansi, WMCHAR_MAP_DISPATCHMESSAGE ))
dispatch_win_proc_params( &params, sizeof(params) );
else if (!is_window( msg->hwnd )) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
else SetLastError( ERROR_MESSAGE_SYNC_ONLY );
spy_exit_message( SPY_RESULT_OK, msg->hwnd, msg->message, retval, msg->wParam, msg->lParam );
if (msg->message == WM_PAINT)
{
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
HRGN hrgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
NtUserGetUpdateRgn( msg->hwnd, hrgn, TRUE );
NtGdiDeleteObjectApp( hrgn );
}
return retval;
}
/**********************************************************************
* NtUserDispatchMessage (win32u.@)
*/
LRESULT WINAPI NtUserDispatchMessage( const MSG *msg )
{
return dispatch_message( msg, FALSE );
}
/***********************************************************************
* NtUserSetTimer (win32u.@)
*/
......
......@@ -4653,6 +4653,8 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code )
return HandleToUlong( begin_defer_window_pos( arg ));
case NtUserCreateCursorIcon:
return HandleToUlong( alloc_cursoricon_handle( arg ));
case NtUserDispatchMessageA:
return dispatch_message( (const MSG *)arg, TRUE );
case NtUserEnableDC:
return set_dce_flags( UlongToHandle(arg), DCHF_ENABLEDC );
case NtUserGetClipCursor:
......
......@@ -839,7 +839,7 @@
@ stub NtUserDisableProcessWindowFiltering
@ stub NtUserDisableThreadIme
@ stub NtUserDiscardPointerFrameMessages
@ stub NtUserDispatchMessage
@ stdcall NtUserDispatchMessage(ptr)
@ stub NtUserDisplayConfigGetDeviceInfo
@ stub NtUserDisplayConfigSetDeviceInfo
@ stub NtUserDoSoundConnect
......
......@@ -205,6 +205,7 @@ struct unix_funcs
UINT flags, UINT unk1, UINT unk2 );
BOOL (WINAPI *pNtUserDestroyCursor)( HCURSOR cursor, ULONG arg );
BOOL (WINAPI *pNtUserDestroyWindow)( HWND hwnd );
LRESULT (WINAPI *pNtUserDispatchMessage)( const MSG *msg );
BOOL (WINAPI *pNtUserDrawIconEx)( HDC hdc, INT x0, INT y0, HICON icon, INT width,
INT height, UINT istep, HBRUSH hbr, UINT flags );
BOOL (WINAPI *pNtUserEndDeferWindowPosEx)( HDWP hdwp, BOOL async );
......@@ -338,6 +339,7 @@ extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ) DECLSPEC_HIDDEN;
extern HMENU get_menu( HWND hwnd ) DECLSPEC_HIDDEN;
/* message.c */
extern LRESULT dispatch_message( const MSG *msg, BOOL ansi ) DECLSPEC_HIDDEN;
extern BOOL kill_system_timer( HWND hwnd, UINT_PTR id ) DECLSPEC_HIDDEN;
extern LRESULT post_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
extern LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
......
......@@ -801,6 +801,12 @@ BOOL WINAPI NtUserDestroyWindow( HWND hwnd )
return unix_funcs->pNtUserDestroyWindow( hwnd );
}
LRESULT WINAPI NtUserDispatchMessage( const MSG *msg )
{
if (!unix_funcs) return 0;
return unix_funcs->pNtUserDispatchMessage( msg );
}
BOOL WINAPI NtUserDrawIconEx( HDC hdc, INT x0, INT y0, HICON icon, INT width,
INT height, UINT istep, HBRUSH hbr, UINT flags )
{
......
......@@ -29,6 +29,7 @@ enum
/* user32 callbacks */
NtUserCallEnumDisplayMonitor,
NtUserCallWinEventHook,
NtUserCallWindowProc,
NtUserCallWindowsHook,
NtUserLoadDriver,
/* win16 hooks */
......@@ -131,6 +132,7 @@ enum
{
NtUserBeginDeferWindowPos,
NtUserCreateCursorIcon,
NtUserDispatchMessageA,
NtUserEnableDC,
NtUserGetClipCursor,
NtUserGetCursorPos,
......@@ -343,6 +345,7 @@ BOOL WINAPI NtUserDestroyAcceleratorTable( HACCEL handle );
BOOL WINAPI NtUserDestroyCursor( HCURSOR cursor, ULONG arg );
BOOL WINAPI NtUserDestroyMenu( HMENU menu );
BOOL WINAPI NtUserDestroyWindow( HWND hwnd );
LRESULT WINAPI NtUserDispatchMessage( const MSG *msg );
BOOL WINAPI NtUserDrawIconEx( HDC hdc, INT x0, INT y0, HICON icon, INT width,
INT height, UINT istep, HBRUSH hbr, UINT flags );
BOOL WINAPI NtUserEndDeferWindowPosEx( HDWP hdwp, BOOL async );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment