user32: Add tests for UpdateLayeredWindowIndirect and fix the behavior of the ULW_EX_NORESIZE flag.
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index cdd0cbc..e84824d 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -50,6 +50,7 @@
static BOOL (WINAPI *pGetLayeredWindowAttributes)(HWND,COLORREF*,BYTE*,DWORD*);
static BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
static BOOL (WINAPI *pUpdateLayeredWindow)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
+static BOOL (WINAPI *pUpdateLayeredWindowIndirect)(HWND,const UPDATELAYEREDWINDOWINFO*);
static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO);
static HMONITOR (WINAPI *pMonitorFromPoint)(POINT,DWORD);
static int (WINAPI *pGetWindowRgnBox)(HWND,LPRECT);
@@ -6074,6 +6075,47 @@
ok( !ret, "GetLayeredWindowAttributes should fail on layered but not initialized window\n" );
ret = pUpdateLayeredWindow( hwnd, 0, NULL, &sz, hdc, &pt, 0, NULL, ULW_OPAQUE );
ok( ret, "UpdateLayeredWindow should succeed on layered window\n" );
+ ret = pUpdateLayeredWindow( hwnd, 0, NULL, &sz, hdc, &pt, 0, NULL, ULW_OPAQUE | ULW_EX_NORESIZE );
+ ok( !ret, "UpdateLayeredWindow should fail with ex flag\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+ if (pUpdateLayeredWindowIndirect)
+ {
+ UPDATELAYEREDWINDOWINFO info;
+ info.cbSize = sizeof(info);
+ info.hdcDst = 0;
+ info.pptDst = NULL;
+ info.psize = &sz;
+ info.hdcSrc = hdc;
+ info.pptSrc = &pt;
+ info.crKey = 0;
+ info.pblend = NULL;
+ info.dwFlags = ULW_OPAQUE | ULW_EX_NORESIZE;
+ info.prcDirty = NULL;
+ ret = pUpdateLayeredWindowIndirect( hwnd, &info );
+ ok( ret, "UpdateLayeredWindowIndirect should succeed on layered window\n" );
+ sz.cx--;
+ ret = pUpdateLayeredWindowIndirect( hwnd, &info );
+ ok( !ret, "UpdateLayeredWindowIndirect should fail\n" );
+ ok( GetLastError() == ERROR_INCORRECT_SIZE || broken(GetLastError() == ERROR_MR_MID_NOT_FOUND),
+ "wrong error %u\n", GetLastError() );
+ info.dwFlags = ULW_OPAQUE;
+ ret = pUpdateLayeredWindowIndirect( hwnd, &info );
+ ok( ret, "UpdateLayeredWindowIndirect should succeed on layered window\n" );
+ sz.cx++;
+ info.dwFlags = ULW_OPAQUE | 0xf00;
+ ret = pUpdateLayeredWindowIndirect( hwnd, &info );
+ ok( !ret, "UpdateLayeredWindowIndirect should fail\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+ info.cbSize--;
+ info.dwFlags = ULW_OPAQUE;
+ ret = pUpdateLayeredWindowIndirect( hwnd, &info );
+ ok( !ret, "UpdateLayeredWindowIndirect should fail\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+ ret = pUpdateLayeredWindowIndirect( hwnd, NULL );
+ ok( !ret, "UpdateLayeredWindowIndirect should fail\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+ }
+
ret = pSetLayeredWindowAttributes( hwnd, 0x654321, 22, LWA_COLORKEY | LWA_ALPHA );
ok( ret, "SetLayeredWindowAttributes should succeed on layered window\n" );
ret = pGetLayeredWindowAttributes( hwnd, &key, &alpha, &flags );
@@ -7072,6 +7114,7 @@
pGetLayeredWindowAttributes = (void *)GetProcAddress( user32, "GetLayeredWindowAttributes" );
pSetLayeredWindowAttributes = (void *)GetProcAddress( user32, "SetLayeredWindowAttributes" );
pUpdateLayeredWindow = (void *)GetProcAddress( user32, "UpdateLayeredWindow" );
+ pUpdateLayeredWindowIndirect = (void *)GetProcAddress( user32, "UpdateLayeredWindowIndirect" );
pGetMonitorInfoA = (void *)GetProcAddress( user32, "GetMonitorInfoA" );
pMonitorFromPoint = (void *)GetProcAddress( user32, "MonitorFromPoint" );
pGetWindowRgnBox = (void *)GetProcAddress( user32, "GetWindowRgnBox" );
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 95c5c4e..8818868 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -3583,50 +3583,55 @@
*/
BOOL WINAPI UpdateLayeredWindowIndirect( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info )
{
+ DWORD flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW;
+ RECT window_rect, client_rect;
+ SIZE offset;
BYTE alpha = 0xff;
- if (!(GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED) ||
+ if (!info ||
+ info->cbSize != sizeof(*info) ||
+ info->dwFlags & ~(ULW_COLORKEY | ULW_ALPHA | ULW_OPAQUE | ULW_EX_NORESIZE) ||
+ !(GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED) ||
GetLayeredWindowAttributes( hwnd, NULL, NULL, NULL ))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
- if (!(info->dwFlags & ULW_EX_NORESIZE) && (info->pptDst || info->psize))
+ WIN_GetRectangles( hwnd, COORDS_PARENT, &window_rect, &client_rect );
+
+ if (info->pptDst)
{
- DWORD flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE;
- RECT window_rect, client_rect;
- SIZE offset;
-
- WIN_GetRectangles( hwnd, COORDS_PARENT, &window_rect, &client_rect );
-
- if (info->pptDst)
- {
- offset.cx = info->pptDst->x - window_rect.left;
- offset.cy = info->pptDst->y - window_rect.top;
- OffsetRect( &client_rect, offset.cx, offset.cy );
- OffsetRect( &window_rect, offset.cx, offset.cy );
- flags &= ~SWP_NOMOVE;
- }
- if (info->psize)
- {
- if (info->psize->cx <= 0 || info->psize->cy <= 0)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- return FALSE;
- }
- offset.cx = info->psize->cx - (window_rect.right - window_rect.left);
- offset.cy = info->psize->cy - (window_rect.bottom - window_rect.top);
- client_rect.right += offset.cx;
- client_rect.bottom += offset.cy;
- window_rect.right += offset.cx;
- window_rect.bottom += offset.cy;
- flags &= ~SWP_NOSIZE;
- }
- TRACE( "moving window %p win %s client %s\n", hwnd,
- wine_dbgstr_rect(&window_rect), wine_dbgstr_rect(&client_rect) );
- set_window_pos( hwnd, 0, flags, &window_rect, &client_rect, NULL );
+ offset.cx = info->pptDst->x - window_rect.left;
+ offset.cy = info->pptDst->y - window_rect.top;
+ OffsetRect( &client_rect, offset.cx, offset.cy );
+ OffsetRect( &window_rect, offset.cx, offset.cy );
+ flags &= ~SWP_NOMOVE;
}
+ if (info->psize)
+ {
+ offset.cx = info->psize->cx - (window_rect.right - window_rect.left);
+ offset.cy = info->psize->cy - (window_rect.bottom - window_rect.top);
+ if (info->psize->cx <= 0 || info->psize->cy <= 0)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ if ((info->dwFlags & ULW_EX_NORESIZE) && (offset.cx || offset.cy))
+ {
+ SetLastError( ERROR_INCORRECT_SIZE );
+ return FALSE;
+ }
+ client_rect.right += offset.cx;
+ client_rect.bottom += offset.cy;
+ window_rect.right += offset.cx;
+ window_rect.bottom += offset.cy;
+ flags &= ~SWP_NOSIZE;
+ }
+
+ TRACE( "window %p win %s client %s\n", hwnd,
+ wine_dbgstr_rect(&window_rect), wine_dbgstr_rect(&client_rect) );
+ set_window_pos( hwnd, 0, flags, &window_rect, &client_rect, NULL );
if (info->hdcSrc)
{
@@ -3668,10 +3673,15 @@
*/
BOOL WINAPI UpdateLayeredWindow( HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize,
HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend,
- DWORD dwFlags)
+ DWORD flags)
{
UPDATELAYEREDWINDOWINFO info;
+ if (flags & ULW_EX_NORESIZE) /* only valid for UpdateLayeredWindowIndirect */
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
info.cbSize = sizeof(info);
info.hdcDst = hdcDst;
info.pptDst = pptDst;
@@ -3680,7 +3690,7 @@
info.pptSrc = pptSrc;
info.crKey = crKey;
info.pblend = pblend;
- info.dwFlags = dwFlags;
+ info.dwFlags = flags;
info.prcDirty = NULL;
return UpdateLayeredWindowIndirect( hwnd, &info );
}
diff --git a/include/winerror.h b/include/winerror.h
index df67e3c..0b9a59e 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -871,6 +871,15 @@
#define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION 1459
#define ERROR_TIMEOUT 1460
#define ERROR_INVALID_MONITOR_HANDLE 1461
+#define ERROR_INCORRECT_SIZE 1462
+#define ERROR_SYMLINK_CLASS_DISABLED 1463
+#define ERROR_SYMLINK_NOT_SUPPORTED 1464
+#define ERROR_XML_PARSE_ERROR 1465
+#define ERROR_XMLDSIG_ERROR 1466
+#define ERROR_RESTART_APPLICATION 1467
+#define ERROR_WRONG_COMPARTMENT 1468
+#define ERROR_AUTHIP_FAILURE 1469
+#define ERROR_NO_NVRAM_RESOURCES 1470
#define ERROR_EVENTLOG_FILE_CORRUPT 1500
#define ERROR_EVENTLOG_CANT_START 1501
#define ERROR_LOG_FILE_FULL 1502