Store in the server all the window information accessible with

Get/SetWindowLong.
This commit is contained in:
Alexandre Julliard 2001-10-22 19:08:33 +00:00
parent 3bb9a36ee0
commit ddc3317b7a
17 changed files with 875 additions and 504 deletions

View File

@ -1714,10 +1714,8 @@ LPINT lpMax /* [out] Where to store maximum value */)
BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar, BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar,
BOOL fShowH, BOOL fShowV ) BOOL fShowH, BOOL fShowV )
{ {
WND *wndPtr = WIN_FindWndPtr( hwnd ); LONG style = GetWindowLongW( hwnd, GWL_STYLE );
BOOL retvalue = FALSE;
if (!wndPtr) return FALSE;
TRACE("hwnd=%04x bar=%d horz=%d, vert=%d\n", TRACE("hwnd=%04x bar=%d horz=%d, vert=%d\n",
hwnd, nBar, fShowH, fShowV ); hwnd, nBar, fShowH, fShowV );
@ -1725,20 +1723,19 @@ BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar,
{ {
case SB_CTL: case SB_CTL:
ShowWindow( hwnd, fShowH ? SW_SHOW : SW_HIDE ); ShowWindow( hwnd, fShowH ? SW_SHOW : SW_HIDE );
retvalue = TRUE; return TRUE;
goto END;
case SB_BOTH: case SB_BOTH:
case SB_HORZ: case SB_HORZ:
if (fShowH) if (fShowH)
{ {
fShowH = !(wndPtr->dwStyle & WS_HSCROLL); fShowH = !(style & WS_HSCROLL);
wndPtr->dwStyle |= WS_HSCROLL; style |= WS_HSCROLL;
} }
else /* hide it */ else /* hide it */
{ {
fShowH = (wndPtr->dwStyle & WS_HSCROLL); fShowH = (style & WS_HSCROLL);
wndPtr->dwStyle &= ~WS_HSCROLL; style &= ~WS_HSCROLL;
} }
if( nBar == SB_HORZ ) { if( nBar == SB_HORZ ) {
fShowV = FALSE; fShowV = FALSE;
@ -1749,35 +1746,30 @@ BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar,
case SB_VERT: case SB_VERT:
if (fShowV) if (fShowV)
{ {
fShowV = !(wndPtr->dwStyle & WS_VSCROLL); fShowV = !(style & WS_VSCROLL);
wndPtr->dwStyle |= WS_VSCROLL; style |= WS_VSCROLL;
} }
else /* hide it */ else /* hide it */
{ {
fShowV = (wndPtr->dwStyle & WS_VSCROLL); fShowV = (style & WS_VSCROLL);
wndPtr->dwStyle &= ~WS_VSCROLL; style &= ~WS_VSCROLL;
} }
if ( nBar == SB_VERT ) if ( nBar == SB_VERT )
fShowH = FALSE; fShowH = FALSE;
break; break;
default: default:
retvalue = FALSE; /* Nothing to do! */ return FALSE; /* Nothing to do! */
goto END;
} }
if( fShowH || fShowV ) /* frame has been changed, let the window redraw itself */ if( fShowH || fShowV ) /* frame has been changed, let the window redraw itself */
{ {
WIN_SetStyle( hwnd, style );
SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE
| SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
retvalue = TRUE; return TRUE;
goto END;
} }
return FALSE; /* no frame changes */
retvalue = FALSE; /* no frame changes */
END:
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
} }

View File

@ -609,13 +609,9 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect ); WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect );
if( winpos->flags & SWP_SHOWWINDOW ) if( winpos->flags & SWP_SHOWWINDOW )
{ WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle | WS_VISIBLE );
wndPtr->dwStyle |= WS_VISIBLE;
}
else if( winpos->flags & SWP_HIDEWINDOW ) else if( winpos->flags & SWP_HIDEWINDOW )
{ WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle & ~WS_VISIBLE );
wndPtr->dwStyle &= ~WS_VISIBLE;
}
/* ------------------------------------------------------------------------ FINAL */ /* ------------------------------------------------------------------------ FINAL */

View File

