user32: Moved the bulk of CreateWindow and SetWindowPos from the driver back into user32.

This commit is contained in:
Alexandre Julliard 2008-01-24 11:23:09 +01:00
parent a7cdf6e110
commit d6f6745c9c
9 changed files with 175 additions and 188 deletions

View file

@ -318,7 +318,7 @@ static BOOL nulldrv_CreateDesktopWindow( HWND hwnd )
return TRUE;
}
static BOOL nulldrv_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
static BOOL nulldrv_CreateWindow( HWND hwnd )
{
static int warned;
if (warned++)
@ -375,10 +375,10 @@ static void nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
}
static BOOL nulldrv_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
const RECT *rectClient, UINT swp_flags, const RECT *valid_rects )
static void nulldrv_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
const RECT *visible_rect, const RECT *valid_rects )
{
return FALSE;
}
static int nulldrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
@ -658,9 +658,9 @@ static BOOL loaderdrv_CreateDesktopWindow( HWND hwnd )
return load_driver()->pCreateDesktopWindow( hwnd );
}
static BOOL loaderdrv_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
static BOOL loaderdrv_CreateWindow( HWND hwnd )
{
return load_driver()->pCreateWindow( hwnd, cs, unicode );
return load_driver()->pCreateWindow( hwnd );
}
static void loaderdrv_DestroyWindow( HWND hwnd )
@ -700,10 +700,12 @@ static void loaderdrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
load_driver()->pSetParent( hwnd, parent, old_parent );
}
static BOOL loaderdrv_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
const RECT *rectClient, UINT swp_flags, const RECT *valid_rects )
static void loaderdrv_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
const RECT *visible_rect, const RECT *valid_rects )
{
return load_driver()->pSetWindowPos( hwnd, insert_after, rectWindow, rectClient, swp_flags, valid_rects );
return load_driver()->pSetWindowPos( hwnd, insert_after, swp_flags, window_rect,
client_rect, visible_rect, valid_rects );
}
static int loaderdrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )

View file

@ -142,7 +142,7 @@ typedef struct tagUSER_DRIVER {
BOOL (*pGetMonitorInfo)(HMONITOR,MONITORINFO*);
/* windowing functions */
BOOL (*pCreateDesktopWindow)(HWND);
BOOL (*pCreateWindow)(HWND,CREATESTRUCTA*,BOOL);
BOOL (*pCreateWindow)(HWND);
void (*pDestroyWindow)(HWND);
HDC (*pGetDCEx)(HWND,HRGN,DWORD);
DWORD (*pMsgWaitForMultipleObjectsEx)(DWORD,const HANDLE*,DWORD,DWORD,DWORD);
@ -150,7 +150,7 @@ typedef struct tagUSER_DRIVER {
BOOL (*pScrollDC)(HDC, INT, INT, const RECT *, const RECT *, HRGN, LPRECT);
void (*pSetFocus)(HWND);
void (*pSetParent)(HWND,HWND,HWND);
BOOL (*pSetWindowPos)(HWND,HWND,const RECT *,const RECT *,UINT,const RECT *);
void (*pSetWindowPos)(HWND,HWND,UINT,const RECT *,const RECT *,const RECT *,const RECT *);
int (*pSetWindowRgn)(HWND,HRGN,BOOL);
void (*pSetWindowIcon)(HWND,UINT,HICON);
void (*pSetWindowStyle)(HWND,DWORD);

View file

@ -863,11 +863,15 @@ static void dump_window_styles( DWORD style, DWORD exstyle )
*/
static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, LPCWSTR className, UINT flags )
{
INT sw = SW_SHOW;
INT cx, cy, sw = SW_SHOW;
LRESULT result;
RECT rect;
WND *wndPtr;
HWND hwnd, parent, owner, top_child = 0;
BOOL unicode = (flags & WIN_ISUNICODE) != 0;
MDICREATESTRUCTA mdi_cs;
CBT_CREATEWNDA cbtc;
CREATESTRUCTA cbcs;
TRACE("%s %s ex=%08x style=%08x %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n",
unicode ? debugstr_w((LPCWSTR)cs->lpszName) : debugstr_a(cs->lpszName),
@ -1078,14 +1082,91 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, LPCWSTR className, UINT flags
}
}
else SetWindowLongPtrW( hwnd, GWLP_ID, (ULONG_PTR)cs->hMenu );
WIN_ReleasePtr( wndPtr );
if (!USER_Driver->pCreateWindow( hwnd, cs, unicode))
/* call the WH_CBT hook */
/* 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 = wndPtr->dwStyle;
cbtc.lpcs = &cbcs;
cbtc.hwndInsertAfter = HWND_TOP;
WIN_ReleasePtr( wndPtr );
if (HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, unicode )) goto failed;
/* send the WM_GETMINMAXINFO message and fix the size if needed */
cx = cs->cx;
cy = cs->cy;
if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
{
WIN_DestroyWindow( hwnd );
return 0;
POINT maxSize, maxPos, minTrack, maxTrack;
WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack);
if (maxTrack.x < cx) cx = maxTrack.x;
if (maxTrack.y < cy) cy = maxTrack.y;
}
if (cx < 0) cx = 0;
if (cy < 0) cy = 0;
SetRect( &rect, cs->x, cs->y, cs->x + cx, cs->y + cy );
if (!set_window_pos( hwnd, 0, SWP_NOZORDER | SWP_NOACTIVATE, &rect, &rect, NULL )) goto failed;
/* send WM_NCCREATE */
TRACE( "hwnd %p cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cx, cy );
if (unicode)
result = SendMessageW( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
else
result = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
if (!result)
{
WARN( "%p: aborted by WM_NCCREATE\n", hwnd );
goto failed;
}
/* send WM_NCCALCSIZE */
if ((wndPtr = WIN_GetPtr(hwnd)))
{
/* yes, even if the CBT hook was called with HWND_TOP */
HWND insert_after = (wndPtr->dwStyle & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
RECT window_rect = wndPtr->rectWindow;
RECT client_rect = window_rect;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&client_rect );
set_window_pos( hwnd, insert_after, SWP_NOACTIVATE, &window_rect, &client_rect, NULL );
}
else return 0;
/* send WM_CREATE */
if (unicode)
result = SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs );
else
result = SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs );
if (result == -1) goto failed;
NotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0);
/* send the size messages */
if (!(wndPtr = WIN_GetPtr(hwnd))) return 0;
if (!(wndPtr->flags & WIN_NEED_SIZE))
{
rect = wndPtr->rectClient;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_SIZE, SIZE_RESTORED,
MAKELONG(rect.right-rect.left, rect.bottom-rect.top));
SendMessageW( hwnd, WM_MOVE, 0, MAKELONG( rect.left, rect.top ) );
}
else WIN_ReleasePtr( wndPtr );
/* call the driver */
if (!USER_Driver->pCreateWindow( hwnd )) goto failed;
/* Notify the parent window only */
send_parent_notify( hwnd, WM_CREATE );
@ -1114,6 +1195,10 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, LPCWSTR className, UINT flags
TRACE("created window %p\n", hwnd);
return hwnd;
failed:
WIN_DestroyWindow( hwnd );
return 0;
}

