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 fShowH, BOOL fShowV )
{
WND *wndPtr = WIN_FindWndPtr( hwnd );
BOOL retvalue = FALSE;
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
if (!wndPtr) return FALSE;
TRACE("hwnd=%04x bar=%d horz=%d, vert=%d\n",
hwnd, nBar, fShowH, fShowV );
@ -1725,20 +1723,19 @@ BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar,
{
case SB_CTL:
ShowWindow( hwnd, fShowH ? SW_SHOW : SW_HIDE );
retvalue = TRUE;
goto END;
return TRUE;
case SB_BOTH:
case SB_HORZ:
if (fShowH)
{
fShowH = !(wndPtr->dwStyle & WS_HSCROLL);
wndPtr->dwStyle |= WS_HSCROLL;
fShowH = !(style & WS_HSCROLL);
style |= WS_HSCROLL;
}
else /* hide it */
{
fShowH = (wndPtr->dwStyle & WS_HSCROLL);
wndPtr->dwStyle &= ~WS_HSCROLL;
fShowH = (style & WS_HSCROLL);
style &= ~WS_HSCROLL;
}
if( nBar == SB_HORZ ) {
fShowV = FALSE;
@ -1749,35 +1746,30 @@ BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar,
case SB_VERT:
if (fShowV)
{
fShowV = !(wndPtr->dwStyle & WS_VSCROLL);
wndPtr->dwStyle |= WS_VSCROLL;
fShowV = !(style & WS_VSCROLL);
style |= WS_VSCROLL;
}
else /* hide it */
{
fShowV = (wndPtr->dwStyle & WS_VSCROLL);
wndPtr->dwStyle &= ~WS_VSCROLL;
fShowV = (style & WS_VSCROLL);
style &= ~WS_VSCROLL;
}
if ( nBar == SB_VERT )
fShowH = FALSE;
break;
default:
retvalue = FALSE; /* Nothing to do! */
goto END;
return FALSE; /* Nothing to do! */
}
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
| SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
retvalue = TRUE;
goto END;
return TRUE;
}
retvalue = FALSE; /* no frame changes */
END:
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
return FALSE; /* no frame changes */
}

View File