@ -1084,16 +1084,21 @@ static void reply_message( struct received_message_info *info, LRESULT result, B
*/ */
static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{ {
if (hwnd == GetDesktopWindow()) return 0;
switch(msg) switch(msg)
{ {
case WM_WINE_DESTROYWINDOW:
return WIN_DestroyWindow( hwnd );
case WM_WINE_SETWINDOWPOS: case WM_WINE_SETWINDOWPOS:
return USER_Driver.pSetWindowPos( (WINDOWPOS *)lparam ); return USER_Driver.pSetWindowPos( (WINDOWPOS *)lparam );
case WM_WINE_SHOWWINDOW: case WM_WINE_SHOWWINDOW:
return USER_Driver.pShowWindow( hwnd, wparam ); return ShowWindow( hwnd, wparam );
case WM_WINE_DESTROYWINDOW:
return WIN_DestroyWindow( hwnd );
case WM_WINE_SETPARENT: case WM_WINE_SETPARENT:
return (LRESULT)WIN_SetParent( hwnd, (HWND)wparam ); return (LRESULT)SetParent( hwnd, (HWND)wparam );
case WM_WINE_SETWINDOWLONG:
return (LRESULT)SetWindowLongW( hwnd, wparam, lparam );
case WM_WINE_ENABLEWINDOW:
return EnableWindow( hwnd, wparam );
default: default:
FIXME( "unknown internal message %x\n", msg ); FIXME( "unknown internal message %x\n", msg );
return 0; return 0;

View File

@ -87,7 +87,6 @@ static BOOL load_driver(void)
GET_USER_FUNC(CreateWindow); GET_USER_FUNC(CreateWindow);
GET_USER_FUNC(DestroyWindow); GET_USER_FUNC(DestroyWindow);
GET_USER_FUNC(GetDC); GET_USER_FUNC(GetDC);
GET_USER_FUNC(EnableWindow);
GET_USER_FUNC(ForceWindowRaise); GET_USER_FUNC(ForceWindowRaise);
GET_USER_FUNC(MsgWaitForMultipleObjectsEx); GET_USER_FUNC(MsgWaitForMultipleObjectsEx);
GET_USER_FUNC(ScrollDC); GET_USER_FUNC(ScrollDC);

View File

@ -22,6 +22,7 @@
#include "debugtools.h" #include "debugtools.h"
#include "x11drv.h" #include "x11drv.h"
#include "win.h" #include "win.h"
#include "winpos.h"
#include "dce.h" #include "dce.h"
#include "options.h" #include "options.h"
@ -106,8 +107,8 @@ static int get_window_attributes( Display *display, WND *win, XSetWindowAttribut
BOOL is_top_level = is_window_top_level( win ); BOOL is_top_level = is_window_top_level( win );
BOOL managed = is_top_level && is_window_managed( win ); BOOL managed = is_top_level && is_window_managed( win );
if (managed) win->dwExStyle |= WS_EX_MANAGED; if (managed) WIN_SetExStyle( win->hwndSelf, win->dwExStyle | WS_EX_MANAGED );
else win->dwExStyle &= ~WS_EX_MANAGED; else WIN_SetExStyle( win->hwndSelf, win->dwExStyle & ~WS_EX_MANAGED );
attr->override_redirect = !managed; attr->override_redirect = !managed;
attr->colormap = X11DRV_PALETTE_PaletteXColormap; attr->colormap = X11DRV_PALETTE_PaletteXColormap;
@ -833,13 +834,17 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
data->hWMIconBitmap = 0; data->hWMIconBitmap = 0;
data->hWMIconMask = 0; data->hWMIconMask = 0;
wndPtr = WIN_FindWndPtr( hwnd ); wndPtr = WIN_GetPtr( hwnd );
wndPtr->pDriverData = data; wndPtr->pDriverData = data;
/* initialize the dimensions before sending WM_GETMINMAXINFO */
SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
WIN_SetRectangles( hwnd, &rect, &rect );
if (!wndPtr->parent) if (!wndPtr->parent)
{ {
create_desktop( display, wndPtr, cs ); create_desktop( display, wndPtr, cs );
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleasePtr( wndPtr );
return TRUE; return TRUE;
} }
@ -847,11 +852,30 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
if (!create_client_window( display, wndPtr )) goto failed; if (!create_client_window( display, wndPtr )) goto failed;
TSXSync( display, False ); TSXSync( display, False );
WIN_ReleaseWndPtr( wndPtr );
SetPropA( hwnd, whole_window_atom, (HANDLE)data->whole_window ); SetPropA( hwnd, whole_window_atom, (HANDLE)data->whole_window );
SetPropA( hwnd, client_window_atom, (HANDLE)data->client_window ); SetPropA( hwnd, client_window_atom, (HANDLE)data->client_window );
/* 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;
WIN_ReleasePtr( wndPtr );
WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack);
if (maxSize.x < cs->cx) cs->cx = maxSize.x;
if (maxSize.y < cs->cy) cs->cy = maxSize.y;
if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
if (cs->cx < 0) cs->cx = 0;
if (cs->cy < 0) cs->cy = 0;
if (!(wndPtr = WIN_GetPtr( hwnd ))) return FALSE;
SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
WIN_SetRectangles( hwnd, &rect, &rect );
X11DRV_sync_whole_window_position( display, wndPtr, 0 );
}
WIN_ReleasePtr( wndPtr );
/* send WM_NCCREATE */ /* send WM_NCCREATE */
TRACE( "hwnd %x cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cs->cx, cs->cy ); TRACE( "hwnd %x cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cs->cx, cs->cy );
if (unicode) if (unicode)
@ -860,17 +884,20 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs ); ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
if (!ret) if (!ret)
{ {
X11DRV_DestroyWindow( hwnd ); WARN("aborted by WM_xxCREATE!\n");
return FALSE; return FALSE;
} }
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE; if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
sync_window_style( display, wndPtr ); sync_window_style( display, wndPtr );
/* send WM_NCCALCSIZE */ /* send WM_NCCALCSIZE */
rect = wndPtr->rectWindow; rect = wndPtr->rectWindow;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect ); SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect );
if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
if (rect.left > rect.right || rect.top > rect.bottom) rect = wndPtr->rectWindow; if (rect.left > rect.right || rect.top > rect.bottom) rect = wndPtr->rectWindow;
WIN_SetRectangles( hwnd, &wndPtr->rectWindow, &rect ); WIN_SetRectangles( hwnd, &wndPtr->rectWindow, &rect );
X11DRV_sync_client_window_position( display, wndPtr ); X11DRV_sync_client_window_position( display, wndPtr );
@ -892,7 +919,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
else else
WIN_LinkWindow( hwnd, wndPtr->parent, HWND_TOP ); WIN_LinkWindow( hwnd, wndPtr->parent, HWND_TOP );
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleasePtr( wndPtr );
if (unicode) if (unicode)
ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1); ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
@ -902,7 +929,6 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
if (!ret) if (!ret)
{ {
WIN_UnlinkWindow( hwnd ); WIN_UnlinkWindow( hwnd );
X11DRV_DestroyWindow( hwnd );
return FALSE; return FALSE;
} }
@ -932,7 +958,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
RECT newPos; RECT newPos;
UINT swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE; UINT swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE); WIN_SetStyle( hwnd, wndPtr->dwStyle & ~(WS_MAXIMIZE | WS_MINIMIZE) );
WINPOS_MinMaximize( hwnd, swFlag, &newPos ); WINPOS_MinMaximize( hwnd, swFlag, &newPos );
swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow()) swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow())
? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
@ -946,8 +972,8 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
failed: failed:
X11DRV_DestroyWindow( wndPtr->hwndSelf ); X11DRV_DestroyWindow( hwnd );
WIN_ReleaseWndPtr( wndPtr ); if (wndPtr) WIN_ReleasePtr( wndPtr );
return FALSE; return FALSE;
} }
@ -1052,78 +1078,6 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
} }
/*******************************************************************
* EnableWindow (X11DRV.@)
*/
BOOL X11DRV_EnableWindow( HWND hwnd, BOOL enable )
{
Display *display = thread_display();
XWMHints *wm_hints;
WND *wndPtr;
BOOL retvalue;
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
hwnd = wndPtr->hwndSelf; /* make it a full handle */
retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
if (enable && (wndPtr->dwStyle & WS_DISABLED))
{
/* Enable window */
wndPtr->dwStyle &= ~WS_DISABLED;
if (wndPtr->dwExStyle & WS_EX_MANAGED)
{
wine_tsx11_lock();
if (!(wm_hints = XGetWMHints( display, get_whole_window(wndPtr) )))
wm_hints = XAllocWMHints();
if (wm_hints)
{
wm_hints->flags |= InputHint;
wm_hints->input = TRUE;
XSetWMHints( display, get_whole_window(wndPtr), wm_hints );
XFree(wm_hints);
}
wine_tsx11_unlock();
}
SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
}
else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
{
SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0 );
/* Disable window */
wndPtr->dwStyle |= WS_DISABLED;
if (wndPtr->dwExStyle & WS_EX_MANAGED)
{
wine_tsx11_lock();
if (!(wm_hints = XGetWMHints( display, get_whole_window(wndPtr) )))
wm_hints = XAllocWMHints();
if (wm_hints)
{
wm_hints->flags |= InputHint;
wm_hints->input = FALSE;
XSetWMHints( display, get_whole_window(wndPtr), wm_hints );
XFree(wm_hints);
}
wine_tsx11_unlock();
}
if (hwnd == GetFocus())
SetFocus( 0 ); /* A disabled window can't have the focus */
if (hwnd == GetCapture())
ReleaseCapture(); /* A disabled window can't capture the mouse */
SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
}
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
}
/***************************************************************** /*****************************************************************
* SetFocus (X11DRV.@) * SetFocus (X11DRV.@)
* *

View File

@ -14,6 +14,7 @@
#include "winbase.h" #include "winbase.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "winerror.h"
#include "x11drv.h" #include "x11drv.h"
#include "hook.h" #include "hook.h"
@ -407,7 +408,7 @@ void X11DRV_Expose( HWND hwnd, XExposeEvent *event )
*/ */
BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags ) BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
{ {
WND *win = WIN_FindWndPtr( hwnd ); WND *win = WIN_GetPtr( hwnd );
HWND top = 0; HWND top = 0;
X11DRV_WND_DATA *data = win->pDriverData; X11DRV_WND_DATA *data = win->pDriverData;
Drawable drawable; Drawable drawable;
@ -505,7 +506,7 @@ BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
DeleteObject( visRgn ); DeleteObject( visRgn );
} }
WIN_ReleaseWndPtr( win ); WIN_ReleasePtr( win );
return TRUE; return TRUE;
} }
@ -675,10 +676,14 @@ static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
/* fix redundant flags and values in the WINDOWPOS structure */ /* fix redundant flags and values in the WINDOWPOS structure */
static BOOL fixup_flags( WINDOWPOS *winpos ) static BOOL fixup_flags( WINDOWPOS *winpos )
{ {
WND *wndPtr = WIN_FindWndPtr( winpos->hwnd ); WND *wndPtr = WIN_GetPtr( winpos->hwnd );
BOOL ret = TRUE; BOOL ret = TRUE;
if (!wndPtr) return FALSE; if (!wndPtr || wndPtr == WND_OTHER_PROCESS)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return FALSE;
}
winpos->hwnd = wndPtr->hwndSelf; /* make it a full handle */ winpos->hwnd = wndPtr->hwndSelf; /* make it a full handle */
if (wndPtr->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW; if (wndPtr->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW;
@ -723,25 +728,20 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
/* hwndInsertAfter must be a sibling of the window */ /* hwndInsertAfter must be a sibling of the window */
if ((winpos->hwndInsertAfter != HWND_TOP) && (winpos->hwndInsertAfter != HWND_BOTTOM)) if ((winpos->hwndInsertAfter != HWND_TOP) && (winpos->hwndInsertAfter != HWND_BOTTOM))
{ {
WND* wnd = WIN_FindWndPtr(winpos->hwndInsertAfter); winpos->hwndInsertAfter = WIN_GetFullHandle( winpos->hwndInsertAfter );
if (wnd) if (GetAncestor( winpos->hwndInsertAfter, GA_PARENT ) != wndPtr->parent) ret = FALSE;
else
{ {
winpos->hwndInsertAfter = wnd->hwndSelf; /* make it a full handle */ /* don't need to change the Zorder of hwnd if it's already inserted
if (wnd->parent != wndPtr->parent) ret = FALSE; * after hwndInsertAfter or when inserting hwnd after itself.
else */
{ if ((winpos->hwnd == winpos->hwndInsertAfter) ||
/* don't need to change the Zorder of hwnd if it's already inserted (winpos->hwnd == GetWindow( winpos->hwndInsertAfter, GW_HWNDNEXT )))
* after hwndInsertAfter or when inserting hwnd after itself. winpos->flags |= SWP_NOZORDER;
*/
if ((winpos->hwnd == winpos->hwndInsertAfter) ||
(winpos->hwnd == GetWindow( winpos->hwndInsertAfter, GW_HWNDNEXT )))
winpos->flags |= SWP_NOZORDER;
}
WIN_ReleaseWndPtr(wnd);
} }
} }
done: done:
WIN_ReleaseWndPtr(wndPtr); WIN_ReleasePtr( wndPtr );
return ret; return ret;
} }
@ -754,18 +754,51 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
void X11DRV_SetWindowStyle( HWND hwnd, LONG oldStyle ) void X11DRV_SetWindowStyle( HWND hwnd, LONG oldStyle )
{ {
Display *display = thread_display(); Display *display = thread_display();
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr;
if (!wndPtr) return; LONG changed;
if ((wndPtr->dwStyle & WS_VISIBLE) && (!(oldStyle & WS_VISIBLE))) if (hwnd == GetDesktopWindow()) return;
if (!(wndPtr = WIN_GetPtr( hwnd ))) return;
if (wndPtr == WND_OTHER_PROCESS) return;
changed = wndPtr->dwStyle ^ oldStyle;
if (changed & WS_VISIBLE)
{ {
if (!IsRectEmpty( &wndPtr->rectWindow )) if (!IsRectEmpty( &wndPtr->rectWindow ))
{ {
TRACE( "mapping win %x\n", hwnd ); if (wndPtr->dwStyle & WS_VISIBLE)
TSXMapWindow( display, get_whole_window(wndPtr) ); {
TRACE( "mapping win %x\n", hwnd );
TSXMapWindow( display, get_whole_window(wndPtr) );
}
else
{
TRACE( "unmapping win %x\n", hwnd );
TSXUnmapWindow( display, get_whole_window(wndPtr) );
}
} }
} }
WIN_ReleaseWndPtr(wndPtr);
if (changed & WS_DISABLED)
{
if (wndPtr->dwExStyle & WS_EX_MANAGED)
{
XWMHints *wm_hints;
wine_tsx11_lock();
if (!(wm_hints = XGetWMHints( display, get_whole_window(wndPtr) )))
wm_hints = XAllocWMHints();
if (wm_hints)
{
wm_hints->flags |= InputHint;
wm_hints->input = !(wndPtr->dwStyle & WS_DISABLED);
XSetWMHints( display, get_whole_window(wndPtr), wm_hints );
XFree(wm_hints);
}
wine_tsx11_unlock();
}
}
WIN_ReleasePtr(wndPtr);
} }
@ -844,37 +877,26 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect ); WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect );
if (winpos->flags & SWP_SHOWWINDOW) wndPtr->dwStyle |= WS_VISIBLE;
else if (winpos->flags & SWP_HIDEWINDOW)
{
/* clear the update region */
RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
RDW_NOINTERNALPAINT | RDW_ALLCHILDREN );
wndPtr->dwStyle &= ~WS_VISIBLE;
}
if (get_whole_window(wndPtr)) /* don't do anything if X window not created yet */ if (get_whole_window(wndPtr)) /* don't do anything if X window not created yet */
{ {
Display *display = thread_display(); Display *display = thread_display();
wine_tsx11_lock();
if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW)) if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
{ {
if (!IsRectEmpty( &oldWindowRect )) WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle & ~WS_VISIBLE );
{ /* clear the update region */
XUnmapWindow( display, get_whole_window(wndPtr) ); // RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE | RDW_NOFRAME |
TRACE( "unmapping win %x\n", winpos->hwnd ); // RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN );
}
else TRACE( "not unmapping zero size win %x\n", winpos->hwnd );
} }
else if ((wndPtr->dwStyle & WS_VISIBLE) && else if ((wndPtr->dwStyle & WS_VISIBLE) &&
!IsRectEmpty( &oldWindowRect ) && IsRectEmpty( &newWindowRect )) !IsRectEmpty( &oldWindowRect ) && IsRectEmpty( &newWindowRect ))
{ {
/* resizing to zero size -> unmap */ /* resizing to zero size -> unmap */
TRACE( "unmapping zero size win %x\n", winpos->hwnd ); TRACE( "unmapping zero size win %x\n", winpos->hwnd );
XUnmapWindow( display, get_whole_window(wndPtr) ); TSXUnmapWindow( display, get_whole_window(wndPtr) );
} }
wine_tsx11_lock();
if (bChangePos) if (bChangePos)
X11DRV_sync_whole_window_position( display, wndPtr, !(winpos->flags & SWP_NOZORDER) ); X11DRV_sync_whole_window_position( display, wndPtr, !(winpos->flags & SWP_NOZORDER) );
else else
@ -893,12 +915,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
} }
if (winpos->flags & SWP_SHOWWINDOW) if (winpos->flags & SWP_SHOWWINDOW)
{ {
if (!IsRectEmpty( &newWindowRect )) WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle | WS_VISIBLE );
{
XMapWindow( display, get_whole_window(wndPtr) );
TRACE( "mapping win %x\n", winpos->hwnd );
}
else TRACE( "not mapping win %x, size is zero\n", winpos->hwnd );
} }
else if ((wndPtr->dwStyle & WS_VISIBLE) && else if ((wndPtr->dwStyle & WS_VISIBLE) &&
IsRectEmpty( &oldWindowRect ) && !IsRectEmpty( &newWindowRect )) IsRectEmpty( &oldWindowRect ) && !IsRectEmpty( &newWindowRect ))
@ -910,6 +927,13 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
XFlush( display ); /* FIXME: should not be necessary */ XFlush( display ); /* FIXME: should not be necessary */
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
else /* no X window, simply toggle the window style */
{
if (winpos->flags & SWP_SHOWWINDOW)
WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle | WS_VISIBLE );
else if (winpos->flags & SWP_HIDEWINDOW)
WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle & ~WS_VISIBLE );
}
/* manually expose the areas that X won't expose because they are still covered by something */ /* manually expose the areas that X won't expose because they are still covered by something */
@ -1021,6 +1045,7 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
WND *wndPtr; WND *wndPtr;
UINT swpFlags = 0; UINT swpFlags = 0;
POINT size; POINT size;
LONG old_style;
WINDOWPLACEMENT wpl; WINDOWPLACEMENT wpl;
TRACE("0x%04x %u\n", hwnd, cmd ); TRACE("0x%04x %u\n", hwnd, cmd );
@ -1046,14 +1071,10 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
switch( cmd ) switch( cmd )
{ {
case SW_MINIMIZE: case SW_MINIMIZE:
if( wndPtr->dwStyle & WS_MAXIMIZE) if( wndPtr->dwStyle & WS_MAXIMIZE) wndPtr->flags |= WIN_RESTORE_MAX;
{ else wndPtr->flags &= ~WIN_RESTORE_MAX;
wndPtr->flags |= WIN_RESTORE_MAX;
wndPtr->dwStyle &= ~WS_MAXIMIZE; WIN_SetStyle( hwnd, (wndPtr->dwStyle & ~WS_MAXIMIZE) | WS_MINIMIZE );
}
else
wndPtr->flags &= ~WIN_RESTORE_MAX;
wndPtr->dwStyle |= WS_MINIMIZE;
X11DRV_set_iconic_state( wndPtr ); X11DRV_set_iconic_state( wndPtr );
@ -1067,21 +1088,19 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
case SW_MAXIMIZE: case SW_MAXIMIZE:
WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL ); WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL );
if( wndPtr->dwStyle & WS_MINIMIZE ) old_style = WIN_SetStyle( hwnd, (wndPtr->dwStyle & ~WS_MINIMIZE) | WS_MAXIMIZE );
if (old_style & WS_MINIMIZE)
{ {
wndPtr->dwStyle &= ~WS_MINIMIZE;
WINPOS_ShowIconTitle( hwnd, FALSE ); WINPOS_ShowIconTitle( hwnd, FALSE );
X11DRV_set_iconic_state( wndPtr ); X11DRV_set_iconic_state( wndPtr );
} }
wndPtr->dwStyle |= WS_MAXIMIZE;
SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y ); SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
break; break;
case SW_RESTORE: case SW_RESTORE:
if( wndPtr->dwStyle & WS_MINIMIZE ) old_style = WIN_SetStyle( hwnd, wndPtr->dwStyle & ~(WS_MINIMIZE|WS_MAXIMIZE) );
if (old_style & WS_MINIMIZE)
{ {
wndPtr->dwStyle &= ~WS_MINIMIZE;
WINPOS_ShowIconTitle( hwnd, FALSE ); WINPOS_ShowIconTitle( hwnd, FALSE );
X11DRV_set_iconic_state( wndPtr ); X11DRV_set_iconic_state( wndPtr );
@ -1089,16 +1108,12 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
{ {
/* Restore to maximized position */ /* Restore to maximized position */
WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL); WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL);
wndPtr->dwStyle |= WS_MAXIMIZE; WIN_SetStyle( hwnd, wndPtr->dwStyle | WS_MAXIMIZE );
SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y ); SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
break; break;
} }
} }
else else if (!(old_style & WS_MAXIMIZE)) break;
{
if (!(wndPtr->dwStyle & WS_MAXIMIZE)) break;
wndPtr->dwStyle &= ~WS_MAXIMIZE;
}
/* Restore to normal position */ /* Restore to normal position */
@ -1250,7 +1265,7 @@ void X11DRV_MapNotify( HWND hwnd, XMapEvent *event )
HWND hwndFocus = GetFocus(); HWND hwndFocus = GetFocus();
WND *win; WND *win;
if (!(win = WIN_FindWndPtr( hwnd ))) return; if (!(win = WIN_GetPtr( hwnd ))) return;
if ((win->dwStyle & WS_VISIBLE) && if ((win->dwStyle & WS_VISIBLE) &&
(win->dwStyle & WS_MINIMIZE) && (win->dwStyle & WS_MINIMIZE) &&
@ -1260,16 +1275,7 @@ void X11DRV_MapNotify( HWND hwnd, XMapEvent *event )
unsigned int width, height, border, depth; unsigned int width, height, border, depth;
Window root, top; Window root, top;
RECT rect; RECT rect;
LONG style = (win->dwStyle & ~(WS_MINIMIZE|WS_MAXIMIZE)) | WS_VISIBLE;
DCE_InvalidateDCE( hwnd, &win->rectWindow );
win->dwStyle &= ~WS_MINIMIZE;
win->dwStyle |= WS_VISIBLE;
WIN_InternalShowOwnedPopups( hwnd, TRUE, TRUE );
if (win->flags & WIN_RESTORE_MAX)
win->dwStyle |= WS_MAXIMIZE;
else
win->dwStyle &= ~WS_MAXIMIZE;
/* FIXME: hack */ /* FIXME: hack */
wine_tsx11_lock(); wine_tsx11_lock();
@ -1283,12 +1289,19 @@ void X11DRV_MapNotify( HWND hwnd, XMapEvent *event )
rect.bottom = y + height; rect.bottom = y + height;
X11DRV_X_to_window_rect( win, &rect ); X11DRV_X_to_window_rect( win, &rect );
DCE_InvalidateDCE( hwnd, &win->rectWindow );
if (win->flags & WIN_RESTORE_MAX) style |= WS_MAXIMIZE;
WIN_SetStyle( hwnd, style );
WIN_ReleasePtr( win );
WIN_InternalShowOwnedPopups( hwnd, TRUE, TRUE );
SendMessageA( hwnd, WM_SHOWWINDOW, SW_RESTORE, 0 ); SendMessageA( hwnd, WM_SHOWWINDOW, SW_RESTORE, 0 );
SetWindowPos( hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, SetWindowPos( hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
SWP_NOZORDER | SWP_WINE_NOHOSTMOVE ); SWP_NOZORDER | SWP_WINE_NOHOSTMOVE );
} }
else WIN_ReleasePtr( win );
if (hwndFocus && IsChild( hwnd, hwndFocus )) X11DRV_SetFocus(hwndFocus); /* FIXME */ if (hwndFocus && IsChild( hwnd, hwndFocus )) X11DRV_SetFocus(hwndFocus); /* FIXME */
WIN_ReleaseWndPtr( win );
} }
@ -1299,28 +1312,26 @@ void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event )
{ {
WND *win; WND *win;
if (!(win = WIN_FindWndPtr( hwnd ))) return; if (!(win = WIN_GetPtr( hwnd ))) return;
if ((win->dwStyle & WS_VISIBLE) && (win->dwExStyle & WS_EX_MANAGED)) if ((win->dwStyle & WS_VISIBLE) && (win->dwExStyle & WS_EX_MANAGED))
{ {
if (win->dwStyle & WS_MAXIMIZE)
win->flags |= WIN_RESTORE_MAX;
else
win->flags &= ~WIN_RESTORE_MAX;
WIN_SetStyle( hwnd, (win->dwStyle & ~WS_MAXIMIZE) | WS_MINIMIZE );
WIN_ReleasePtr( win );
EndMenu(); EndMenu();
SendMessageA( hwnd, WM_SHOWWINDOW, SW_MINIMIZE, 0 ); SendMessageA( hwnd, WM_SHOWWINDOW, SW_MINIMIZE, 0 );
win->flags &= ~WIN_RESTORE_MAX;
win->dwStyle |= WS_MINIMIZE;
if (win->dwStyle & WS_MAXIMIZE)
{
win->flags |= WIN_RESTORE_MAX;
win->dwStyle &= ~WS_MAXIMIZE;
}
SetWindowPos( hwnd, 0, 0, 0, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), SetWindowPos( hwnd, 0, 0, 0, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON),
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_WINE_NOHOSTMOVE ); SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_WINE_NOHOSTMOVE );
WIN_InternalShowOwnedPopups( hwnd, FALSE, TRUE ); WIN_InternalShowOwnedPopups( hwnd, FALSE, TRUE );
} }
WIN_ReleaseWndPtr( win ); else WIN_ReleasePtr( win );
} }
@ -1538,23 +1549,26 @@ void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
* *
* Assign specified region to window (for non-rectangular windows) * Assign specified region to window (for non-rectangular windows)
*/ */
BOOL X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) int X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
{ {
RECT rect; WND *wndPtr;
WND *wndPtr = WIN_FindWndPtr(hwnd);
int ret = FALSE;
if (!wndPtr) return FALSE; if ((wndPtr = WIN_GetPtr( hwnd )) == WND_OTHER_PROCESS)
{
if (IsWindow( hwnd ))
FIXME( "not supported on other process window %x\n", hwnd );
wndPtr = NULL;
}
if (!wndPtr)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return FALSE;
}
if (wndPtr->hrgnWnd == hrgn) if (wndPtr->hrgnWnd == hrgn)
{ {
ret = TRUE; WIN_ReleasePtr( wndPtr );
goto done; return TRUE;
}
if (hrgn) /* verify that region really exists */
{
if (GetRgnBox( hrgn, &rect ) == ERROR) goto done;
} }
if (wndPtr->hrgnWnd) if (wndPtr->hrgnWnd)
@ -1584,8 +1598,11 @@ BOOL X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
DWORD size; DWORD size;
DWORD dwBufferSize = GetRegionData(hrgn, 0, NULL); DWORD dwBufferSize = GetRegionData(hrgn, 0, NULL);
PRGNDATA pRegionData = HeapAlloc(GetProcessHeap(), 0, dwBufferSize); PRGNDATA pRegionData = HeapAlloc(GetProcessHeap(), 0, dwBufferSize);
if (!pRegionData) goto done; if (!pRegionData)
{
WIN_ReleasePtr( wndPtr );
return TRUE;
}
GetRegionData(hrgn, dwBufferSize, pRegionData); GetRegionData(hrgn, dwBufferSize, pRegionData);
size = pRegionData->rdh.nCount; size = pRegionData->rdh.nCount;
x_offset = wndPtr->rectWindow.left - data->whole_rect.left; x_offset = wndPtr->rectWindow.left - data->whole_rect.left;
@ -1624,12 +1641,9 @@ BOOL X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
} }
#endif /* HAVE_LIBXSHAPE */ #endif /* HAVE_LIBXSHAPE */
WIN_ReleasePtr( wndPtr );
if (redraw) RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE ); if (redraw) RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE );
ret = TRUE; return TRUE;
done:
WIN_ReleaseWndPtr(wndPtr);
return ret;
} }

