Alexandre Julliard : user32: Prevent changing some window styles through SetWindowLong.

Alexandre Julliard julliard at winehq.org
Wed Sep 1 11:08:53 CDT 2010


Module: wine
Branch: master
Commit: cd79ec79a688fabdd71f71ad1a2bb01035021515
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cd79ec79a688fabdd71f71ad1a2bb01035021515

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Aug 31 22:18:09 2010 +0200

user32: Prevent changing some window styles through SetWindowLong.

---

 dlls/user32/tests/win.c |   19 +++++++++++++++++++
 dlls/user32/win.c       |   26 ++++++++++++++++++++------
 2 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 3af8d75..5dd1126 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -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);
 }
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index cbc949c..6082b80 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -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 );
     }




More information about the wine-cvs mailing list