View file

@ -1563,6 +1563,59 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
return ret;
}
/***********************************************************************
* set_window_pos
*
* Backend implementation of SetWindowPos.
*/
BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect, const RECT *valid_rects )
{
WND *win;
BOOL ret;
RECT visible_rect;
if (!(win = WIN_GetPtr( hwnd ))) return FALSE;
if (win == WND_DESKTOP || win == WND_OTHER_PROCESS) return FALSE;
SERVER_START_REQ( set_window_pos )
{
req->handle = hwnd;
req->previous = insert_after;
req->flags = swp_flags;
req->window.left = window_rect->left;
req->window.top = window_rect->top;
req->window.right = window_rect->right;
req->window.bottom = window_rect->bottom;
req->client.left = client_rect->left;
req->client.top = client_rect->top;
req->client.right = client_rect->right;
req->client.bottom = client_rect->bottom;
if (!IsRectEmpty( &valid_rects[0] ))
wine_server_add_data( req, valid_rects, 2 * sizeof(*valid_rects) );
if ((ret = !wine_server_call( req )))
{
win->dwStyle = reply->new_style;
win->dwExStyle = reply->new_ex_style;
win->rectWindow = *window_rect;
win->rectClient = *client_rect;
visible_rect.left = reply->visible.left;
visible_rect.top = reply->visible.top;
visible_rect.right = reply->visible.right;
visible_rect.bottom = reply->visible.bottom;
}
}
SERVER_END_REQ;
WIN_ReleasePtr( win );
if (ret)
USER_Driver->pSetWindowPos( hwnd, insert_after, swp_flags, window_rect,
client_rect, &visible_rect, valid_rects );
return ret;
}
/***********************************************************************
* USER_SetWindowPos
*
@ -1606,8 +1659,8 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos )
SWP_DoNCCalcSize( winpos, &newWindowRect, &newClientRect, valid_rects );
if(!USER_Driver->pSetWindowPos( winpos->hwnd, winpos->hwndInsertAfter,
&newWindowRect, &newClientRect, orig_flags, valid_rects ))
if (!set_window_pos( winpos->hwnd, winpos->hwndInsertAfter, orig_flags,
&newWindowRect, &newClientRect, valid_rects ))
return FALSE;
/* erase parent when hiding or resizing child */