View File

@ -78,7 +78,6 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics
@ cdecl CreateWindow(long ptr long) X11DRV_CreateWindow @ cdecl CreateWindow(long ptr long) X11DRV_CreateWindow
@ cdecl DestroyWindow(long) X11DRV_DestroyWindow @ cdecl DestroyWindow(long) X11DRV_DestroyWindow
@ cdecl GetDC(long long long long) X11DRV_GetDC @ cdecl GetDC(long long long long) X11DRV_GetDC
@ cdecl EnableWindow(long long) X11DRV_EnableWindow
@ cdecl ForceWindowRaise(long) X11DRV_ForceWindowRaise @ cdecl ForceWindowRaise(long) X11DRV_ForceWindowRaise
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx @ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx
@ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC @ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC

View File

@ -38,7 +38,9 @@ enum wine_internal_message
WM_WINE_DESTROYWINDOW = 0x80000000, WM_WINE_DESTROYWINDOW = 0x80000000,
WM_WINE_SETWINDOWPOS, WM_WINE_SETWINDOWPOS,
WM_WINE_SHOWWINDOW, WM_WINE_SHOWWINDOW,
WM_WINE_SETPARENT WM_WINE_SETPARENT,
WM_WINE_SETWINDOWLONG,
WM_WINE_ENABLEWINDOW
}; };
/* internal SendInput codes (FIXME) */ /* internal SendInput codes (FIXME) */
@ -79,7 +81,6 @@ typedef struct tagUSER_DRIVER {
BOOL (*pCreateWindow)(HWND,CREATESTRUCTA*,BOOL); BOOL (*pCreateWindow)(HWND,CREATESTRUCTA*,BOOL);
BOOL (*pDestroyWindow)(HWND); BOOL (*pDestroyWindow)(HWND);
BOOL (*pGetDC)(HWND,HDC,HRGN,DWORD); BOOL (*pGetDC)(HWND,HDC,HRGN,DWORD);
BOOL (*pEnableWindow)(HWND,BOOL);
void (*pForceWindowRaise)(HWND); void (*pForceWindowRaise)(HWND);
DWORD (*pMsgWaitForMultipleObjectsEx)(DWORD,const HANDLE*,DWORD,DWORD,DWORD); DWORD (*pMsgWaitForMultipleObjectsEx)(DWORD,const HANDLE*,DWORD,DWORD,DWORD);
BOOL (*pScrollDC)(HDC,INT,INT,const RECT*,const RECT*,HRGN,LPRECT); BOOL (*pScrollDC)(HDC,INT,INT,const RECT*,const RECT*,HRGN,LPRECT);
@ -87,7 +88,7 @@ typedef struct tagUSER_DRIVER {
void (*pSetFocus)(HWND); void (*pSetFocus)(HWND);
HWND (*pSetParent)(HWND,HWND); HWND (*pSetParent)(HWND,HWND);
BOOL (*pSetWindowPos)(WINDOWPOS *); BOOL (*pSetWindowPos)(WINDOWPOS *);
BOOL (*pSetWindowRgn)(HWND,HRGN,BOOL); int (*pSetWindowRgn)(HWND,HRGN,BOOL);
HICON (*pSetWindowIcon)(HWND,HICON,BOOL); HICON (*pSetWindowIcon)(HWND,HICON,BOOL);
void (*pSetWindowStyle)(HWND,DWORD); void (*pSetWindowStyle)(HWND,DWORD);
BOOL (*pSetWindowText)(HWND,LPCWSTR); BOOL (*pSetWindowText)(HWND,LPCWSTR);

View File

@ -89,6 +89,8 @@ extern HWND WIN_IsCurrentThread( HWND hwnd );
extern void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ); extern void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter );
extern void WIN_UnlinkWindow( HWND hwnd ); extern void WIN_UnlinkWindow( HWND hwnd );
extern void WIN_SetOwner( HWND hwnd, HWND owner ); extern void WIN_SetOwner( HWND hwnd, HWND owner );
extern LONG WIN_SetStyle( HWND hwnd, LONG style );
extern LONG WIN_SetExStyle( HWND hwnd, LONG style );
extern void WIN_SetRectangles( HWND hwnd, const RECT *rectWindow, const RECT *rectClient ); extern void WIN_SetRectangles( HWND hwnd, const RECT *rectWindow, const RECT *rectClient );
extern HWND WIN_FindWinToRepaint( HWND hwnd ); extern HWND WIN_FindWinToRepaint( HWND hwnd );
extern LRESULT WIN_DestroyWindow( HWND hwnd ); extern LRESULT WIN_DestroyWindow( HWND hwnd );
@ -97,7 +99,6 @@ extern BOOL WIN_CreateDesktopWindow(void);
extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL ); extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL );
extern HWND *WIN_ListParents( HWND hwnd ); extern HWND *WIN_ListParents( HWND hwnd );
extern HWND *WIN_ListChildren( HWND hwnd ); extern HWND *WIN_ListChildren( HWND hwnd );
extern HWND WIN_SetParent( HWND hwnd, HWND parent );
extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly ); extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly );
inline static HWND WIN_GetFullHandle( HWND hwnd ) inline static HWND WIN_GetFullHandle( HWND hwnd )

