- 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.
This commit is contained in:
Robert Shearman 2005-03-23 10:26:15 +00:00 committed by Alexandre Julliard
parent 6d32d63979
commit caec6026e7
3 changed files with 147 additions and 21 deletions

View File

@ -2471,6 +2471,116 @@ todo_wine {
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)
{
pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
@ -2531,4 +2641,6 @@ START_TEST(win)
test_nccalcscroll( hwndMain);
UnhookWindowsHookEx(hhook);
test_window_styles();
}

View File

@ -871,6 +871,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
RECT rect;
DWORD style;
CBT_CREATEWNDA cbtc;
CREATESTRUCTA cbcs;
BOOL ret = FALSE;
if (cs->cx > 65535)
@ -926,7 +927,15 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
}
/* 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;
if (HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, unicode ))
{

View File

@ -1111,18 +1111,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
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) ||
((!(cs->dwExStyle & WS_EX_STATICEDGE)) &&
(cs->style & (WS_DLGFRAME | WS_THICKFRAME))))
@ -1130,13 +1118,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
else
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 */
if (!(wndPtr = create_window_handle( parent, owner, classAtom, cs->hInstance, type )))
@ -1165,7 +1146,31 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
wndPtr->hIconSmall = 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;
SERVER_START_REQ( set_window_info )