@ -609,13 +609,9 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect );
if( winpos->flags & SWP_SHOWWINDOW )
{
wndPtr->dwStyle |= WS_VISIBLE;
}
WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle | WS_VISIBLE );
else if( winpos->flags & SWP_HIDEWINDOW )
{
wndPtr->dwStyle &= ~WS_VISIBLE;
}
WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle & ~WS_VISIBLE );
/* ------------------------------------------------------------------------ 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 )
{
if (hwnd == GetDesktopWindow()) return 0;
switch(msg)
{
case WM_WINE_DESTROYWINDOW:
return WIN_DestroyWindow( hwnd );
case WM_WINE_SETWINDOWPOS:
return USER_Driver.pSetWindowPos( (WINDOWPOS *)lparam );
case WM_WINE_SHOWWINDOW:
return USER_Driver.pShowWindow( hwnd, wparam );
case WM_WINE_DESTROYWINDOW:
return WIN_DestroyWindow( hwnd );
return ShowWindow( hwnd, wparam );
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:
FIXME( "unknown internal message %x\n", msg );
return 0;

View File

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

View File

@ -22,6 +22,7 @@
#include "debugtools.h"
#include "x11drv.h"
#include "win.h"
#include "winpos.h"
#include "dce.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 managed = is_top_level && is_window_managed( win );
if (managed) win->dwExStyle |= WS_EX_MANAGED;
else win->dwExStyle &= ~WS_EX_MANAGED;
if (managed) WIN_SetExStyle( win->hwndSelf, win->dwExStyle | WS_EX_MANAGED );
else WIN_SetExStyle( win->hwndSelf, win->dwExStyle & ~WS_EX_MANAGED );
attr->override_redirect = !managed;
attr->colormap = X11DRV_PALETTE_PaletteXColormap;
@ -833,13 +834,17 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
data->hWMIconBitmap = 0;
data->hWMIconMask = 0;
wndPtr = WIN_FindWndPtr( hwnd );
wndPtr = WIN_GetPtr( hwnd );
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)
{
create_desktop( display, wndPtr, cs );
WIN_ReleaseWndPtr( wndPtr );
WIN_ReleasePtr( wndPtr );
return TRUE;
}
@ -847,11 +852,30 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
if (!create_client_window( display, wndPtr )) goto failed;
TSXSync( display, False );
WIN_ReleaseWndPtr( wndPtr );
SetPropA( hwnd, whole_window_atom, (HANDLE)data->whole_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 */
TRACE( "hwnd %x cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cs->cx, cs->cy );
if (unicode)
@ -860,17 +884,20 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
ret = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
if (!ret)
{
X11DRV_DestroyWindow( hwnd );
WARN("aborted by WM_xxCREATE!\n");
return FALSE;
}
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
if (!(wndPtr = WIN_GetPtr(hwnd))) return FALSE;
sync_window_style( display, wndPtr );
/* send WM_NCCALCSIZE */
rect = wndPtr->rectWindow;
WIN_ReleasePtr( wndPtr );
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;
WIN_SetRectangles( hwnd, &wndPtr->rectWindow, &rect );
X11DRV_sync_client_window_position( display, wndPtr );
@ -892,7 +919,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
else
WIN_LinkWindow( hwnd, wndPtr->parent, HWND_TOP );
WIN_ReleaseWndPtr( wndPtr );
WIN_ReleasePtr( wndPtr );
if (unicode)
ret = (SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1);
@ -902,7 +929,6 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
if (!ret)
{
WIN_UnlinkWindow( hwnd );
X11DRV_DestroyWindow( hwnd );
return FALSE;
}
@ -932,7 +958,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
RECT newPos;
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 );
swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow())
? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
@ -946,8 +972,8 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
failed:
X11DRV_DestroyWindow( wndPtr->hwndSelf );
WIN_ReleaseWndPtr( wndPtr );
X11DRV_DestroyWindow( hwnd );
if (wndPtr) WIN_ReleasePtr( wndPtr );
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.@)
*

View File

