Commit caec6026 authored by Robert Shearman's avatar Robert Shearman Committed by Alexandre Julliard

- Window styles passed to CreateWindowEx must the same as passed in

CREATESTRUCT for WM_CREATE/WM_NCCREATE. - Fix cases where WS_EX_WINDOWEDGE style is applied. - Tests for the above.
parent 6d32d639
...@@ -2471,6 +2471,116 @@ todo_wine { ...@@ -2471,6 +2471,116 @@ todo_wine {
ok(!IsWindow(child4), "child4 still exists\n"); ok(!IsWindow(child4), "child4 still exists\n");
} }
static LRESULT WINAPI StyleCheckProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
LPCREATESTRUCT lpcs;
LPSTYLESTRUCT lpss;
switch (msg)
{
case WM_NCCREATE:
case WM_CREATE:
lpcs = (LPCREATESTRUCT)lparam;
lpss = (LPSTYLESTRUCT)lpcs->lpCreateParams;
if (lpss)
{
if ((lpcs->dwExStyle & WS_EX_DLGMODALFRAME) ||
((!(lpcs->dwExStyle & WS_EX_STATICEDGE)) &&
(lpcs->style & (WS_DLGFRAME | WS_THICKFRAME))))
ok(lpcs->dwExStyle & WS_EX_WINDOWEDGE, "Window should have WS_EX_WINDOWEDGE style\n");
else
ok(!(lpcs->dwExStyle & WS_EX_WINDOWEDGE), "Window shouldn't have WS_EX_WINDOWEDGE style\n");
ok((lpss->styleOld & ~WS_EX_WINDOWEDGE) == (lpcs->dwExStyle & ~WS_EX_WINDOWEDGE),
"Ex style (0x%08lx) should match what the caller passed to CreateWindowEx (0x%08lx)\n",
(lpss->styleOld & ~WS_EX_WINDOWEDGE), (lpcs->dwExStyle & ~WS_EX_WINDOWEDGE));
ok(lpss->styleNew == lpcs->style,
"Style (0x%08lx) should match what the caller passed to CreateWindowEx (0x%08lx)\n",
lpss->styleNew, lpcs->style);
}
break;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
static ATOM atomStyleCheckClass;
static void register_style_check_class(void)
{
WNDCLASS wc =
{
0,
StyleCheckProc,
0,
0,
GetModuleHandle(NULL),
NULL,
LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_BTNFACE+1),
NULL,
TEXT("WineStyleCheck"),
};
atomStyleCheckClass = RegisterClass(&wc);
}
static void check_window_style(DWORD dwStyleIn, DWORD dwExStyleIn, DWORD dwStyleOut, DWORD dwExStyleOut)
{
DWORD dwActualStyle;
DWORD dwActualExStyle;
STYLESTRUCT ss;
HWND hwnd;
HWND hwndParent = NULL;
MSG msg;
ss.styleNew = dwStyleIn;
ss.styleOld = dwExStyleIn;
if (dwStyleIn & WS_CHILD)
{
hwndParent = CreateWindowEx(0, MAKEINTATOM(atomStyleCheckClass), NULL,
WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
}
hwnd = CreateWindowEx(dwExStyleIn, MAKEINTATOM(atomStyleCheckClass), NULL,
dwStyleIn, 0, 0, 0, 0, hwndParent, NULL, NULL, &ss);
assert(hwnd);
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
dwActualStyle = GetWindowLong(hwnd, GWL_STYLE);
dwActualExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
ok((dwActualStyle == dwStyleOut) && (dwActualExStyle == dwExStyleOut),
"Style (0x%08lx) should really be 0x%08lx and/or Ex style (0x%08lx) should really be 0x%08lx\n",
dwActualStyle, dwStyleOut, dwActualExStyle, dwExStyleOut);
DestroyWindow(hwnd);
if (hwndParent) DestroyWindow(hwndParent);
}
/* tests what window styles the window manager automatically adds */
static void test_window_styles()
{
register_style_check_class();
check_window_style(0, 0, WS_CLIPSIBLINGS|WS_CAPTION, WS_EX_WINDOWEDGE);
check_window_style(WS_OVERLAPPEDWINDOW, 0, WS_CLIPSIBLINGS|WS_OVERLAPPEDWINDOW, WS_EX_WINDOWEDGE);
check_window_style(WS_CHILD, 0, WS_CHILD, 0);
check_window_style(WS_CHILD, WS_EX_WINDOWEDGE, WS_CHILD, 0);
check_window_style(0, WS_EX_TOOLWINDOW, WS_CLIPSIBLINGS|WS_CAPTION, WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW);
check_window_style(WS_POPUP, 0, WS_POPUP|WS_CLIPSIBLINGS, 0);
check_window_style(WS_POPUP, WS_EX_WINDOWEDGE, WS_POPUP|WS_CLIPSIBLINGS, 0);
check_window_style(WS_CHILD, WS_EX_DLGMODALFRAME, WS_CHILD, WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME);
check_window_style(WS_CHILD, WS_EX_DLGMODALFRAME|WS_EX_STATICEDGE, WS_CHILD, WS_EX_STATICEDGE|WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME);
check_window_style(WS_CAPTION, WS_EX_STATICEDGE, WS_CLIPSIBLINGS|WS_CAPTION, WS_EX_STATICEDGE|WS_EX_WINDOWEDGE);
check_window_style(0, WS_EX_APPWINDOW, WS_CLIPSIBLINGS|WS_CAPTION, WS_EX_APPWINDOW|WS_EX_WINDOWEDGE);
}
START_TEST(win) START_TEST(win)
{ {
pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" ); pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
...@@ -2531,4 +2641,6 @@ START_TEST(win) ...@@ -2531,4 +2641,6 @@ START_TEST(win)
test_nccalcscroll( hwndMain); test_nccalcscroll( hwndMain);
UnhookWindowsHookEx(hhook); UnhookWindowsHookEx(hhook);
test_window_styles();
} }
...@@ -871,6 +871,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode ) ...@@ -871,6 +871,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
RECT rect; RECT rect;
DWORD style; DWORD style;
CBT_CREATEWNDA cbtc; CBT_CREATEWNDA cbtc;
CREATESTRUCTA cbcs;
BOOL ret = FALSE; BOOL ret = FALSE;
if (cs->cx > 65535) if (cs->cx > 65535)
...@@ -926,7 +927,15 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode ) ...@@ -926,7 +927,15 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
} }
/* Call the WH_CBT hook */ /* Call the WH_CBT hook */
cbtc.lpcs = cs;
/* the window style passed to the hook must be the real window style,
* rather than just the window style that the caller to CreateWindowEx
* passed in, so we have to copy the original CREATESTRUCT and get the
* the real style. */
cbcs = *cs;
cbcs.style = GetWindowLongW(hwnd, GWL_STYLE);
cbtc.lpcs = &cbcs;
cbtc.hwndInsertAfter = HWND_TOP; cbtc.hwndInsertAfter = HWND_TOP;
if (HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, unicode )) if (HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, unicode ))
{ {
......
...@@ -1111,18 +1111,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, ...@@ -1111,18 +1111,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
WIN_FixCoordinates(cs, &sw); /* fix default coordinates */ WIN_FixCoordinates(cs, &sw); /* fix default coordinates */
/* Correct the window styles.
*
* It affects both the style loaded into the WIN structure and
* passed in the CREATESTRUCT to the WM_[NC]CREATE.
*
* WS_EX_WINDOWEDGE appears to be enforced based on the other styles, so
* why does the user get to set it?
*/
/* This has been tested for WS_CHILD | WS_VISIBLE. It has not been
* tested for WS_POPUP
*/
if ((cs->dwExStyle & WS_EX_DLGMODALFRAME) || if ((cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
((!(cs->dwExStyle & WS_EX_STATICEDGE)) && ((!(cs->dwExStyle & WS_EX_STATICEDGE)) &&
(cs->style & (WS_DLGFRAME | WS_THICKFRAME)))) (cs->style & (WS_DLGFRAME | WS_THICKFRAME))))
...@@ -1130,13 +1118,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, ...@@ -1130,13 +1118,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
else else
cs->dwExStyle &= ~WS_EX_WINDOWEDGE; cs->dwExStyle &= ~WS_EX_WINDOWEDGE;
if (!(cs->style & WS_CHILD))
{
cs->style |= WS_CLIPSIBLINGS;
if (!(cs->style & WS_POPUP))
cs->style |= WS_CAPTION;
}
/* Create the window structure */ /* Create the window structure */
if (!(wndPtr = create_window_handle( parent, owner, classAtom, cs->hInstance, type ))) if (!(wndPtr = create_window_handle( parent, owner, classAtom, cs->hInstance, type )))
...@@ -1165,7 +1146,31 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, ...@@ -1165,7 +1146,31 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
wndPtr->hIconSmall = 0; wndPtr->hIconSmall = 0;
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU) ? MENU_GetSysMenu( hwnd, 0 ) : 0; wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU) ? MENU_GetSysMenu( hwnd, 0 ) : 0;
if (!(cs->style & (WS_CHILD | WS_POPUP))) /*
* Correct the window styles.
*
* It affects only the style loaded into the WIN structure.
*/
if (!(wndPtr->dwStyle & WS_CHILD))
{
wndPtr->dwStyle |= WS_CLIPSIBLINGS;
if (!(wndPtr->dwStyle & WS_POPUP))
wndPtr->dwStyle |= WS_CAPTION;
}
/*
* WS_EX_WINDOWEDGE appears to be enforced based on the other styles, so
* why does the user get to set it?
*/
if ((wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) ||
(wndPtr->dwStyle & (WS_DLGFRAME | WS_THICKFRAME)))
wndPtr->dwExStyle |= WS_EX_WINDOWEDGE;
else
wndPtr->dwExStyle &= ~WS_EX_WINDOWEDGE;
if (!(wndPtr->dwStyle & (WS_CHILD | WS_POPUP)))
wndPtr->flags |= WIN_NEED_SIZE; wndPtr->flags |= WIN_NEED_SIZE;
SERVER_START_REQ( set_window_info ) SERVER_START_REQ( set_window_info )
......
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