View file

@ -1307,17 +1307,10 @@ BOOL X11DRV_CreateDesktopWindow( HWND hwnd )
/**********************************************************************
* CreateWindow (X11DRV.@)
*/
BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
BOOL X11DRV_CreateWindow( HWND hwnd )
{
Display *display = thread_display();
WND *wndPtr;
HWND insert_after;
RECT rect;
DWORD style;
CBT_CREATEWNDA cbtc;
CREATESTRUCTA cbcs;
BOOL ret = FALSE;
INT cx = cs->cx, cy = cs->cy;
if (hwnd == GetDesktopWindow() && root_window != DefaultRootWindow( display ))
{
@ -1325,94 +1318,6 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
if (!create_desktop_win_data( display, hwnd )) return FALSE;
}
/* Call the WH_CBT hook */
/* 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 ))
{
TRACE("CBT-hook returned !0\n");
goto failed;
}
/* Send the WM_GETMINMAXINFO message and fix the size if needed */
if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
{
POINT maxSize, maxPos, minTrack, maxTrack;
WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack);
if (maxTrack.x < cx) cx = maxTrack.x;
if (maxTrack.y < cy) cy = maxTrack.y;
}
if (cx < 0) cx = 0;
if (cy < 0) cy = 0;
SetRect( &rect, cs->x, cs->y, cs->x + cx, cs->y + cy );
if (!X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER | SWP_NOACTIVATE, NULL ))
return FALSE;
/* send WM_NCCREATE */
TRACE( "hwnd %p cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cs->cx, cs->cy );
if (unicode)
ret = SendMessageW( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
else
ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
if (!ret)
{
WARN("aborted by WM_xxCREATE!\n");
return FALSE;
}
/* make sure the window is still valid */
if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
/* send WM_NCCALCSIZE */
rect = wndPtr->rectWindow;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect );
if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
/* yes, even if the CBT hook was called with HWND_TOP */
insert_after = (wndPtr->dwStyle & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
X11DRV_SetWindowPos( hwnd, insert_after, &wndPtr->rectWindow, &rect, SWP_NOACTIVATE, NULL );
WIN_ReleasePtr( wndPtr );
if (unicode)
ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
else
ret = (SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
if (!ret) return FALSE;
NotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0);
/* Send the size messages */
if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return FALSE;
if (!(wndPtr->flags & WIN_NEED_SIZE))
{
RECT rect = wndPtr->rectClient;
WIN_ReleasePtr( wndPtr );
/* send it anyway */
if (((rect.right-rect.left) <0) ||((rect.bottom-rect.top)<0))
WARN("sending bogus WM_SIZE message 0x%08x\n",
MAKELONG(rect.right-rect.left, rect.bottom-rect.top));
SendMessageW( hwnd, WM_SIZE, SIZE_RESTORED,
MAKELONG(rect.right-rect.left, rect.bottom-rect.top));
SendMessageW( hwnd, WM_MOVE, 0, MAKELONG( rect.left, rect.top ) );
}
else WIN_ReleasePtr( wndPtr );
/* Show the window, maximizing or minimizing if needed */
style = GetWindowLongW( hwnd, GWL_STYLE );
@ -1433,10 +1338,6 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
}
return TRUE;
failed:
X11DRV_DestroyWindow( hwnd );
return FALSE;
}

View file

@ -89,7 +89,7 @@
@ cdecl AcquireClipboard(long) X11DRV_AcquireClipboard
@ cdecl CountClipboardFormats() X11DRV_CountClipboardFormats
@ cdecl CreateDesktopWindow(long) X11DRV_CreateDesktopWindow
@ cdecl CreateWindow(long ptr long) X11DRV_CreateWindow
@ cdecl CreateWindow(long) X11DRV_CreateWindow
@ cdecl DestroyWindow(long) X11DRV_DestroyWindow
@ cdecl EmptyClipboard(long) X11DRV_EmptyClipboard
@ cdecl EndClipboardUpdate() X11DRV_EndClipboardUpdate
@ -106,7 +106,7 @@
@ cdecl SetFocus(long) X11DRV_SetFocus
@ cdecl SetParent(long long long) X11DRV_SetParent
@ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
@ cdecl SetWindowPos(long long ptr ptr long ptr) X11DRV_SetWindowPos
@ cdecl SetWindowPos(long long long ptr ptr ptr ptr) X11DRV_SetWindowPos
@ cdecl SetWindowRgn(long long long) X11DRV_SetWindowRgn
@ cdecl SetWindowStyle(ptr long) X11DRV_SetWindowStyle
@ cdecl SetWindowText(long wstr) X11DRV_SetWindowText

View file