View File

@ -1601,6 +1601,7 @@ struct link_window_request
user_handle_t handle; user_handle_t handle;
user_handle_t parent; user_handle_t parent;
user_handle_t previous; user_handle_t previous;
user_handle_t full_parent;
}; };
@ -1613,6 +1614,16 @@ struct destroy_window_request
struct set_window_owner_request
{
struct request_header __header;
user_handle_t handle;
user_handle_t owner;
user_handle_t full_owner;
};
struct get_window_info_request struct get_window_info_request
{ {
struct request_header __header; struct request_header __header;
@ -1620,10 +1631,35 @@ struct get_window_info_request
user_handle_t full_handle; user_handle_t full_handle;
void* pid; void* pid;
void* tid; void* tid;
atom_t atom;
}; };
struct set_window_info_request
{
struct request_header __header;
user_handle_t handle;
unsigned int flags;
unsigned int style;
unsigned int ex_style;
unsigned int id;
void* instance;
void* user_data;
unsigned int old_style;
unsigned int old_ex_style;
unsigned int old_id;
void* old_instance;
void* old_user_data;
};
#define SET_WIN_STYLE 0x01
#define SET_WIN_EXSTYLE 0x02
#define SET_WIN_ID 0x04
#define SET_WIN_INSTANCE 0x08
#define SET_WIN_USERDATA 0x10
struct get_window_parents_request struct get_window_parents_request
{ {
struct request_header __header; struct request_header __header;
@ -1858,7 +1894,9 @@ enum request
REQ_create_window, REQ_create_window,
REQ_link_window, REQ_link_window,
REQ_destroy_window, REQ_destroy_window,
REQ_set_window_owner,
REQ_get_window_info, REQ_get_window_info,
REQ_set_window_info,
REQ_get_window_parents, REQ_get_window_parents,
REQ_get_window_children, REQ_get_window_children,
REQ_get_window_tree, REQ_get_window_tree,
@ -2001,7 +2039,9 @@ union generic_request
struct create_window_request create_window; struct create_window_request create_window;
struct link_window_request link_window; struct link_window_request link_window;
struct destroy_window_request destroy_window; struct destroy_window_request destroy_window;
struct set_window_owner_request set_window_owner;
struct get_window_info_request get_window_info; struct get_window_info_request get_window_info;
struct set_window_info_request set_window_info;
struct get_window_parents_request get_window_parents; struct get_window_parents_request get_window_parents;
struct get_window_children_request get_window_children; struct get_window_children_request get_window_children;
struct get_window_tree_request get_window_tree; struct get_window_tree_request get_window_tree;
@ -2014,6 +2054,6 @@ union generic_request
struct get_window_properties_request get_window_properties; struct get_window_properties_request get_window_properties;
}; };
#define SERVER_PROTOCOL_VERSION 60 #define SERVER_PROTOCOL_VERSION 61
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -1434,6 +1434,7 @@ enum message_type
user_handle_t parent; /* handle to the parent */ user_handle_t parent; /* handle to the parent */
user_handle_t previous; /* previous child in Z-order */ user_handle_t previous; /* previous child in Z-order */
@REPLY @REPLY
user_handle_t full_parent; /* full handle of new parent */
@END @END
@ -1443,6 +1444,15 @@ enum message_type
@END @END
/* Set a window owner */
@REQ(set_window_owner)
user_handle_t handle; /* handle to the window */
user_handle_t owner; /* new owner */
@REPLY
user_handle_t full_owner; /* full handle of new owner */
@END
/* Get information from a window handle */ /* Get information from a window handle */
@REQ(get_window_info) @REQ(get_window_info)
user_handle_t handle; /* handle to the window */ user_handle_t handle; /* handle to the window */
@ -1450,9 +1460,33 @@ enum message_type
user_handle_t full_handle; /* full 32-bit handle */ user_handle_t full_handle; /* full 32-bit handle */
void* pid; /* process owning the window */ void* pid; /* process owning the window */
void* tid; /* thread owning the window */ void* tid; /* thread owning the window */
atom_t atom; /* class atom */
@END @END
/* Set some information in a window */
@REQ(set_window_info)
user_handle_t handle; /* handle to the window */
unsigned int flags; /* flags for fields to set (see below) */
unsigned int style; /* window style */
unsigned int ex_style; /* window extended style */
unsigned int id; /* window id */
void* instance; /* creator instance */
void* user_data; /* user-specific data */
@REPLY
unsigned int old_style; /* old window style */
unsigned int old_ex_style; /* old window extended style */
unsigned int old_id; /* old window id */
void* old_instance; /* old creator instance */
void* old_user_data; /* old user-specific data */
@END
#define SET_WIN_STYLE 0x01
#define SET_WIN_EXSTYLE 0x02
#define SET_WIN_ID 0x04
#define SET_WIN_INSTANCE 0x08
#define SET_WIN_USERDATA 0x10
/* Get a list of the window parents, up to the root of the tree */ /* Get a list of the window parents, up to the root of the tree */
@REQ(get_window_parents) @REQ(get_window_parents)
user_handle_t handle; /* handle to the window */ user_handle_t handle; /* handle to the window */

View File

@ -191,7 +191,9 @@ DECL_HANDLER(get_named_pipe_info);
DECL_HANDLER(create_window); DECL_HANDLER(create_window);
DECL_HANDLER(link_window); DECL_HANDLER(link_window);
DECL_HANDLER(destroy_window); DECL_HANDLER(destroy_window);
DECL_HANDLER(set_window_owner);
DECL_HANDLER(get_window_info); DECL_HANDLER(get_window_info);
DECL_HANDLER(set_window_info);
DECL_HANDLER(get_window_parents); DECL_HANDLER(get_window_parents);
DECL_HANDLER(get_window_children); DECL_HANDLER(get_window_children);
DECL_HANDLER(get_window_tree); DECL_HANDLER(get_window_tree);
@ -333,7 +335,9 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_create_window, (req_handler)req_create_window,
(req_handler)req_link_window, (req_handler)req_link_window,
(req_handler)req_destroy_window, (req_handler)req_destroy_window,
(req_handler)req_set_window_owner,
(req_handler)req_get_window_info, (req_handler)req_get_window_info,
(req_handler)req_set_window_info,
(req_handler)req_get_window_parents, (req_handler)req_get_window_parents,
(req_handler)req_get_window_children, (req_handler)req_get_window_children,
(req_handler)req_get_window_tree, (req_handler)req_get_window_tree,

View File

