Store in the server all the window information accessible with
Get/SetWindowLong.
diff --git a/controls/scroll.c b/controls/scroll.c
index 55b330d..6f83cd3 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -1714,10 +1714,8 @@
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 @@
{
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 @@
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 */
}
diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c
index d375c29..47e4f4e 100644
--- a/dlls/ttydrv/wnd.c
+++ b/dlls/ttydrv/wnd.c
@@ -609,13 +609,9 @@
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 */
diff --git a/dlls/user/message.c b/dlls/user/message.c
index a9608cb..14f458f 100644
--- a/dlls/user/message.c
+++ b/dlls/user/message.c
@@ -1084,16 +1084,21 @@
*/
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;
diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c
index 92dc3f5..006e74c 100644
--- a/dlls/user/user_main.c
+++ b/dlls/user/user_main.c
@@ -87,7 +87,6 @@
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);
diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c
index bf5d0fa..8307062 100644
--- a/dlls/x11drv/window.c
+++ b/dlls/x11drv/window.c
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
if (!ret)
{
WIN_UnlinkWindow( hwnd );
- X11DRV_DestroyWindow( hwnd );
return FALSE;
}
@@ -932,7 +958,7 @@
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 @@
failed:
- X11DRV_DestroyWindow( wndPtr->hwndSelf );
- WIN_ReleaseWndPtr( wndPtr );
+ X11DRV_DestroyWindow( hwnd );
+ if (wndPtr) WIN_ReleasePtr( wndPtr );
return FALSE;
}
@@ -1052,78 +1078,6 @@
}
-/*******************************************************************
- * 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.@)
*
diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c
index 5409293..6301e08 100644
--- a/dlls/x11drv/winpos.c
+++ b/dlls/x11drv/winpos.c
@@ -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 @@
*/
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 @@
DeleteObject( visRgn );
}
- WIN_ReleaseWndPtr( win );
+ WIN_ReleasePtr( win );
return TRUE;
}
@@ -675,10 +676,14 @@
/* 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,25 +728,20 @@
/* 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 = WIN_GetFullHandle( winpos->hwndInsertAfter );
+ if (GetAncestor( winpos->hwndInsertAfter, GA_PARENT ) != wndPtr->parent) ret = FALSE;
+ else
{
- winpos->hwndInsertAfter = wnd->hwndSelf; /* make it a full handle */
- if (wnd->parent != wndPtr->parent) ret = FALSE;
- else
- {
- /* don't need to change the Zorder of hwnd if it's already inserted
- * after hwndInsertAfter or when inserting hwnd after itself.
- */
- if ((winpos->hwnd == winpos->hwndInsertAfter) ||
- (winpos->hwnd == GetWindow( winpos->hwndInsertAfter, GW_HWNDNEXT )))
- winpos->flags |= SWP_NOZORDER;
- }
- WIN_ReleaseWndPtr(wnd);
+ /* don't need to change the Zorder of hwnd if it's already inserted
+ * after hwndInsertAfter or when inserting hwnd after itself.
+ */
+ if ((winpos->hwnd == winpos->hwndInsertAfter) ||
+ (winpos->hwnd == GetWindow( winpos->hwndInsertAfter, GW_HWNDNEXT )))
+ winpos->flags |= SWP_NOZORDER;
}
}
done:
- WIN_ReleaseWndPtr(wndPtr);
+ WIN_ReleasePtr( wndPtr );
return ret;
}
@@ -754,18 +754,51 @@
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 ))
{
- TRACE( "mapping win %x\n", hwnd );
- TSXMapWindow( display, get_whole_window(wndPtr) );
+ 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 @@
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 @@
}
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 @@
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 @@
WND *wndPtr;
UINT swpFlags = 0;
POINT size;
+ LONG old_style;
WINDOWPLACEMENT wpl;
TRACE("0x%04x %u\n", hwnd, cmd );
@@ -1046,14 +1071,10 @@
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 @@
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 @@
{
/* 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 @@
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 @@
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 @@
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 @@
{
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 @@
*
* 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 @@
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 @@
}
#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;
}
diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec
index 2c3efaf..25ee1f9 100644
--- a/dlls/x11drv/x11drv.spec
+++ b/dlls/x11drv/x11drv.spec
@@ -78,7 +78,6 @@
@ 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
diff --git a/include/user.h b/include/user.h
index fb5603d..baf99db 100644
--- a/include/user.h
+++ b/include/user.h
@@ -38,7 +38,9 @@
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 @@
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 @@
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);
diff --git a/include/win.h b/include/win.h
index 81c3df7..6c8d577 100644
--- a/include/win.h
+++ b/include/win.h
@@ -89,6 +89,8 @@
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_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 )
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 25ba881..375667c 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -1601,6 +1601,7 @@
user_handle_t handle;
user_handle_t parent;
user_handle_t previous;
+ user_handle_t full_parent;
};
@@ -1613,6 +1614,16 @@
+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 @@
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 @@
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 @@
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 @@
struct get_window_properties_request get_window_properties;
};
-#define SERVER_PROTOCOL_VERSION 60
+#define SERVER_PROTOCOL_VERSION 61
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index 78955d9..be779ea 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1434,6 +1434,7 @@
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 @@
@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 @@
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 */
diff --git a/server/request.h b/server/request.h
index aae7aea..2d1204f 100644
--- a/server/request.h
+++ b/server/request.h
@@ -191,7 +191,9 @@
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 @@
(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,
diff --git a/server/trace.c b/server/trace.c
index 1d3330e..7c68db2 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1707,11 +1707,27 @@
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 @@
{
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 @@
(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 @@
(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 @@
"create_window",
"link_window",
"destroy_window",
+ "set_window_owner",
"get_window_info",
+ "set_window_info",
"get_window_parents",
"get_window_children",
"get_window_tree",
diff --git a/server/window.c b/server/window.c
index 1559d44..c5333aa 100644
--- a/server/window.c
+++ b/server/window.c
@@ -42,6 +42,11 @@
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 @@
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->next = previous->next)) win->next->prev = win;
@@ -261,6 +270,11 @@
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 @@
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 @@
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 @@
}
+/* 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)
{
@@ -388,13 +427,32 @@
req->full_handle = win->handle;
if (win->thread)
{
- req->tid = get_thread_id( win->thread );
- req->pid = get_process_id( win->thread->process );
+ 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)
{
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 69649cc..af998c9 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -168,9 +168,7 @@
{
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 @@
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 );
}
diff --git a/windows/win.c b/windows/win.c
index dc85efc..0c8deea 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -362,7 +362,6 @@
*/
void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
{
- BOOL ret;
WND *wndPtr = WIN_GetPtr( hwnd );
if (!wndPtr) return;
@@ -377,10 +376,17 @@
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_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,11 +699,10 @@
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)
{
DestroyMenu( wndPtr->hSysMenu );
@@ -682,8 +777,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
}
- 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 @@
{
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 @@
SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
}
- WIN_ReleaseWndPtr(wndPtr);
return retvalue;
}
@@ -1588,22 +1666,32 @@
*/
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 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 @@
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 @@
*/
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)
+ {
+ 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 + sizeof(LONG) > wndPtr->cbWndExtra)
+ if (offset > wndPtr->cbWndExtra - sizeof(LONG))
{
WARN("Invalid offset %d\n", offset );
- retvalue = 0;
- goto end;
+ WIN_ReleasePtr( wndPtr );
+ SetLastError( ERROR_INVALID_INDEX );
+ return 0;
}
- retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
/* Special case for dialog window procedure */
if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
- {
retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type );
- goto end;
+ else
+ retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
+ WIN_ReleasePtr( wndPtr );
+ return retvalue;
}
- 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;
- default:
- WARN("Unknown offset %d\n", 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 @@
*
* 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;
- 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;
+ STYLESTRUCT style;
+ BOOL ok;
+
+ /* first some special cases */
+ switch( offset )
+ {
+ case GWL_STYLE:
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;
-
- default:
+ 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:
+ 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 );
+ SetLastError( ERROR_INVALID_INDEX );
+ return 0;
+ }
- /* Don't think this is right error but it should do */
- SetLastError( ERROR_OUTOFMEMORY );
+ 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 );
- retval = 0;
- goto end;
+ 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 @@
* 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 @@
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 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 @@
}
SERVER_END_VAR_REQ;
+ done:
if (ret && type == GA_ROOTOWNER)
{
for (;;)
@@ -2148,16 +2372,28 @@
/*****************************************************************
- * 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 @@
}
-/*****************************************************************
- * 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,13 +2513,21 @@
{
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 );
- if (!wndPtr) return 0;
- retval = wndPtr->owner;
- WIN_ReleaseWndPtr( wndPtr );
- return retval;
+ WND *wndPtr = WIN_GetPtr( hwnd );
+ if (!wndPtr)
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ 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 )
@@ -2333,6 +2549,9 @@
case GW_HWNDPREV:
retval = req->prev_sibling;
break;
+ case GW_OWNER:
+ retval = req->owner;
+ break;
case GW_CHILD:
retval = req->first_child;
break;
diff --git a/windows/winpos.c b/windows/winpos.c
index 448e448..f288fcb 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -215,15 +215,25 @@
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 @@
{
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 @@
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;
}