From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/message.c | 7 +++++ dlls/win32u/spy.c | 1 + dlls/win32u/win32u_private.h | 17 +++++++++++ dlls/win32u/window.c | 57 +++++++++++++++++++++++++++--------- include/ntuser.h | 1 + 5 files changed, 69 insertions(+), 14 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 035ab6574e4..21ab2e87628 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2151,6 +2151,13 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR if (!set_active_window( (HWND)wparam, &prev, FALSE, TRUE, lparam )) return 0; return (LRESULT)prev; } + case WM_WINE_UPDATELAYEREDWINDOW: + { + const struct update_layered_window_params *params = (const struct update_layered_window_params *)lparam; + return update_layered_window( hwnd, params->hdc_dst, params->pts_dst, params->size, + params->hdc_src, params->pts_src, params->key, params->blend, + params->flags, params->dirty ); + } case WM_WINE_KEYBOARD_LL_HOOK: case WM_WINE_MOUSE_LL_HOOK: { diff --git a/dlls/win32u/spy.c b/dlls/win32u/spy.c index 67c6b126922..2f088682148 100644 --- a/dlls/win32u/spy.c +++ b/dlls/win32u/spy.c @@ -1137,6 +1137,7 @@ static const char * const WINEMessageTypeNames[SPY_MAX_WINEMSGNUM + 1] = "WM_WINE_SETWINDOWLONG", "WM_WINE_SETSTYLE", "WM_WINE_SETACTIVEWINDOW", + "WM_WINE_UPDATELAYEREDWINDOW", "WM_WINE_KEYBOARD_LL_HOOK", "WM_WINE_MOUSE_LL_HOOK", "WM_WINE_IME_NOTIFY", diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 4c7ce21d5b4..056ef83cdd4 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -292,6 +292,23 @@ extern HWND get_shell_window(void); extern HWND get_progman_window(void); extern HWND get_taskman_window(void);
+struct update_layered_window_params +{ + HDC hdc_dst; + const POINT *pts_dst; + const SIZE *size; + HDC hdc_src; + const POINT *pts_src; + COLORREF key; + const BLENDFUNCTION *blend; + DWORD flags; + const RECT *dirty; +}; + +extern BOOL update_layered_window( HWND hwnd, HDC hdc_dst, const POINT *pts_dst, const SIZE *size, + HDC hdc_src, const POINT *pts_src, COLORREF key, + const BLENDFUNCTION *blend, DWORD flags, const RECT *dirty ); + /* to release pointers retrieved by win_get_ptr */ static inline void release_win_ptr( struct tagWND *ptr ) { diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 4345c7b7ff4..49fe9060a19 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2446,12 +2446,10 @@ BOOL WINAPI NtUserSetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alph return ret; }
-/***************************************************************************** - * UpdateLayeredWindow (win32u.@) - */ -BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_dst, const SIZE *size, - HDC hdc_src, const POINT *pts_src, COLORREF key, - const BLENDFUNCTION *blend, DWORD flags, const RECT *dirty ) +/* NtUserUpdateLayeredWindow implementation */ +static BOOL update_layered_window( HWND hwnd, HDC hdc_dst, const POINT *pts_dst, const SIZE *size, + HDC hdc_src, const POINT *pts_src, COLORREF key, + const BLENDFUNCTION *blend, DWORD flags, const RECT *dirty ) { DWORD swp_flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW; struct window_rects new_rects; @@ -2460,14 +2458,6 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_ SIZE offset; BOOL ret = FALSE;
- if (flags & ~(ULW_COLORKEY | ULW_ALPHA | ULW_OPAQUE | ULW_EX_NORESIZE) || - !(get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED) || - NtUserGetLayeredWindowAttributes( hwnd, NULL, NULL, NULL )) - { - RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); - return FALSE; - } - get_window_rects( hwnd, COORDS_PARENT, &new_rects, get_thread_dpi() );
if (pts_dst) @@ -2553,6 +2543,45 @@ done: return ret; }
+/***************************************************************************** + * UpdateLayeredWindow (win32u.@) + */ +BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_dst, const SIZE *size, + HDC hdc_src, const POINT *pts_src, COLORREF key, + const BLENDFUNCTION *blend, DWORD flags, const RECT *dirty ) +{ + struct update_layered_window_params params = { hdc_dst, pts_dst, size, hdc_src, pts_src, key, blend, flags, dirty }; + DWORD swp_flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW; + struct window_rects new_rects; + struct window_surface *surface; + RECT surface_rect; + SIZE offset; + BOOL ret = FALSE; + + if (flags & ~(ULW_COLORKEY | ULW_ALPHA | ULW_OPAQUE | ULW_EX_NORESIZE) || + !(get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED) || + NtUserGetLayeredWindowAttributes( hwnd, NULL, NULL, NULL )) + { + RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (!is_current_process_window( hwnd )) + { + FIXME( "Not supported on other process windows\n" ); + RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (!is_current_thread_window( hwnd )) + { + WARN( "Called for other thread window %p\n", hwnd ); + return send_message( hwnd, WM_WINE_UPDATELAYEREDWINDOW, 0, (LPARAM)¶ms ); + } + + return update_layered_window( hwnd, hdc_dst, pts_dst, size, hdc_src, pts_src, key, blend, flags, dirty ); +} + /*********************************************************************** * list_children_from_point * diff --git a/include/ntuser.h b/include/ntuser.h index ef09d7e97bb..5cb11f25f1b 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -633,6 +633,7 @@ enum wine_internal_message WM_WINE_SETWINDOWLONG, WM_WINE_SETSTYLE, WM_WINE_SETACTIVEWINDOW, + WM_WINE_UPDATELAYEREDWINDOW, WM_WINE_KEYBOARD_LL_HOOK, WM_WINE_MOUSE_LL_HOOK, WM_WINE_IME_NOTIFY,