@ -301,76 +301,23 @@ static void move_window_bits( struct x11drv_win_data *data, const RECT *old_rect
}
}
/***********************************************************************
* set_server_window_pos
*
* Set the window pos on the server side only. Helper for SetWindowPos.
*/
static BOOL set_server_window_pos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
const RECT *rectClient, UINT swp_flags, const RECT *valid_rects,
RECT *visible_rect )
{
WND *win;
BOOL ret;
if (!(win = WIN_GetPtr( hwnd ))) return FALSE;
if (win == WND_DESKTOP || win == WND_OTHER_PROCESS) return FALSE;
SERVER_START_REQ( set_window_pos )
{
req->handle = hwnd;
req->previous = insert_after;
req->flags = swp_flags;
req->window.left = rectWindow->left;
req->window.top = rectWindow->top;
req->window.right = rectWindow->right;
req->window.bottom = rectWindow->bottom;
req->client.left = rectClient->left;
req->client.top = rectClient->top;
req->client.right = rectClient->right;
req->client.bottom = rectClient->bottom;
if (!IsRectEmpty( &valid_rects[0] ))
wine_server_add_data( req, valid_rects, 2 * sizeof(*valid_rects) );
if ((ret = !wine_server_call( req )))
{
win->dwStyle = reply->new_style;
win->dwExStyle = reply->new_ex_style;
win->rectWindow = *rectWindow;
win->rectClient = *rectClient;
visible_rect->left = reply->visible.left;
visible_rect->top = reply->visible.top;
visible_rect->right = reply->visible.right;
visible_rect->bottom = reply->visible.bottom;
}
}
SERVER_END_REQ;
WIN_ReleasePtr( win );
return ret;
}
/***********************************************************************
* SetWindowPos (X11DRV.@)
*/
BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
const RECT *rectClient, UINT swp_flags, const RECT *valid_rects )
void X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *rectWindow, const RECT *rectClient,
const RECT *visible_rect, const RECT *valid_rects )
{
Display *display = thread_display();
struct x11drv_win_data *data;
RECT old_window_rect, old_whole_rect, old_client_rect, visible_rect;
DWORD new_style;
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
DWORD new_style = GetWindowLongW( hwnd, GWL_STYLE );
RECT old_window_rect, old_whole_rect, old_client_rect;
if (!set_server_window_pos( hwnd, insert_after, rectWindow, rectClient, swp_flags,
valid_rects, &visible_rect ))
return FALSE;
new_style = GetWindowLongW( hwnd, GWL_STYLE );
if (!(data = X11DRV_get_win_data( hwnd )))
if (!data)
{
/* create the win data if the window is being made visible */
if (!(new_style & WS_VISIBLE)) return TRUE;
if (!(data = X11DRV_create_win_data( hwnd ))) return FALSE;
if (!(new_style & WS_VISIBLE)) return;
if (!(data = X11DRV_create_win_data( hwnd ))) return;
}
/* check if we need to switch the window to managed */
@ -398,7 +345,7 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
if (memcmp( &visible_rect, &data->whole_rect, sizeof(RECT) ))
{
TRACE( "%p: need to update visible rect %s -> %s\n", hwnd,
wine_dbgstr_rect(&visible_rect), wine_dbgstr_rect(&data->whole_rect) );
wine_dbgstr_rect(visible_rect), wine_dbgstr_rect(&data->whole_rect) );
SERVER_START_REQ( set_window_visible_rect )
{
req->handle = hwnd;
@ -452,7 +399,7 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
data->client_rect.bottom-data->client_rect.top == old_client_rect.bottom-old_client_rect.top)
X11DRV_sync_gl_drawable( display, data );
if (!data->whole_window || data->lock_changes) return TRUE; /* nothing more to do */
if (!data->whole_window || data->lock_changes) return; /* nothing more to do */
if (data->mapped && (!(new_style & WS_VISIBLE) || !X11DRV_is_window_rect_mapped( rectWindow )))
{
@ -485,8 +432,6 @@ BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
}
update_wm_states( display, data, !was_mapped );
}
return TRUE;
}

View file

@ -731,8 +731,6 @@ extern void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *
extern void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data,
UINT swp_flags, const RECT *old_client_rect,
const RECT *old_whole_rect );
extern BOOL X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
const RECT *rectClient, UINT swp_flags, const RECT *validRects );
extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data );
extern void xinerama_init( unsigned int width, unsigned int height );

View file

@ -116,4 +116,7 @@ extern HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ) DEC
extern void WINPOS_CheckInternalPos( HWND hwnd ) DECLSPEC_HIDDEN;
extern void WINPOS_ActivateOtherWindow( HWND hwnd ) DECLSPEC_HIDDEN;
extern BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect, const RECT *valid_rects );
#endif /* __WINE_WIN_H */