@ -1707,11 +1707,27 @@ static void dump_link_window_request( const struct link_window_request *req )
fprintf( stderr, " previous=%08x", req->previous ); fprintf( stderr, " previous=%08x", req->previous );
} }
static void dump_link_window_reply( const struct link_window_request *req )
{
fprintf( stderr, " full_parent=%08x", req->full_parent );
}
static void dump_destroy_window_request( const struct destroy_window_request *req ) static void dump_destroy_window_request( const struct destroy_window_request *req )
{ {
fprintf( stderr, " handle=%08x", req->handle ); fprintf( stderr, " handle=%08x", req->handle );
} }
static void dump_set_window_owner_request( const struct set_window_owner_request *req )
{
fprintf( stderr, " handle=%08x,", req->handle );
fprintf( stderr, " owner=%08x", req->owner );
}
static void dump_set_window_owner_reply( const struct set_window_owner_request *req )
{
fprintf( stderr, " full_owner=%08x", req->full_owner );
}
static void dump_get_window_info_request( const struct get_window_info_request *req ) static void dump_get_window_info_request( const struct get_window_info_request *req )
{ {
fprintf( stderr, " handle=%08x", req->handle ); fprintf( stderr, " handle=%08x", req->handle );
@ -1721,7 +1737,28 @@ static void dump_get_window_info_reply( const struct get_window_info_request *re
{ {
fprintf( stderr, " full_handle=%08x,", req->full_handle ); fprintf( stderr, " full_handle=%08x,", req->full_handle );
fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " tid=%p", req->tid ); fprintf( stderr, " tid=%p,", req->tid );
fprintf( stderr, " atom=%04x", req->atom );
}
static void dump_set_window_info_request( const struct set_window_info_request *req )
{
fprintf( stderr, " handle=%08x,", req->handle );
fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " style=%08x,", req->style );
fprintf( stderr, " ex_style=%08x,", req->ex_style );
fprintf( stderr, " id=%08x,", req->id );
fprintf( stderr, " instance=%p,", req->instance );
fprintf( stderr, " user_data=%p", req->user_data );
}
static void dump_set_window_info_reply( const struct set_window_info_request *req )
{
fprintf( stderr, " old_style=%08x,", req->old_style );
fprintf( stderr, " old_ex_style=%08x,", req->old_ex_style );
fprintf( stderr, " old_id=%08x,", req->old_id );
fprintf( stderr, " old_instance=%p,", req->old_instance );
fprintf( stderr, " old_user_data=%p", req->old_user_data );
} }
static void dump_get_window_parents_request( const struct get_window_parents_request *req ) static void dump_get_window_parents_request( const struct get_window_parents_request *req )
@ -1970,7 +2007,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_window_request, (dump_func)dump_create_window_request,
(dump_func)dump_link_window_request, (dump_func)dump_link_window_request,
(dump_func)dump_destroy_window_request, (dump_func)dump_destroy_window_request,
(dump_func)dump_set_window_owner_request,
(dump_func)dump_get_window_info_request, (dump_func)dump_get_window_info_request,
(dump_func)dump_set_window_info_request,
(dump_func)dump_get_window_parents_request, (dump_func)dump_get_window_parents_request,
(dump_func)dump_get_window_children_request, (dump_func)dump_get_window_children_request,
(dump_func)dump_get_window_tree_request, (dump_func)dump_get_window_tree_request,
@ -2107,9 +2146,11 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)0, (dump_func)0,
(dump_func)dump_get_named_pipe_info_reply, (dump_func)dump_get_named_pipe_info_reply,
(dump_func)dump_create_window_reply, (dump_func)dump_create_window_reply,
(dump_func)dump_link_window_reply,
(dump_func)0, (dump_func)0,
(dump_func)0, (dump_func)dump_set_window_owner_reply,
(dump_func)dump_get_window_info_reply, (dump_func)dump_get_window_info_reply,
(dump_func)dump_set_window_info_reply,
(dump_func)dump_get_window_parents_reply, (dump_func)dump_get_window_parents_reply,
(dump_func)dump_get_window_children_reply, (dump_func)dump_get_window_children_reply,
(dump_func)dump_get_window_tree_reply, (dump_func)dump_get_window_tree_reply,
@ -2248,7 +2289,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_window", "create_window",
"link_window", "link_window",
"destroy_window", "destroy_window",
"set_window_owner",
"get_window_info", "get_window_info",
"set_window_info",
"get_window_parents", "get_window_parents",
"get_window_children", "get_window_children",
"get_window_tree", "get_window_tree",

View File

@ -42,6 +42,11 @@ struct window
atom_t atom; /* class atom */ atom_t atom; /* class atom */
rectangle_t window_rect; /* window rectangle */ rectangle_t window_rect; /* window rectangle */
rectangle_t client_rect; /* client rectangle */ rectangle_t client_rect; /* client rectangle */
unsigned int style; /* window style */
unsigned int ex_style; /* window extended style */
unsigned int id; /* window id */
void* instance; /* creator instance */
void* user_data; /* user-specific data */
int prop_inuse; /* number of in-use window properties */ int prop_inuse; /* number of in-use window properties */
int prop_alloc; /* number of allocated window properties */ int prop_alloc; /* number of allocated window properties */
struct property *properties; /* window properties array */ struct property *properties; /* window properties array */
@ -81,7 +86,11 @@ static void link_window( struct window *win, struct window *parent, struct windo
if (parent) if (parent)
{ {
win->parent = parent; if (win->parent != parent)
{
win->owner = NULL; /* reset owner if changing parent */
win->parent = parent;
}
if ((win->prev = previous)) if ((win->prev = previous))
{ {
if ((win->next = previous->next)) win->next->prev = win; if ((win->next = previous->next)) win->next->prev = win;
@ -261,6 +270,11 @@ static struct window *create_window( struct window *parent, struct window *owner
win->first_unlinked = NULL; win->first_unlinked = NULL;
win->thread = current; win->thread = current;
win->atom = atom; win->atom = atom;
win->style = 0;
win->ex_style = 0;
win->id = 0;
win->instance = NULL;
win->user_data = NULL;
win->prop_inuse = 0; win->prop_inuse = 0;
win->prop_alloc = 0; win->prop_alloc = 0;
win->properties = NULL; win->properties = NULL;
@ -323,6 +337,12 @@ DECL_HANDLER(create_window)
if (!(parent = get_window( req->parent ))) return; if (!(parent = get_window( req->parent ))) return;
if (req->owner && !(owner = get_window( req->owner ))) return; if (req->owner && !(owner = get_window( req->owner ))) return;
if (owner && owner->parent != parent)
{
/* owner must be a sibling of the new window */
set_error( STATUS_ACCESS_DENIED );
return;
}
if (!(win = create_window( parent, owner, req->atom ))) return; if (!(win = create_window( parent, owner, req->atom ))) return;
req->handle = win->handle; req->handle = win->handle;
} }
@ -342,6 +362,7 @@ DECL_HANDLER(link_window)
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return; return;
} }
req->full_parent = parent ? parent->handle : 0;
if (parent && req->previous) if (parent && req->previous)
{ {
if (req->previous == (user_handle_t)1) /* special case: HWND_BOTTOM */ if (req->previous == (user_handle_t)1) /* special case: HWND_BOTTOM */
@ -376,6 +397,24 @@ DECL_HANDLER(destroy_window)
} }
/* set a window owner */
DECL_HANDLER(set_window_owner)
{
struct window *win = get_window( req->handle );
struct window *owner = get_window( req->owner );
if (!win || !owner) return;
if (owner->parent != win->parent)
{
/* owner has to be a sibling of window */
set_error( STATUS_ACCESS_DENIED );
return;
}
win->owner = owner;
req->full_owner = owner->handle;
}
/* get information from a window handle */ /* get information from a window handle */
DECL_HANDLER(get_window_info) DECL_HANDLER(get_window_info)
{ {
@ -388,13 +427,32 @@ DECL_HANDLER(get_window_info)
req->full_handle = win->handle; req->full_handle = win->handle;
if (win->thread) if (win->thread)
{ {
req->tid = get_thread_id( win->thread ); req->tid = get_thread_id( win->thread );
req->pid = get_process_id( win->thread->process ); req->pid = get_process_id( win->thread->process );
req->atom = win->atom;
} }
} }
} }
/* set some information in a window */
DECL_HANDLER(set_window_info)
{
struct window *win = get_window( req->handle );
if (!win) return;
req->old_style = win->style;
req->old_ex_style = win->ex_style;
req->old_id = win->id;
req->old_instance = win->instance;
req->old_user_data = win->user_data;
if (req->flags & SET_WIN_STYLE) win->style = req->style;
if (req->flags & SET_WIN_EXSTYLE) win->ex_style = req->ex_style;
if (req->flags & SET_WIN_ID) win->id = req->id;
if (req->flags & SET_WIN_INSTANCE) win->instance = req->instance;
if (req->flags & SET_WIN_USERDATA) win->user_data = req->user_data;
}
/* get a list of the window parents, up to the root of the tree */ /* get a list of the window parents, up to the root of the tree */
DECL_HANDLER(get_window_parents) DECL_HANDLER(get_window_parents)
{ {

View File

@ -168,9 +168,7 @@ static void DEFWND_SetRedraw( HWND hwnd, WPARAM wParam )
{ {
if( !bVisible ) if( !bVisible )
{ {
wndPtr->dwStyle |= WS_VISIBLE; WIN_SetStyle( hwnd, wndPtr->dwStyle | WS_VISIBLE );
if (USER_Driver.pSetWindowStyle)
USER_Driver.pSetWindowStyle( hwnd, wndPtr->dwStyle & ~WS_VISIBLE );
DCE_InvalidateDCE( hwnd, &wndPtr->rectWindow ); DCE_InvalidateDCE( hwnd, &wndPtr->rectWindow );
} }
} }
@ -181,9 +179,7 @@ static void DEFWND_SetRedraw( HWND hwnd, WPARAM wParam )
RedrawWindow( hwnd, NULL, 0, wParam ); RedrawWindow( hwnd, NULL, 0, wParam );
DCE_InvalidateDCE( hwnd, &wndPtr->rectWindow ); DCE_InvalidateDCE( hwnd, &wndPtr->rectWindow );
wndPtr->dwStyle &= ~WS_VISIBLE; WIN_SetStyle( hwnd, wndPtr->dwStyle & ~WS_VISIBLE );
if (USER_Driver.pSetWindowStyle)
USER_Driver.pSetWindowStyle( hwnd, wndPtr->dwStyle | WS_VISIBLE );
} }
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleaseWndPtr( wndPtr );
} }

View File