@ -14,6 +14,7 @@
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "x11drv.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 )
{
WND *win = WIN_FindWndPtr( hwnd );
WND *win = WIN_GetPtr( hwnd );
HWND top = 0;
X11DRV_WND_DATA *data = win->pDriverData;
Drawable drawable;
@ -505,7 +506,7 @@ BOOL X11DRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
DeleteObject( visRgn );
}
WIN_ReleaseWndPtr( win );
WIN_ReleasePtr( win );
return TRUE;
}
@ -675,10 +676,14 @@ static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
/* fix redundant flags and values in the WINDOWPOS structure */
static BOOL fixup_flags( WINDOWPOS *winpos )
{
WND *wndPtr = WIN_FindWndPtr( winpos->hwnd );
WND *wndPtr = WIN_GetPtr( winpos->hwnd );
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 */
if (wndPtr->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW;
@ -723,11 +728,8 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
/* hwndInsertAfter must be a sibling of the window */
if ((winpos->hwndInsertAfter != HWND_TOP) && (winpos->hwndInsertAfter != HWND_BOTTOM))
{
WND* wnd = WIN_FindWndPtr(winpos->hwndInsertAfter);
if (wnd)
{
winpos->hwndInsertAfter = wnd->hwndSelf; /* make it a full handle */
if (wnd->parent != wndPtr->parent) ret = FALSE;
winpos->hwndInsertAfter = WIN_GetFullHandle( winpos->hwndInsertAfter );
if (GetAncestor( winpos->hwndInsertAfter, GA_PARENT ) != wndPtr->parent) ret = FALSE;
else
{
/* don't need to change the Zorder of hwnd if it's already inserted
@ -737,11 +739,9 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
(winpos->hwnd == GetWindow( winpos->hwndInsertAfter, GW_HWNDNEXT )))
winpos->flags |= SWP_NOZORDER;
}
WIN_ReleaseWndPtr(wnd);
}
}
done:
WIN_ReleaseWndPtr(wndPtr);
WIN_ReleasePtr( wndPtr );
return ret;
}
@ -754,18 +754,51 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
void X11DRV_SetWindowStyle( HWND hwnd, LONG oldStyle )
{
Display *display = thread_display();
WND *wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return;
WND *wndPtr;
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 (wndPtr->dwStyle & WS_VISIBLE)
{
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 );
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 */
{
Display *display = thread_display();
wine_tsx11_lock();
if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
{
if (!IsRectEmpty( &oldWindowRect ))
{
XUnmapWindow( display, get_whole_window(wndPtr) );
TRACE( "unmapping win %x\n", winpos->hwnd );
}
else TRACE( "not unmapping zero size win %x\n", winpos->hwnd );
WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle & ~WS_VISIBLE );
/* clear the update region */
// RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE | RDW_NOFRAME |
// RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN );
}
else if ((wndPtr->dwStyle & WS_VISIBLE) &&
!IsRectEmpty( &oldWindowRect ) && IsRectEmpty( &newWindowRect ))
{
/* resizing to zero size -> unmap */
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)
X11DRV_sync_whole_window_position( display, wndPtr, !(winpos->flags & SWP_NOZORDER) );
else
@ -893,12 +915,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
}
if (winpos->flags & SWP_SHOWWINDOW)
{
if (!IsRectEmpty( &newWindowRect ))
{
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 );
WIN_SetStyle( winpos->hwnd, wndPtr->dwStyle | WS_VISIBLE );
}
else if ((wndPtr->dwStyle & WS_VISIBLE) &&
IsRectEmpty( &oldWindowRect ) && !IsRectEmpty( &newWindowRect ))
@ -910,6 +927,13 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
XFlush( display ); /* FIXME: should not be necessary */
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 */
@ -1021,6 +1045,7 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
WND *wndPtr;
UINT swpFlags = 0;
POINT size;
LONG old_style;
WINDOWPLACEMENT wpl;
TRACE("0x%04x %u\n", hwnd, cmd );
@ -1046,14 +1071,10 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
switch( cmd )
{
case SW_MINIMIZE:
if( wndPtr->dwStyle & WS_MAXIMIZE)
{
wndPtr->flags |= WIN_RESTORE_MAX;
wndPtr->dwStyle &= ~WS_MAXIMIZE;
}
else
wndPtr->flags &= ~WIN_RESTORE_MAX;
wndPtr->dwStyle |= WS_MINIMIZE;
if( wndPtr->dwStyle & WS_MAXIMIZE) wndPtr->flags |= WIN_RESTORE_MAX;
else wndPtr->flags &= ~WIN_RESTORE_MAX;
WIN_SetStyle( hwnd, (wndPtr->dwStyle & ~WS_MAXIMIZE) | WS_MINIMIZE );
X11DRV_set_iconic_state( wndPtr );
@ -1067,21 +1088,19 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
case SW_MAXIMIZE:
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 );
X11DRV_set_iconic_state( wndPtr );
}
wndPtr->dwStyle |= WS_MAXIMIZE;
SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
break;
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 );
X11DRV_set_iconic_state( wndPtr );
@ -1089,16 +1108,12 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
{
/* Restore to maximized position */
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 );
break;
}
}
else
{
if (!(wndPtr->dwStyle & WS_MAXIMIZE)) break;
wndPtr->dwStyle &= ~WS_MAXIMIZE;
}
else if (!(old_style & WS_MAXIMIZE)) break;
/* Restore to normal position */
@ -1250,7 +1265,7 @@ void X11DRV_MapNotify( HWND hwnd, XMapEvent *event )
HWND hwndFocus = GetFocus();
WND *win;
if (!(win = WIN_FindWndPtr( hwnd ))) return;
if (!(win = WIN_GetPtr( hwnd ))) return;
if ((win->dwStyle & WS_VISIBLE) &&
(win->dwStyle & WS_MINIMIZE) &&
@ -1260,16 +1275,7 @@ void X11DRV_MapNotify( HWND hwnd, XMapEvent *event )
unsigned int width, height, border, depth;
Window root, top;
RECT rect;
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;
LONG style = (win->dwStyle & ~(WS_MINIMIZE|WS_MAXIMIZE)) | WS_VISIBLE;
/* FIXME: hack */
wine_tsx11_lock();
@ -1283,12 +1289,19 @@ void X11DRV_MapNotify( HWND hwnd, XMapEvent *event )
rect.bottom = y + height;
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 );
SetWindowPos( hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
SWP_NOZORDER | SWP_WINE_NOHOSTMOVE );
}
else WIN_ReleasePtr( win );
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;
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_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();
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),
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_WINE_NOHOSTMOVE );
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)
*/
BOOL X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
int X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
{
RECT rect;
WND *wndPtr = WIN_FindWndPtr(hwnd);
int ret = FALSE;
WND *wndPtr;
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)
{
ret = TRUE;
goto done;
}
if (hrgn) /* verify that region really exists */
{
if (GetRgnBox( hrgn, &rect ) == ERROR) goto done;
WIN_ReleasePtr( wndPtr );
return TRUE;
}
if (wndPtr->hrgnWnd)
@ -1584,8 +1598,11 @@ BOOL X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
DWORD size;
DWORD dwBufferSize = GetRegionData(hrgn, 0, NULL);
PRGNDATA pRegionData = HeapAlloc(GetProcessHeap(), 0, dwBufferSize);
if (!pRegionData) goto done;
if (!pRegionData)
{
WIN_ReleasePtr( wndPtr );
return TRUE;
}
GetRegionData(hrgn, dwBufferSize, pRegionData);
size = pRegionData->rdh.nCount;
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 */
WIN_ReleasePtr( wndPtr );
if (redraw) RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE );
ret = TRUE;
done:
WIN_ReleaseWndPtr(wndPtr);
return ret;
return TRUE;
}

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 DestroyWindow(long) X11DRV_DestroyWindow
@ cdecl GetDC(long long long long) X11DRV_GetDC
@ cdecl EnableWindow(long long) X11DRV_EnableWindow
@ cdecl ForceWindowRaise(long) X11DRV_ForceWindowRaise
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx
@ 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_SETWINDOWPOS,
WM_WINE_SHOWWINDOW,
WM_WINE_SETPARENT
WM_WINE_SETPARENT,
WM_WINE_SETWINDOWLONG,
WM_WINE_ENABLEWINDOW
};
/* internal SendInput codes (FIXME) */
@ -79,7 +81,6 @@ typedef struct tagUSER_DRIVER {
BOOL (*pCreateWindow)(HWND,CREATESTRUCTA*,BOOL);
BOOL (*pDestroyWindow)(HWND);
BOOL (*pGetDC)(HWND,HDC,HRGN,DWORD);
BOOL (*pEnableWindow)(HWND,BOOL);
void (*pForceWindowRaise)(HWND);
DWORD (*pMsgWaitForMultipleObjectsEx)(DWORD,const HANDLE*,DWORD,DWORD,DWORD);
BOOL (*pScrollDC)(HDC,INT,INT,const RECT*,const RECT*,HRGN,LPRECT);
@ -87,7 +88,7 @@ typedef struct tagUSER_DRIVER {
void (*pSetFocus)(HWND);
HWND (*pSetParent)(HWND,HWND);
BOOL (*pSetWindowPos)(WINDOWPOS *);
BOOL (*pSetWindowRgn)(HWND,HRGN,BOOL);
int (*pSetWindowRgn)(HWND,HRGN,BOOL);
HICON (*pSetWindowIcon)(HWND,HICON,BOOL);
void (*pSetWindowStyle)(HWND,DWORD);
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_UnlinkWindow( HWND hwnd );
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 HWND WIN_FindWinToRepaint( 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 HWND *WIN_ListParents( 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 );
inline static HWND WIN_GetFullHandle( HWND hwnd )

View File

@ -1601,6 +1601,7 @@ struct link_window_request
user_handle_t handle;
user_handle_t parent;
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 request_header __header;
@ -1620,10 +1631,35 @@ struct get_window_info_request
user_handle_t full_handle;
void* pid;
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 request_header __header;
@ -1858,7 +1894,9 @@ enum request
REQ_create_window,
REQ_link_window,
REQ_destroy_window,
REQ_set_window_owner,
REQ_get_window_info,
REQ_set_window_info,
REQ_get_window_parents,
REQ_get_window_children,
REQ_get_window_tree,
@ -2001,7 +2039,9 @@ union generic_request
struct create_window_request create_window;
struct link_window_request link_window;
struct destroy_window_request destroy_window;
struct set_window_owner_request set_window_owner;
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_children_request get_window_children;
struct get_window_tree_request get_window_tree;
@ -2014,6 +2054,6 @@ union generic_request
struct get_window_properties_request get_window_properties;
};
#define SERVER_PROTOCOL_VERSION 60
#define SERVER_PROTOCOL_VERSION 61
#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 previous; /* previous child in Z-order */
@REPLY
user_handle_t full_parent; /* full handle of new parent */
@END
@ -1443,6 +1444,15 @@ enum message_type
@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 */
@REQ(get_window_info)
user_handle_t handle; /* handle to the window */
@ -1450,9 +1460,33 @@ enum message_type
user_handle_t full_handle; /* full 32-bit handle */
void* pid; /* process owning the window */
void* tid; /* thread owning the window */
atom_t atom; /* class atom */
@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 */
@REQ(get_window_parents)
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(link_window);
DECL_HANDLER(destroy_window);
DECL_HANDLER(set_window_owner);
DECL_HANDLER(get_window_info);
DECL_HANDLER(set_window_info);
DECL_HANDLER(get_window_parents);
DECL_HANDLER(get_window_children);
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_link_window,
(req_handler)req_destroy_window,
(req_handler)req_set_window_owner,
(req_handler)req_get_window_info,
(req_handler)req_set_window_info,
(req_handler)req_get_window_parents,
(req_handler)req_get_window_children,
(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 );
}
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 )
{
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 )
{
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, " 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 )
@ -1970,7 +2007,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_window_request,
(dump_func)dump_link_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_set_window_info_request,
(dump_func)dump_get_window_parents_request,
(dump_func)dump_get_window_children_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)dump_get_named_pipe_info_reply,
(dump_func)dump_create_window_reply,
(dump_func)dump_link_window_reply,
(dump_func)0,
(dump_func)0,
(dump_func)dump_set_window_owner_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_children_reply,
(dump_func)dump_get_window_tree_reply,
@ -2248,7 +2289,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_window",
"link_window",
"destroy_window",
"set_window_owner",
"get_window_info",
"set_window_info",
"get_window_parents",
"get_window_children",
"get_window_tree",

