user32: Prevent changing some window styles through SetWindowLong.

This commit is contained in:
Alexandre Julliard 2010-08-31 22:18:09 +02:00
parent 2c08a3fbc7
commit cd79ec79a6
2 changed files with 39 additions and 6 deletions

View File

@ -3491,6 +3491,25 @@ static void check_window_style(DWORD dwStyleIn, DWORD dwExStyleIn, DWORD dwStyle
"Style (0x%08x) should really be 0x%08x and/or Ex style (0x%08x) should really be 0x%08x\n",
dwActualStyle, dwStyleOut, dwActualExStyle, dwExStyleOut);
/* try setting the styles explicitly */
SetWindowLong( hwnd, GWL_EXSTYLE, dwExStyleIn );
SetWindowLong( hwnd, GWL_STYLE, dwStyleIn );
dwActualStyle = GetWindowLong(hwnd, GWL_STYLE);
dwActualExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
/* WS_CLIPSIBLINGS can't be reset on top-level windows */
if (dwStyleIn & WS_CHILD) dwStyleOut = dwStyleIn;
else dwStyleOut = dwStyleIn | WS_CLIPSIBLINGS;
/* WS_EX_WINDOWEDGE can't always be changed */
if ((dwExStyleIn & WS_EX_DLGMODALFRAME) || (dwStyleIn & WS_THICKFRAME))
dwExStyleOut = dwExStyleIn | WS_EX_WINDOWEDGE;
else if (dwStyleIn & (WS_CHILD | WS_POPUP))
dwExStyleOut = dwExStyleIn & ~WS_EX_WINDOWEDGE;
else
dwExStyleOut = dwExStyleIn;
ok((dwActualStyle == dwStyleOut) && (dwActualExStyle == dwExStyleOut),
"%08x/%08x: Style (0x%08x) should really be 0x%08x and/or Ex style (0x%08x) should really be 0x%08x\n",
dwStyleIn, dwExStyleIn, dwActualStyle, dwStyleOut, dwActualExStyle, dwExStyleOut);
DestroyWindow(hwnd);
if (hwndParent) DestroyWindow(hwndParent);
}

View File

@ -2084,14 +2084,28 @@ LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, B
switch( offset )
{
case GWL_STYLE:
case GWL_EXSTYLE:
style.styleOld =
offset == GWL_STYLE ? wndPtr->dwStyle : wndPtr->dwExStyle;
style.styleOld = wndPtr->dwStyle;
style.styleNew = newval;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_STYLECHANGING, offset, (LPARAM)&style );
SendMessageW( hwnd, WM_STYLECHANGING, GWL_STYLE, (LPARAM)&style );
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
newval = style.styleNew;
/* WS_CLIPSIBLINGS can't be reset on top-level windows */
if (wndPtr->parent == GetDesktopWindow()) newval |= WS_CLIPSIBLINGS;
break;
case GWL_EXSTYLE:
style.styleOld = wndPtr->dwExStyle;
style.styleNew = newval;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_STYLECHANGING, GWL_EXSTYLE, (LPARAM)&style );
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
/* WS_EX_TOPMOST can only be changed through SetWindowPos */
newval = (style.styleNew & ~WS_EX_TOPMOST) | (wndPtr->dwExStyle & WS_EX_TOPMOST);
/* WS_EX_WINDOWEDGE depends on some other styles */
if ((newval & WS_EX_DLGMODALFRAME) || (wndPtr->dwStyle & WS_THICKFRAME))
newval |= WS_EX_WINDOWEDGE;
else if (wndPtr->dwStyle & (WS_CHILD|WS_POPUP))
newval &= ~WS_EX_WINDOWEDGE;
break;
case GWLP_HWNDPARENT:
if (wndPtr->parent == GetDesktopWindow())
@ -2165,8 +2179,6 @@ LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, B
break;
case GWL_EXSTYLE:
req->flags = SET_WIN_EXSTYLE;
/* WS_EX_TOPMOST can only be changed through SetWindowPos */
newval = (newval & ~WS_EX_TOPMOST) | (wndPtr->dwExStyle & WS_EX_TOPMOST);
req->ex_style = newval;
break;
case GWLP_ID:
@ -2231,6 +2243,8 @@ LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, B
if (offset == GWL_STYLE || offset == GWL_EXSTYLE)
{
style.styleOld = retval;
style.styleNew = newval;
USER_Driver->pSetWindowStyle( hwnd, offset, &style );
SendMessageW( hwnd, WM_STYLECHANGED, offset, (LPARAM)&style );
}