@ -362,7 +362,6 @@ void WIN_UnlinkWindow( HWND hwnd )
*/ */
void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ) void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
{ {
BOOL ret;
WND *wndPtr = WIN_GetPtr( hwnd ); WND *wndPtr = WIN_GetPtr( hwnd );
if (!wndPtr) return; if (!wndPtr) return;
@ -377,10 +376,17 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
req->handle = hwnd; req->handle = hwnd;
req->parent = parent; req->parent = parent;
req->previous = hwndInsertAfter; req->previous = hwndInsertAfter;
ret = !SERVER_CALL_ERR(); if (!SERVER_CALL())
{
if (req->full_parent && req->full_parent != wndPtr->parent)
{
wndPtr->owner = 0; /* reset owner when changing parent */
wndPtr->parent = req->full_parent;
}
}
} }
SERVER_END_REQ; SERVER_END_REQ;
if (ret && parent) wndPtr->parent = WIN_GetFullHandle(parent);
WIN_ReleasePtr( wndPtr ); WIN_ReleasePtr( wndPtr );
} }
@ -392,12 +398,102 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
*/ */
void WIN_SetOwner( HWND hwnd, HWND owner ) void WIN_SetOwner( HWND hwnd, HWND owner )
{ {
WND *win = WIN_FindWndPtr( hwnd ); WND *win = WIN_GetPtr( hwnd );
if (win)
if (!win) return;
if (win == WND_OTHER_PROCESS)
{ {
win->owner = owner; if (IsWindow(hwnd)) ERR( "cannot set owner %x on other process window %x\n", owner, hwnd );
WIN_ReleaseWndPtr( win ); return;
} }
SERVER_START_REQ( set_window_owner )
{
req->handle = hwnd;
req->owner = owner;
if (!SERVER_CALL()) win->owner = req->full_owner;
}
SERVER_END_REQ;
WIN_ReleasePtr( win );
}
/***********************************************************************
* WIN_SetStyle
*
* Change the style of a window.
*/
LONG WIN_SetStyle( HWND hwnd, LONG style )
{
BOOL ok;
LONG ret = 0;
WND *win = WIN_GetPtr( hwnd );
if (!win) return 0;
if (win == WND_OTHER_PROCESS)
{
if (IsWindow(hwnd))
ERR( "cannot set style %lx on other process window %x\n", style, hwnd );
return 0;
}
if (style == win->dwStyle)
{
WIN_ReleasePtr( win );
return style;
}
SERVER_START_REQ( set_window_info )
{
req->handle = hwnd;
req->flags = SET_WIN_STYLE;
req->style = style;
if ((ok = !SERVER_CALL()))
{
ret = req->old_style;
win->dwStyle = style;
}
}
SERVER_END_REQ;
WIN_ReleasePtr( win );
if (ok && USER_Driver.pSetWindowStyle) USER_Driver.pSetWindowStyle( hwnd, ret );
return ret;
}
/***********************************************************************
* WIN_SetExStyle
*
* Change the extended style of a window.
*/
LONG WIN_SetExStyle( HWND hwnd, LONG style )
{
LONG ret = 0;
WND *win = WIN_GetPtr( hwnd );
if (!win) return 0;
if (win == WND_OTHER_PROCESS)
{
if (IsWindow(hwnd))
ERR( "cannot set exstyle %lx on other process window %x\n", style, hwnd );
return 0;
}
if (style == win->dwExStyle)
{
WIN_ReleasePtr( win );
return style;
}
SERVER_START_REQ( set_window_info )
{
req->handle = hwnd;
req->flags = SET_WIN_EXSTYLE;
req->ex_style = style;
if (!SERVER_CALL())
{
ret = req->old_ex_style;
win->dwExStyle = style;
}
}
SERVER_END_REQ;
WIN_ReleasePtr( win );
return ret;
} }
@ -603,11 +699,10 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
wndPtr->hmemTaskQ = 0; wndPtr->hmemTaskQ = 0;
if (!(wndPtr->dwStyle & WS_CHILD)) if (!(wndPtr->dwStyle & WS_CHILD))
if (wndPtr->wIDmenu) {
{ HMENU menu = (HMENU)SetWindowLongW( hwnd, GWL_ID, 0 );
DestroyMenu( wndPtr->wIDmenu ); if (menu) DestroyMenu( menu );
wndPtr->wIDmenu = 0; }
}
if (wndPtr->hSysMenu) if (wndPtr->hSysMenu)
{ {
DestroyMenu( wndPtr->hSysMenu ); DestroyMenu( wndPtr->hSysMenu );
@ -682,8 +777,7 @@ BOOL WIN_CreateDesktopWindow(void)
pWndDesktop->hmemTaskQ = 0; pWndDesktop->hmemTaskQ = 0;
pWndDesktop->hrgnUpdate = 0; pWndDesktop->hrgnUpdate = 0;
pWndDesktop->hwndLastActive = hwndDesktop; pWndDesktop->hwndLastActive = hwndDesktop;
pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | pWndDesktop->dwStyle = 0;
WS_CLIPSIBLINGS;
pWndDesktop->dwExStyle = 0; pWndDesktop->dwExStyle = 0;
pWndDesktop->clsStyle = clsStyle; pWndDesktop->clsStyle = clsStyle;
pWndDesktop->dce = NULL; pWndDesktop->dce = NULL;
@ -712,6 +806,7 @@ BOOL WIN_CreateDesktopWindow(void)
SetRect( &rect, 0, 0, cs.cx, cs.cy ); SetRect( &rect, 0, 0, cs.cx, cs.cy );
WIN_SetRectangles( hwndDesktop, &rect, &rect ); WIN_SetRectangles( hwndDesktop, &rect, &rect );
WIN_SetStyle( hwndDesktop, WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS );
if (!USER_Driver.pCreateWindow( hwndDesktop, &cs, FALSE )) return FALSE; if (!USER_Driver.pCreateWindow( hwndDesktop, &cs, FALSE )) return FALSE;
@ -798,11 +893,9 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
struct tagCLASS *classPtr; struct tagCLASS *classPtr;
WND *wndPtr; WND *wndPtr;
HWND hwnd, hwndLinkAfter, parent, owner; HWND hwnd, hwndLinkAfter, parent, owner;
POINT maxSize, maxPos, minTrack, maxTrack;
INT wndExtra; INT wndExtra;
DWORD clsStyle; DWORD clsStyle;
WNDPROC winproc; WNDPROC winproc;
RECT rect;
DCE *dce; DCE *dce;
BOOL unicode = (type == WIN_PROC_32W); BOOL unicode = (type == WIN_PROC_32W);
@ -924,8 +1017,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
TRACE("CBT-hook returned 0\n"); TRACE("CBT-hook returned 0\n");
free_window_handle( hwnd ); free_window_handle( hwnd );
CLASS_RemoveWindow( classPtr ); CLASS_RemoveWindow( classPtr );
hwnd = 0; WIN_ReleaseWndPtr(wndPtr);
goto end; return 0;
} }
} }
@ -940,6 +1033,16 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
wndPtr->flags |= WIN_NEED_SIZE; wndPtr->flags |= WIN_NEED_SIZE;
} }
} }
SERVER_START_REQ( set_window_info )
{
req->handle = hwnd;
req->flags = SET_WIN_STYLE | SET_WIN_EXSTYLE | SET_WIN_INSTANCE;
req->style = wndPtr->dwStyle;
req->ex_style = wndPtr->dwExStyle;
req->instance = (void *)wndPtr->hInstance;
SERVER_CALL();
}
SERVER_END_REQ;
/* Get class or window DC if needed */ /* Get class or window DC if needed */
@ -947,28 +1050,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
else if (clsStyle & CS_CLASSDC) wndPtr->dce = dce; else if (clsStyle & CS_CLASSDC) wndPtr->dce = dce;
else wndPtr->dce = NULL; else wndPtr->dce = NULL;
/* Initialize the dimensions before sending WM_GETMINMAXINFO */
SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
WIN_SetRectangles( hwnd, &rect, &rect );
/* Send the WM_GETMINMAXINFO message and fix the size if needed */
if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
{
WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack);
if (maxSize.x < cs->cx) cs->cx = maxSize.x;
if (maxSize.y < cs->cy) cs->cy = maxSize.y;
if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
}
if (cs->cx < 0) cs->cx = 0;
if (cs->cy < 0) cs->cy = 0;
SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
WIN_SetRectangles( hwnd, &rect, &rect );
/* Set the window menu */ /* Set the window menu */
if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION ) if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
@ -988,41 +1069,35 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
} }
} }
} }
else wndPtr->wIDmenu = (UINT)cs->hMenu; else SetWindowLongW( hwnd, GWL_ID, (UINT)cs->hMenu );
WIN_ReleaseWndPtr( wndPtr );
if (!USER_Driver.pCreateWindow( hwnd, cs, unicode)) if (!USER_Driver.pCreateWindow( hwnd, cs, unicode))
{ {
WARN("aborted by WM_xxCREATE!\n");
WIN_ReleaseWndPtr( wndPtr );
WIN_DestroyWindow( hwnd ); WIN_DestroyWindow( hwnd );
CLASS_RemoveWindow( classPtr );
return 0; return 0;
} }
/* Notify the parent window only */ /* Notify the parent window only */
send_parent_notify( hwnd, WM_CREATE ); send_parent_notify( hwnd, WM_CREATE );
if( !IsWindow(hwnd) ) if (!IsWindow( hwnd )) return 0;
{
hwnd = 0;
goto end;
}
if (cs->style & WS_VISIBLE) if (cs->style & WS_VISIBLE)
{ {
/* in case WS_VISIBLE got set in the meantime */ /* in case WS_VISIBLE got set in the meantime */
wndPtr->dwStyle &= ~WS_VISIBLE; if (!(wndPtr = WIN_GetPtr( hwnd ))) return 0;
WIN_SetStyle( hwnd, wndPtr->dwStyle & ~WS_VISIBLE );
WIN_ReleasePtr( wndPtr );
ShowWindow( hwnd, sw ); ShowWindow( hwnd, sw );
} }
/* Call WH_SHELL hook */ /* Call WH_SHELL hook */
if (!(wndPtr->dwStyle & WS_CHILD) && !GetWindow( hwnd, GW_OWNER )) if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) && !GetWindow( hwnd, GW_OWNER ))
HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWCREATED, (WPARAM)hwnd, 0 ); HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWCREATED, (WPARAM)hwnd, 0 );
TRACE("created window %04x\n", hwnd); TRACE("created window %04x\n", hwnd);
end:
WIN_ReleaseWndPtr(wndPtr);
return hwnd; return hwnd;
} }
@ -1524,27 +1599,31 @@ BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
{ {
WND *wndPtr; WND *wndPtr;
BOOL retvalue; BOOL retvalue;
LONG style;
HWND full_handle;
if (!(full_handle = WIN_IsCurrentThread( hwnd )))
return SendMessageW( hwnd, WM_WINE_ENABLEWINDOW, enable, 0 );
hwnd = full_handle;
TRACE("( %x, %d )\n", hwnd, enable); TRACE("( %x, %d )\n", hwnd, enable);
if (USER_Driver.pEnableWindow) if (!(wndPtr = WIN_GetPtr( hwnd ))) return FALSE;
return USER_Driver.pEnableWindow( hwnd, enable ); style = wndPtr->dwStyle;
retvalue = ((style & WS_DISABLED) != 0);
WIN_ReleasePtr( wndPtr );
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; if (enable && retvalue)
hwnd = wndPtr->hwndSelf; /* make it a full handle */
retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
if (enable && (wndPtr->dwStyle & WS_DISABLED))
{ {
wndPtr->dwStyle &= ~WS_DISABLED; /* Enable window */ WIN_SetStyle( hwnd, style & ~WS_DISABLED );
SendMessageA( hwnd, WM_ENABLE, TRUE, 0 ); SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
} }
else if (!enable && !(wndPtr->dwStyle & WS_DISABLED)) else if (!enable && !retvalue)
{ {
SendMessageA( hwnd, WM_CANCELMODE, 0, 0); SendMessageA( hwnd, WM_CANCELMODE, 0, 0);
wndPtr->dwStyle |= WS_DISABLED; /* Disable window */ WIN_SetStyle( hwnd, style | WS_DISABLED );
if (hwnd == GetFocus()) if (hwnd == GetFocus())
SetFocus( 0 ); /* A disabled window can't have the focus */ SetFocus( 0 ); /* A disabled window can't have the focus */
@ -1554,7 +1633,6 @@ BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
SendMessageA( hwnd, WM_ENABLE, FALSE, 0 ); SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
} }
WIN_ReleaseWndPtr(wndPtr);
return retvalue; return retvalue;
} }
@ -1588,22 +1666,32 @@ BOOL WINAPI IsWindowUnicode( HWND hwnd )
*/ */
WORD WINAPI GetWindowWord( HWND hwnd, INT offset ) WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
{ {
WORD retvalue;
WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return 0;
if (offset >= 0) if (offset >= 0)
{ {
if (offset + sizeof(WORD) > wndPtr->cbWndExtra) WORD retvalue = 0;
WND *wndPtr = WIN_GetPtr( hwnd );
if (!wndPtr)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (wndPtr == WND_OTHER_PROCESS)
{
if (IsWindow( hwnd ))
FIXME( "(%d) not supported yet on other process window %x\n", offset, hwnd );
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (offset > wndPtr->cbWndExtra - sizeof(WORD))
{ {
WARN("Invalid offset %d\n", offset ); WARN("Invalid offset %d\n", offset );
retvalue = 0; SetLastError( ERROR_INVALID_INDEX );
} }
else retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset); else retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset);
WIN_ReleaseWndPtr(wndPtr); WIN_ReleasePtr( wndPtr );
return retvalue; return retvalue;
} }
WIN_ReleaseWndPtr(wndPtr);
switch(offset) switch(offset)
{ {
case GWL_HWNDPARENT: case GWL_HWNDPARENT:
@ -1629,24 +1717,8 @@ WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval ) WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
{ {
WORD *ptr, retval; WORD *ptr, retval;
WND * wndPtr = WIN_FindWndPtr( hwnd ); WND * wndPtr;
if (!wndPtr) return 0;
if (offset >= 0)
{
if (offset + sizeof(WORD) > wndPtr->cbWndExtra)
{
WARN("Invalid offset %d\n", offset );
WIN_ReleaseWndPtr(wndPtr);
return 0;
}
ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
retval = *ptr;
*ptr = newval;
WIN_ReleaseWndPtr(wndPtr);
return retval;
}
WIN_ReleaseWndPtr(wndPtr);
switch(offset) switch(offset)
{ {
case GWL_ID: case GWL_ID:
@ -1654,9 +1726,40 @@ WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
case GWL_HWNDPARENT: case GWL_HWNDPARENT:
return SetWindowLongW( hwnd, offset, (UINT)newval ); return SetWindowLongW( hwnd, offset, (UINT)newval );
default: default:
if (offset < 0)
{
WARN("Invalid offset %d\n", offset );
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
}
wndPtr = WIN_GetPtr( hwnd );
if (wndPtr == WND_OTHER_PROCESS)
{
if (IsWindow(hwnd))
FIXME( "set %d <- %x not supported yet on other process window %x\n",
offset, newval, hwnd );
wndPtr = NULL;
}
if (!wndPtr)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (offset > wndPtr->cbWndExtra - sizeof(WORD))
{
WARN("Invalid offset %d\n", offset ); WARN("Invalid offset %d\n", offset );
WIN_ReleasePtr(wndPtr);
SetLastError( ERROR_INVALID_INDEX );
return 0; return 0;
} }
ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
retval = *ptr;
*ptr = newval;
WIN_ReleasePtr(wndPtr);
return retval;
} }
@ -1667,49 +1770,87 @@ WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
*/ */
static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type ) static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
{ {
LONG retvalue; LONG retvalue = 0;
WND * wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr;
if (!wndPtr) return 0;
if (offset == GWL_HWNDPARENT) return (LONG)GetParent( hwnd );
if (!(wndPtr = WIN_GetPtr( hwnd )))
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (wndPtr == WND_OTHER_PROCESS)
{
if (offset >= 0)
{
FIXME( "(%d) not supported on other process window %x\n", offset, hwnd );
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (offset == GWL_WNDPROC)
{
SetLastError( ERROR_ACCESS_DENIED );
return 0;
}
SERVER_START_REQ( set_window_info )
{
req->handle = hwnd;
req->flags = 0; /* don't set anything, just retrieve */
if (!SERVER_CALL_ERR())
{
switch(offset)
{
case GWL_STYLE: retvalue = req->style; break;
case GWL_EXSTYLE: retvalue = req->ex_style; break;
case GWL_ID: retvalue = req->id; break;
case GWL_HINSTANCE: retvalue = (ULONG_PTR)req->instance; break;
case GWL_USERDATA: retvalue = (ULONG_PTR)req->user_data; break;
default:
SetLastError( ERROR_INVALID_INDEX );
break;
}
}
}
SERVER_END_REQ;
return retvalue;
}
/* now we have a valid wndPtr */
if (offset >= 0) if (offset >= 0)
{ {
if (offset + sizeof(LONG) > wndPtr->cbWndExtra) if (offset > wndPtr->cbWndExtra - sizeof(LONG))
{ {
WARN("Invalid offset %d\n", offset ); WARN("Invalid offset %d\n", offset );
retvalue = 0; WIN_ReleasePtr( wndPtr );
goto end; SetLastError( ERROR_INVALID_INDEX );
return 0;
} }
retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
/* Special case for dialog window procedure */ /* Special case for dialog window procedure */
if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG)) if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
{
retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type ); retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type );
goto end; else
} retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
goto end; WIN_ReleasePtr( wndPtr );
return retvalue;
} }
switch(offset) switch(offset)
{ {
case GWL_USERDATA: retvalue = wndPtr->userdata; case GWL_USERDATA: retvalue = wndPtr->userdata; break;
goto end; case GWL_STYLE: retvalue = wndPtr->dwStyle; break;
case GWL_STYLE: retvalue = wndPtr->dwStyle; case GWL_EXSTYLE: retvalue = wndPtr->dwExStyle; break;
goto end; case GWL_ID: retvalue = (LONG)wndPtr->wIDmenu; break;
case GWL_EXSTYLE: retvalue = wndPtr->dwExStyle; case GWL_WNDPROC: retvalue = (LONG)WINPROC_GetProc( wndPtr->winproc, type ); break;
goto end; case GWL_HINSTANCE: retvalue = wndPtr->hInstance; break;
case GWL_ID: retvalue = (LONG)wndPtr->wIDmenu; default:
goto end; WARN("Unknown offset %d\n", offset );
case GWL_WNDPROC: retvalue = (LONG)WINPROC_GetProc( wndPtr->winproc, SetLastError( ERROR_INVALID_INDEX );
type ); break;
goto end;
case GWL_HWNDPARENT: retvalue = (LONG)GetParent(hwnd);
goto end;
case GWL_HINSTANCE: retvalue = wndPtr->hInstance;
goto end;
default:
WARN("Unknown offset %d\n", offset );
} }
retvalue = 0; WIN_ReleasePtr(wndPtr);
end:
WIN_ReleaseWndPtr(wndPtr);
return retvalue; return retvalue;
} }
@ -1721,99 +1862,148 @@ end:
* *
* 0 is the failure code. However, in the case of failure SetLastError * 0 is the failure code. However, in the case of failure SetLastError
* must be set to distinguish between a 0 return value and a failure. * must be set to distinguish between a 0 return value and a failure.
*
* FIXME: The error values for SetLastError may not be right. Can
* someone check with the real thing?
*/ */
static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval, static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
WINDOWPROCTYPE type ) WINDOWPROCTYPE type )
{ {
LONG *ptr, retval; LONG retval = 0;
WND * wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr;
STYLESTRUCT style;
TRACE("%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type); TRACE( "%x %d %lx %x\n", hwnd, offset, newval, type );
if (!wndPtr) if (!WIN_IsCurrentThread( hwnd ))
{ {
/* Is this the right error? */ ERR("set %x %d %x\n", hwnd, offset, newval );
SetLastError( ERROR_INVALID_WINDOW_HANDLE ); return SendMessageW( hwnd, WM_WINE_SETWINDOWLONG, offset, newval );
return 0;
} }
wndPtr = WIN_GetPtr( hwnd );
if (offset >= 0) if (offset >= 0)
{ {
if (offset + sizeof(LONG) > wndPtr->cbWndExtra) LONG *ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
if (offset > wndPtr->cbWndExtra - sizeof(LONG))
{ {
WARN("Invalid offset %d\n", offset ); WARN("Invalid offset %d\n", offset );
WIN_ReleasePtr( wndPtr );
/* Is this the right error? */ SetLastError( ERROR_INVALID_INDEX );
SetLastError( ERROR_OUTOFMEMORY ); return 0;
retval = 0;
goto end;
} }
ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
/* Special case for dialog window procedure */ /* Special case for dialog window procedure */
if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG)) if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
{ {
retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type ); retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval, WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
type, WIN_PROC_WINDOW ); type, WIN_PROC_WINDOW );
goto end; WIN_ReleasePtr( wndPtr );
return retval;
} }
retval = *ptr;
*ptr = newval;
WIN_ReleasePtr( wndPtr );
} }
else switch(offset) else
{ {
case GWL_ID: STYLESTRUCT style;
ptr = (DWORD*)&wndPtr->wIDmenu; BOOL ok;
break;
case GWL_HINSTANCE: /* first some special cases */
ptr = (DWORD*)&wndPtr->hInstance; switch( offset )
break; {
case GWL_USERDATA: case GWL_STYLE:
ptr = &wndPtr->userdata;
break;
case GWL_HWNDPARENT:
retval = SetParent( hwnd, (HWND)newval );
goto end;
case GWL_WNDPROC:
retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
type, WIN_PROC_WINDOW );
goto end;
case GWL_STYLE:
retval = wndPtr->dwStyle;
style.styleOld = wndPtr->dwStyle;
style.styleNew = newval;
SendMessageA(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
wndPtr->dwStyle = style.styleNew;
if (USER_Driver.pSetWindowStyle) USER_Driver.pSetWindowStyle( hwnd, retval );
SendMessageA(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
retval = style.styleOld;
goto end;
case GWL_EXSTYLE: case GWL_EXSTYLE:
style.styleOld = wndPtr->dwExStyle; style.styleOld = wndPtr->dwStyle;
style.styleNew = newval; style.styleNew = newval;
SendMessageA(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style); WIN_ReleasePtr( wndPtr );
wndPtr->dwExStyle = style.styleNew; SendMessageW( hwnd, WM_STYLECHANGING, offset, (LPARAM)&style );
SendMessageA(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style); if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
retval = style.styleOld; newval = style.styleNew;
goto end; break;
case GWL_HWNDPARENT:
default: WIN_ReleasePtr( wndPtr );
return (LONG)SetParent( hwnd, (HWND)newval );
case GWL_WNDPROC:
retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
type, WIN_PROC_WINDOW );
WIN_ReleasePtr( wndPtr );
return retval;
case GWL_ID:
case GWL_HINSTANCE:
case GWL_USERDATA:
break;
default:
WIN_ReleasePtr( wndPtr );
WARN("Invalid offset %d\n", offset ); WARN("Invalid offset %d\n", offset );
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
/* Don't think this is right error but it should do */ SERVER_START_REQ( set_window_info )
SetLastError( ERROR_OUTOFMEMORY ); {
req->handle = hwnd;
switch(offset)
{
case GWL_STYLE:
req->flags = SET_WIN_STYLE;
req->style = newval;
break;
case GWL_EXSTYLE:
req->flags = SET_WIN_EXSTYLE;
req->ex_style = newval;
break;
case GWL_ID:
req->flags = SET_WIN_ID;
req->id = newval;
break;
case GWL_HINSTANCE:
req->flags = SET_WIN_INSTANCE;
req->instance = (void *)newval;
break;
case GWL_USERDATA:
req->flags = SET_WIN_USERDATA;
req->user_data = (void *)newval;
break;
}
if ((ok = !SERVER_CALL_ERR()))
{
switch(offset)
{
case GWL_STYLE:
wndPtr->dwStyle = newval;
retval = req->old_style;
break;
case GWL_EXSTYLE:
wndPtr->dwExStyle = newval;
retval = req->old_ex_style;
break;
case GWL_ID:
wndPtr->wIDmenu = newval;
retval = req->old_id;
break;
case GWL_HINSTANCE:
wndPtr->hInstance = newval;
retval = (HINSTANCE)req->old_instance;
break;
case GWL_USERDATA:
wndPtr->userdata = newval;
retval = (ULONG_PTR)req->old_user_data;
break;
}
}
}
SERVER_END_REQ;
WIN_ReleasePtr( wndPtr );
if (!ok) return 0;
if (offset == GWL_STYLE && USER_Driver.pSetWindowStyle)
USER_Driver.pSetWindowStyle( hwnd, retval );
if (offset == GWL_STYLE || offset == GWL_EXSTYLE)
SendMessageW( hwnd, WM_STYLECHANGED, offset, (LPARAM)&style );
retval = 0;
goto end;
} }
retval = *ptr;
*ptr = newval;
end:
WIN_ReleaseWndPtr(wndPtr);
return retval; return retval;
} }
@ -1928,15 +2118,6 @@ LONG WINAPI SetWindowLongA( HWND hwnd, INT offset, LONG newval )
* it sends WM_STYLECHANGING before changing the settings * it sends WM_STYLECHANGING before changing the settings
* and WM_STYLECHANGED afterwards. * and WM_STYLECHANGED afterwards.
* App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST. * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
*
* BUGS
*
* GWL_STYLE does not dispatch WM_STYLE... messages.
*
* CONFORMANCE
*
* ECMA-234, Win32
*
*/ */
LONG WINAPI SetWindowLongW( LONG WINAPI SetWindowLongW(
HWND hwnd, /* [in] window to alter */ HWND hwnd, /* [in] window to alter */
@ -2089,13 +2270,33 @@ HWND WINAPI GetParent( HWND hwnd )
WND *wndPtr; WND *wndPtr;
HWND retvalue = 0; HWND retvalue = 0;
if ((wndPtr = WIN_FindWndPtr(hwnd))) if (!(wndPtr = WIN_GetPtr( hwnd )))
{ {
if (wndPtr->dwStyle & WS_CHILD) SetLastError( ERROR_INVALID_WINDOW_HANDLE );
retvalue = wndPtr->parent; return 0;
else if (wndPtr->dwStyle & WS_POPUP) }
retvalue = wndPtr->owner; if (wndPtr == WND_OTHER_PROCESS)
WIN_ReleaseWndPtr(wndPtr); {
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
if (style & (WS_POPUP | WS_CHILD))
{
SERVER_START_REQ( get_window_tree )
{
req->handle = hwnd;
if (!SERVER_CALL_ERR())
{
if (style & WS_CHILD) retvalue = req->parent;
else retvalue = req->owner;
}
}
SERVER_END_REQ;
}
}
else
{
if (wndPtr->dwStyle & WS_CHILD) retvalue = wndPtr->parent;
else if (wndPtr->dwStyle & WS_POPUP) retvalue = wndPtr->owner;
WIN_ReleasePtr( wndPtr );
} }
return retvalue; return retvalue;
} }
@ -2106,8 +2307,30 @@ HWND WINAPI GetParent( HWND hwnd )
*/ */
HWND WINAPI GetAncestor( HWND hwnd, UINT type ) HWND WINAPI GetAncestor( HWND hwnd, UINT type )
{ {
WND *win;
HWND ret = 0; HWND ret = 0;
size_t size = (type == GA_PARENT) ? sizeof(user_handle_t) : REQUEST_MAX_VAR_SIZE; size_t size;
for (;;)
{
if (!(win = WIN_GetPtr( hwnd )))
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (win == WND_OTHER_PROCESS) break; /* need to do it the hard way */
ret = win->parent;
WIN_ReleasePtr( win );
if (type == GA_PARENT) return ret;
if (!ret || ret == GetDesktopWindow())
{
ret = hwnd; /* if ret is the desktop, hwnd is the root ancestor */
goto done;
}
hwnd = ret; /* restart with parent as hwnd */
}
size = (type == GA_PARENT) ? sizeof(user_handle_t) : REQUEST_MAX_VAR_SIZE;
SERVER_START_VAR_REQ( get_window_parents, size ) SERVER_START_VAR_REQ( get_window_parents, size )
{ {
@ -2134,6 +2357,7 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type )
} }
SERVER_END_VAR_REQ; SERVER_END_VAR_REQ;
done:
if (ret && type == GA_ROOTOWNER) if (ret && type == GA_ROOTOWNER)
{ {
for (;;) for (;;)
@ -2148,16 +2372,28 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type )
/***************************************************************** /*****************************************************************
* WIN_SetParent * SetParent (USER32.@)
*
* Implementation of SetParent, runs in the thread owning the window.
*/ */
HWND WIN_SetParent( HWND hwnd, HWND parent ) HWND WINAPI SetParent( HWND hwnd, HWND parent )
{ {
WND *wndPtr; WND *wndPtr;
HWND retvalue; HWND retvalue, full_handle;
BOOL was_visible; BOOL was_visible;
if (!parent) parent = GetDesktopWindow();
else parent = WIN_GetFullHandle( parent );
if (!IsWindow( parent ))
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (!(full_handle = WIN_IsCurrentThread( hwnd )))
return SendMessageW( hwnd, WM_WINE_SETPARENT, (WPARAM)parent, 0 );
hwnd = full_handle;
if (USER_Driver.pSetParent) if (USER_Driver.pSetParent)
return USER_Driver.pSetParent( hwnd, parent ); return USER_Driver.pSetParent( hwnd, parent );
@ -2196,34 +2432,6 @@ HWND WIN_SetParent( HWND hwnd, HWND parent )
} }
/*****************************************************************
* SetParent (USER32.@)
*/
HWND WINAPI SetParent( HWND hwnd, HWND parent )
{
HWND full_handle;
if (!parent) parent = GetDesktopWindow();
else parent = WIN_GetFullHandle( parent );
if (!IsWindow( parent ))
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if ((full_handle = WIN_IsCurrentThread( hwnd )))
return WIN_SetParent( full_handle, parent );
if ((full_handle = WIN_GetFullHandle(hwnd)) == GetDesktopWindow())
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
return SendMessageW( full_handle, WM_WINE_SETPARENT, (WPARAM)parent, 0 );
}
/******************************************************************* /*******************************************************************
* IsChild (USER32.@) * IsChild (USER32.@)
*/ */
@ -2305,13 +2513,21 @@ HWND WINAPI GetWindow( HWND hwnd, UINT rel )
{ {
HWND retval = 0; HWND retval = 0;
if (rel == GW_OWNER) /* special case: not fully supported in the server yet */ if (rel == GW_OWNER) /* this one may be available locally */
{ {
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr = WIN_GetPtr( hwnd );
if (!wndPtr) return 0; if (!wndPtr)
retval = wndPtr->owner; {
WIN_ReleaseWndPtr( wndPtr ); SetLastError( ERROR_INVALID_HANDLE );
return retval; return 0;
}
if (wndPtr != WND_OTHER_PROCESS)
{
retval = wndPtr->owner;
WIN_ReleasePtr( wndPtr );
return retval;
}
/* else fall through to server call */
} }
SERVER_START_REQ( get_window_tree ) SERVER_START_REQ( get_window_tree )
@ -2333,6 +2549,9 @@ HWND WINAPI GetWindow( HWND hwnd, UINT rel )
case GW_HWNDPREV: case GW_HWNDPREV:
retval = req->prev_sibling; retval = req->prev_sibling;
break; break;
case GW_OWNER:
retval = req->owner;
break;
case GW_CHILD: case GW_CHILD:
retval = req->first_child; retval = req->first_child;
break; break;

View File

@ -215,15 +215,25 @@ BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn ) int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
{ {
int nRet = ERROR; int nRet = ERROR;
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr = WIN_GetPtr( hwnd );
if (wndPtr)
if (wndPtr == WND_OTHER_PROCESS)
{ {
if (wndPtr->hrgnWnd) nRet = CombineRgn( hrgn, wndPtr->hrgnWnd, 0, RGN_COPY ); if (IsWindow( hwnd ))
WIN_ReleaseWndPtr(wndPtr); FIXME( "not supported on other process window %x\n", hwnd );
wndPtr = NULL;
} }
if (!wndPtr)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return ERROR;
}
if (wndPtr->hrgnWnd) nRet = CombineRgn( hrgn, wndPtr->hrgnWnd, 0, RGN_COPY );
WIN_ReleasePtr( wndPtr );
return nRet; return nRet;
} }
/*********************************************************************** /***********************************************************************
* SetWindowRgn (USER32.@) * SetWindowRgn (USER32.@)
*/ */
@ -231,22 +241,31 @@ int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
{ {
RECT rect; RECT rect;
WND *wndPtr; WND *wndPtr;
int ret = FALSE;
if (hrgn) /* verify that region really exists */
{
if (GetRgnBox( hrgn, &rect ) == ERROR) return FALSE;
}
if (USER_Driver.pSetWindowRgn) if (USER_Driver.pSetWindowRgn)
return USER_Driver.pSetWindowRgn( hwnd, hrgn, bRedraw ); return USER_Driver.pSetWindowRgn( hwnd, hrgn, bRedraw );
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE; if ((wndPtr = WIN_GetPtr( hwnd )) == WND_OTHER_PROCESS)
{
if (IsWindow( hwnd ))
FIXME( "not supported on other process window %x\n", hwnd );
wndPtr = NULL;
}
if (!wndPtr)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return FALSE;
}
if (wndPtr->hrgnWnd == hrgn) if (wndPtr->hrgnWnd == hrgn)
{ {
ret = TRUE; WIN_ReleasePtr( wndPtr );
goto done; return TRUE;
}
if (hrgn) /* verify that region really exists */
{
if (GetRgnBox( hrgn, &rect ) == ERROR) goto done;
} }
if (wndPtr->hrgnWnd) if (wndPtr->hrgnWnd)
@ -256,17 +275,14 @@ int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
wndPtr->hrgnWnd = 0; wndPtr->hrgnWnd = 0;
} }
wndPtr->hrgnWnd = hrgn; wndPtr->hrgnWnd = hrgn;
WIN_ReleasePtr( wndPtr );
/* Size the window to the rectangle of the new region (if it isn't NULL) */ /* Size the window to the rectangle of the new region (if it isn't NULL) */
if (hrgn) SetWindowPos( hwnd, 0, rect.left, rect.top, if (hrgn) SetWindowPos( hwnd, 0, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top, rect.right - rect.left, rect.bottom - rect.top,
SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE |
SWP_NOZORDER | (bRedraw ? 0 : SWP_NOREDRAW) ); SWP_NOZORDER | (bRedraw ? 0 : SWP_NOREDRAW) );
ret = TRUE; return TRUE;
done:
WIN_ReleaseWndPtr(wndPtr);
return ret;
} }