View File

@ -42,6 +42,11 @@ struct window
atom_t atom; /* class atom */
rectangle_t window_rect; /* window 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_alloc; /* number of allocated window properties */
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 (win->parent != parent)
{
win->owner = NULL; /* reset owner if changing parent */
win->parent = parent;
}
if ((win->prev = previous))
{
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->thread = current;
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_alloc = 0;
win->properties = NULL;
@ -323,6 +337,12 @@ DECL_HANDLER(create_window)
if (!(parent = get_window( req->parent ))) 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;
req->handle = win->handle;
}
@ -342,6 +362,7 @@ DECL_HANDLER(link_window)
set_error( STATUS_INVALID_PARAMETER );
return;
}
req->full_parent = parent ? parent->handle : 0;
if (parent && req->previous)
{
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 */
DECL_HANDLER(get_window_info)
{
@ -390,11 +429,30 @@ DECL_HANDLER(get_window_info)
{
req->tid = get_thread_id( win->thread );
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 */
DECL_HANDLER(get_window_parents)
{

View File

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

View File

@ -362,7 +362,6 @@ void WIN_UnlinkWindow( HWND hwnd )
*/
void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
{
BOOL ret;
WND *wndPtr = WIN_GetPtr( hwnd );
if (!wndPtr) return;
@ -377,10 +376,17 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
req->handle = hwnd;
req->parent = parent;
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;
if (ret && parent) wndPtr->parent = WIN_GetFullHandle(parent);
WIN_ReleasePtr( wndPtr );
}
@ -392,12 +398,102 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
*/
void WIN_SetOwner( HWND hwnd, HWND owner )
{
WND *win = WIN_FindWndPtr( hwnd );
if (win)
WND *win = WIN_GetPtr( hwnd );
if (!win) return;
if (win == WND_OTHER_PROCESS)
{
win->owner = owner;
WIN_ReleaseWndPtr( win );
if (IsWindow(hwnd)) ERR( "cannot set owner %x on other process window %x\n", owner, hwnd );
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,10 +699,9 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
wndPtr->hmemTaskQ = 0;
if (!(wndPtr->dwStyle & WS_CHILD))
if (wndPtr->wIDmenu)
{
DestroyMenu( wndPtr->wIDmenu );
wndPtr->wIDmenu = 0;
HMENU menu = (HMENU)SetWindowLongW( hwnd, GWL_ID, 0 );
if (menu) DestroyMenu( menu );
}
if (wndPtr->hSysMenu)
{
@ -682,8 +777,7 @@ BOOL WIN_CreateDesktopWindow(void)
pWndDesktop->hmemTaskQ = 0;
pWndDesktop->hrgnUpdate = 0;
pWndDesktop->hwndLastActive = hwndDesktop;
pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
WS_CLIPSIBLINGS;
pWndDesktop->dwStyle = 0;
pWndDesktop->dwExStyle = 0;
pWndDesktop->clsStyle = clsStyle;
pWndDesktop->dce = NULL;
@ -712,6 +806,7 @@ BOOL WIN_CreateDesktopWindow(void)
SetRect( &rect, 0, 0, cs.cx, cs.cy );
WIN_SetRectangles( hwndDesktop, &rect, &rect );
WIN_SetStyle( hwndDesktop, WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS );
if (!USER_Driver.pCreateWindow( hwndDesktop, &cs, FALSE )) return FALSE;
@ -798,11 +893,9 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
struct tagCLASS *classPtr;
WND *wndPtr;
HWND hwnd, hwndLinkAfter, parent, owner;
POINT maxSize, maxPos, minTrack, maxTrack;
INT wndExtra;
DWORD clsStyle;
WNDPROC winproc;
RECT rect;
DCE *dce;
BOOL unicode = (type == WIN_PROC_32W);
@ -924,8 +1017,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
TRACE("CBT-hook returned 0\n");
free_window_handle( hwnd );
CLASS_RemoveWindow( classPtr );
hwnd = 0;
goto end;
WIN_ReleaseWndPtr(wndPtr);
return 0;
}
}
@ -940,6 +1033,16 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
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 */
@ -947,28 +1050,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
else if (clsStyle & CS_CLASSDC) wndPtr->dce = dce;
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 */
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))
{
WARN("aborted by WM_xxCREATE!\n");
WIN_ReleaseWndPtr( wndPtr );
WIN_DestroyWindow( hwnd );
CLASS_RemoveWindow( classPtr );
return 0;
}
/* Notify the parent window only */
send_parent_notify( hwnd, WM_CREATE );
if( !IsWindow(hwnd) )
{
hwnd = 0;
goto end;
}
if (!IsWindow( hwnd )) return 0;
if (cs->style & WS_VISIBLE)
{
/* 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 );
}
/* 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 );
TRACE("created window %04x\n", hwnd);
end:
WIN_ReleaseWndPtr(wndPtr);
return hwnd;
}
@ -1524,27 +1599,31 @@ BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
{
WND *wndPtr;
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);
if (USER_Driver.pEnableWindow)
return USER_Driver.pEnableWindow( hwnd, enable );
if (!(wndPtr = WIN_GetPtr( hwnd ))) return FALSE;
style = wndPtr->dwStyle;
retvalue = ((style & WS_DISABLED) != 0);
WIN_ReleasePtr( wndPtr );
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))
if (enable && retvalue)
{
wndPtr->dwStyle &= ~WS_DISABLED; /* Enable window */
WIN_SetStyle( hwnd, style & ~WS_DISABLED );
SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
}
else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
else if (!enable && !retvalue)
{
SendMessageA( hwnd, WM_CANCELMODE, 0, 0);
wndPtr->dwStyle |= WS_DISABLED; /* Disable window */
WIN_SetStyle( hwnd, style | WS_DISABLED );
if (hwnd == GetFocus())
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 );
}
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
}
@ -1588,22 +1666,32 @@ BOOL WINAPI IsWindowUnicode( HWND hwnd )
*/
WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
{
WORD retvalue;
WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return 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 );
retvalue = 0;
SetLastError( ERROR_INVALID_INDEX );
}
else retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset);
WIN_ReleaseWndPtr(wndPtr);
WIN_ReleasePtr( wndPtr );
return retvalue;
}
WIN_ReleaseWndPtr(wndPtr);
switch(offset)
{
case GWL_HWNDPARENT:
@ -1629,24 +1717,8 @@ WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
{
WORD *ptr, retval;
WND * wndPtr = WIN_FindWndPtr( hwnd );
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;
}
WND * wndPtr;
WIN_ReleaseWndPtr(wndPtr);
switch(offset)
{
case GWL_ID:
@ -1654,9 +1726,40 @@ WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
case GWL_HWNDPARENT:
return SetWindowLongW( hwnd, offset, (UINT)newval );
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 );
WIN_ReleasePtr(wndPtr);
SetLastError( ERROR_INVALID_INDEX );
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 )
{
LONG retvalue;
WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return 0;
LONG retvalue = 0;
WND *wndPtr;
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)
{
if (offset + sizeof(LONG) > wndPtr->cbWndExtra)
FIXME( "(%d) not supported on other process window %x\n", offset, hwnd );
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (offset == GWL_WNDPROC)
{
WARN("Invalid offset %d\n", offset );
retvalue = 0;
goto end;
SetLastError( ERROR_ACCESS_DENIED );
return 0;
}
retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
/* Special case for dialog window procedure */
if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
SERVER_START_REQ( set_window_info )
{
req->handle = hwnd;
req->flags = 0; /* don't set anything, just retrieve */
if (!SERVER_CALL_ERR())
{
retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type );
goto end;
}
goto end;
}
switch(offset)
{
case GWL_USERDATA: retvalue = wndPtr->userdata;
goto end;
case GWL_STYLE: retvalue = wndPtr->dwStyle;
goto end;
case GWL_EXSTYLE: retvalue = wndPtr->dwExStyle;
goto end;
case GWL_ID: retvalue = (LONG)wndPtr->wIDmenu;
goto end;
case GWL_WNDPROC: retvalue = (LONG)WINPROC_GetProc( wndPtr->winproc,
type );
goto end;
case GWL_HWNDPARENT: retvalue = (LONG)GetParent(hwnd);
goto end;
case GWL_HINSTANCE: retvalue = wndPtr->hInstance;
goto end;
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 > wndPtr->cbWndExtra - sizeof(LONG))
{
WARN("Invalid offset %d\n", offset );
WIN_ReleasePtr( wndPtr );
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
/* Special case for dialog window procedure */
if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type );
else
retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
WIN_ReleasePtr( wndPtr );
return retvalue;
}
switch(offset)
{
case GWL_USERDATA: retvalue = wndPtr->userdata; break;
case GWL_STYLE: retvalue = wndPtr->dwStyle; break;
case GWL_EXSTYLE: retvalue = wndPtr->dwExStyle; break;
case GWL_ID: retvalue = (LONG)wndPtr->wIDmenu; break;
case GWL_WNDPROC: retvalue = (LONG)WINPROC_GetProc( wndPtr->winproc, type ); break;
case GWL_HINSTANCE: retvalue = wndPtr->hInstance; break;
default:
WARN("Unknown offset %d\n", offset );
SetLastError( ERROR_INVALID_INDEX );
break;
}
retvalue = 0;
end:
WIN_ReleaseWndPtr(wndPtr);
WIN_ReleasePtr(wndPtr);
return retvalue;
}
@ -1721,99 +1862,148 @@ end:
*
* 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.
*
* 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,
WINDOWPROCTYPE type )
{
LONG *ptr, retval;
WND * wndPtr = WIN_FindWndPtr( hwnd );
STYLESTRUCT style;
LONG retval = 0;
WND *wndPtr;
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? */
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
ERR("set %x %d %x\n", hwnd, offset, newval );
return SendMessageW( hwnd, WM_WINE_SETWINDOWLONG, offset, newval );
}
wndPtr = WIN_GetPtr( hwnd );
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 );
/* Is this the right error? */
SetLastError( ERROR_OUTOFMEMORY );
retval = 0;
goto end;
WIN_ReleasePtr( wndPtr );
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
/* Special case for dialog window procedure */
if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
{
retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
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:
ptr = (DWORD*)&wndPtr->wIDmenu;
break;
case GWL_HINSTANCE:
ptr = (DWORD*)&wndPtr->hInstance;
break;
case GWL_USERDATA:
ptr = &wndPtr->userdata;
STYLESTRUCT style;
BOOL ok;
/* first some special cases */
switch( offset )
{
case GWL_STYLE:
case GWL_EXSTYLE:
style.styleOld = wndPtr->dwStyle;
style.styleNew = newval;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_STYLECHANGING, offset, (LPARAM)&style );
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
newval = style.styleNew;
break;
case GWL_HWNDPARENT:
retval = SetParent( hwnd, (HWND)newval );
goto end;
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 );
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:
style.styleOld = wndPtr->dwExStyle;
style.styleNew = newval;
SendMessageA(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
wndPtr->dwExStyle = style.styleNew;
SendMessageA(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
retval = style.styleOld;
goto end;
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 );
/* Don't think this is right error but it should do */
SetLastError( ERROR_OUTOFMEMORY );
retval = 0;
goto end;
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
SERVER_START_REQ( set_window_info )
{
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 = *ptr;
*ptr = newval;
end:
WIN_ReleaseWndPtr(wndPtr);
return retval;
}
@ -1928,15 +2118,6 @@ LONG WINAPI SetWindowLongA( HWND hwnd, INT offset, LONG newval )
* it sends WM_STYLECHANGING before changing the settings
* and WM_STYLECHANGED afterwards.
* 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(
HWND hwnd, /* [in] window to alter */
@ -2089,13 +2270,33 @@ HWND WINAPI GetParent( HWND hwnd )
WND *wndPtr;
HWND retvalue = 0;
if ((wndPtr = WIN_FindWndPtr(hwnd)))
if (!(wndPtr = WIN_GetPtr( hwnd )))
{
if (wndPtr->dwStyle & WS_CHILD)
retvalue = wndPtr->parent;
else if (wndPtr->dwStyle & WS_POPUP)
retvalue = wndPtr->owner;
WIN_ReleaseWndPtr(wndPtr);
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (wndPtr == WND_OTHER_PROCESS)
{
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;
}
@ -2106,8 +2307,30 @@ HWND WINAPI GetParent( HWND hwnd )
*/
HWND WINAPI GetAncestor( HWND hwnd, UINT type )
{
WND *win;
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 )
{
@ -2134,6 +2357,7 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type )
}
SERVER_END_VAR_REQ;
done:
if (ret && type == GA_ROOTOWNER)
{
for (;;)
@ -2148,16 +2372,28 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type )
/*****************************************************************
* WIN_SetParent
*
* Implementation of SetParent, runs in the thread owning the window.
* SetParent (USER32.@)
*/
HWND WIN_SetParent( HWND hwnd, HWND parent )
HWND WINAPI SetParent( HWND hwnd, HWND parent )
{
WND *wndPtr;
HWND retvalue;
HWND retvalue, full_handle;
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)
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.@)
*/
@ -2305,14 +2513,22 @@ HWND WINAPI GetWindow( HWND hwnd, UINT rel )
{
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_GetPtr( hwnd );
if (!wndPtr)
{
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
if (wndPtr != WND_OTHER_PROCESS)
{
WND *wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return 0;
retval = wndPtr->owner;
WIN_ReleaseWndPtr( wndPtr );
WIN_ReleasePtr( wndPtr );
return retval;
}
/* else fall through to server call */
}
SERVER_START_REQ( get_window_tree )
{
@ -2333,6 +2549,9 @@ HWND WINAPI GetWindow( HWND hwnd, UINT rel )
case GW_HWNDPREV:
retval = req->prev_sibling;
break;
case GW_OWNER:
retval = req->owner;
break;
case GW_CHILD:
retval = req->first_child;
break;

View File

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