From fb0ff053c0dec8878e51dbf2f6c5a2208b61cf61 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 16 Oct 2001 21:58:58 +0000 Subject: [PATCH] Added internal Wine messages to perform SetWindowPos, ShowWindow and SetParent in the correct thread. Replace QUEUE_IsExitingQueue by USER_IsExitingThread. Store window rectangles in the server. Prevent DestroyWindow on windows not belonging to the current thread. --- controls/icontitle.c | 8 +- dlls/ttydrv/wnd.c | 36 ++++- dlls/user/message.c | 57 ++++++- dlls/user/user_main.c | 18 ++- dlls/x11drv/window.c | 21 +-- dlls/x11drv/winpos.c | 204 ++++++++++++----------- include/queue.h | 2 - include/user.h | 11 +- include/win.h | 4 + include/winpos.h | 4 - windows/dce.c | 20 +-- windows/painting.c | 19 ++- windows/queue.c | 20 --- windows/win.c | 358 +++++++++++++++++++++++------------------ windows/winpos.c | 276 +++++++++++++++---------------- windows/x11drv/event.c | 146 ++++++++--------- 16 files changed, 659 insertions(+), 545 deletions(-) diff --git a/controls/icontitle.c b/controls/icontitle.c index c0480928394..f3f62c42761 100644 --- a/controls/icontitle.c +++ b/controls/icontitle.c @@ -43,7 +43,6 @@ const struct builtin_class_descr ICONTITLE_builtin_class = */ HWND ICONTITLE_Create( HWND owner ) { - WND* wndPtr; HWND hWnd; HINSTANCE instance = GetWindowLongA( owner, GWL_HINSTANCE ); LONG style = WS_CLIPSIBLINGS; @@ -57,10 +56,9 @@ HWND ICONTITLE_Create( HWND owner ) hWnd = CreateWindowExA( 0, ICONTITLE_CLASS_ATOM, NULL, style, 0, 0, 1, 1, owner, 0, instance, NULL ); - if (!(wndPtr = WIN_GetPtr( hWnd ))) return 0; - wndPtr->owner = owner; /* MDI depends on this */ - wndPtr->dwStyle &= ~(WS_CAPTION | WS_BORDER); - WIN_ReleasePtr(wndPtr); + WIN_SetOwner( hWnd, owner ); /* MDI depends on this */ + SetWindowLongW( hWnd, GWL_STYLE, + GetWindowLongW( hWnd, GWL_STYLE ) & ~(WS_CAPTION | WS_BORDER) ); return hWnd; } diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c index 7cf4cec4441..d375c291b8c 100644 --- a/dlls/ttydrv/wnd.c +++ b/dlls/ttydrv/wnd.c @@ -566,9 +566,36 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos ) /* Send WM_NCCALCSIZE message to get new client area */ if( (winpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE ) { - WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect, - &wndPtr->rectWindow, &wndPtr->rectClient, - winpos, &newClientRect ); + NCCALCSIZE_PARAMS params; + WINDOWPOS winposCopy; + + params.rgrc[0] = newWindowRect; + params.rgrc[1] = wndPtr->rectWindow; + params.rgrc[2] = wndPtr->rectClient; + params.lppos = &winposCopy; + winposCopy = *winpos; + + SendMessageW( winpos->hwnd, WM_NCCALCSIZE, TRUE, (LPARAM)¶ms ); + + TRACE( "%d,%d-%d,%d\n", params.rgrc[0].left, params.rgrc[0].top, + params.rgrc[0].right, params.rgrc[0].bottom ); + + /* If the application send back garbage, ignore it */ + if (params.rgrc[0].left <= params.rgrc[0].right && + params.rgrc[0].top <= params.rgrc[0].bottom) + newClientRect = params.rgrc[0]; + + /* FIXME: WVR_ALIGNxxx */ + + if( newClientRect.left != wndPtr->rectClient.left || + newClientRect.top != wndPtr->rectClient.top ) + winpos->flags &= ~SWP_NOCLIENTMOVE; + + if( (newClientRect.right - newClientRect.left != + wndPtr->rectClient.right - wndPtr->rectClient.left) || + (newClientRect.bottom - newClientRect.top != + wndPtr->rectClient.bottom - wndPtr->rectClient.top) ) + winpos->flags &= ~SWP_NOCLIENTSIZE; } if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter) @@ -579,8 +606,7 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos ) /* FIXME: actually do something with WVR_VALIDRECTS */ - wndPtr->rectWindow = newWindowRect; - wndPtr->rectClient = newClientRect; + WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect ); if( winpos->flags & SWP_SHOWWINDOW ) { diff --git a/dlls/user/message.c b/dlls/user/message.c index 8c598961ba7..04cd9ab0b19 100644 --- a/dlls/user/message.c +++ b/dlls/user/message.c @@ -533,6 +533,10 @@ static size_t pack_message( HWND hwnd, UINT message, WPARAM wparam, LPARAM lpara if (lparam) return sizeof(BOOL); return 0; + case WM_WINE_SETWINDOWPOS: + push_data( data, (WINDOWPOS *)lparam, sizeof(WINDOWPOS) ); + return 0; + /* these contain an HFONT */ case WM_SETFONT: case WM_GETFONT: @@ -644,6 +648,7 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa break; case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGED: + case WM_WINE_SETWINDOWPOS: minsize = sizeof(WINDOWPOS); break; case WM_COPYDATA: @@ -1072,6 +1077,30 @@ static void reply_message( struct received_message_info *info, LRESULT result, B } +/*********************************************************************** + * handle_internal_message + * + * Handle an internal Wine message instead of calling the window proc. + */ +static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + switch(msg) + { + 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 ); + case WM_WINE_SETPARENT: + return (LRESULT)WIN_SetParent( hwnd, (HWND)wparam ); + default: + FIXME( "unknown internal message %x\n", msg ); + return 0; + } +} + + /*********************************************************************** * call_window_proc * @@ -1082,7 +1111,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar LRESULT result; WNDPROC winproc; - /* FIXME: should check for exiting queue */ + if (msg & 0x80000000) return handle_internal_message( hwnd, msg, wparam, lparam ); /* first the WH_CALLWNDPROC hook */ if (HOOK_IsHooked( WH_CALLWNDPROC )) @@ -1308,8 +1337,6 @@ static BOOL put_message_in_queue( DWORD dest_tid, const struct send_message_info unsigned int res; int timeout = -1; - /* FIXME: should check for exiting queue */ - if (info->type != MSG_NOTIFY && info->type != MSG_CALLBACK && info->type != MSG_POSTED && @@ -1489,7 +1516,9 @@ LRESULT WINAPI SendMessageTimeoutW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l SPY_EnterMessage( SPY_SENDMESSAGE, hwnd, msg, wparam, lparam ); - dest_tid = GetWindowThreadProcessId( hwnd, &dest_pid ); + if (!(dest_tid = GetWindowThreadProcessId( hwnd, &dest_pid ))) return 0; + + if (USER_IsExitingThread( dest_tid )) return 0; if (dest_tid == GetCurrentThreadId()) { @@ -1535,7 +1564,9 @@ LRESULT WINAPI SendMessageTimeoutA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l SPY_EnterMessage( SPY_SENDMESSAGE, hwnd, msg, wparam, lparam ); - dest_tid = GetWindowThreadProcessId( hwnd, &dest_pid ); + if (!(dest_tid = GetWindowThreadProcessId( hwnd, &dest_pid ))) return 0; + + if (USER_IsExitingThread( dest_tid )) return 0; if (dest_tid == GetCurrentThreadId()) { @@ -1624,7 +1655,9 @@ BOOL WINAPI SendNotifyMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara return TRUE; } - dest_tid = GetWindowThreadProcessId( hwnd, NULL ); + if (!(dest_tid = GetWindowThreadProcessId( hwnd, NULL ))) return FALSE; + + if (USER_IsExitingThread( dest_tid )) return TRUE; if (dest_tid == GetCurrentThreadId()) { @@ -1676,7 +1709,9 @@ BOOL WINAPI SendMessageCallbackW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa return TRUE; } - dest_tid = GetWindowThreadProcessId( hwnd, NULL ); + if (!(dest_tid = GetWindowThreadProcessId( hwnd, NULL ))) return FALSE; + + if (USER_IsExitingThread( dest_tid )) return TRUE; if (dest_tid == GetCurrentThreadId()) { @@ -1740,6 +1775,7 @@ BOOL WINAPI PostMessageA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) BOOL WINAPI PostMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { struct send_message_info info; + DWORD dest_tid; if (is_pointer_message( msg )) { @@ -1758,7 +1794,11 @@ BOOL WINAPI PostMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) EnumWindows( broadcast_message_callback, (LPARAM)&info ); return TRUE; } - return put_message_in_queue( GetWindowThreadProcessId( hwnd, NULL ), &info, NULL ); + if (!(dest_tid = GetWindowThreadProcessId( hwnd, NULL ))) return FALSE; + + if (USER_IsExitingThread( dest_tid )) return TRUE; + + return put_message_in_queue( dest_tid, &info, NULL ); } @@ -1783,6 +1823,7 @@ BOOL WINAPI PostThreadMessageW( DWORD thread, UINT msg, WPARAM wparam, LPARAM lp SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } + if (USER_IsExitingThread( thread )) return TRUE; info.type = MSG_POSTED; info.hwnd = 0; diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c index c16bb6cc7df..a4fa0277b30 100644 --- a/dlls/user/user_main.c +++ b/dlls/user/user_main.c @@ -34,8 +34,10 @@ WINE_LOOK TWEAK_WineLook = WIN31_LOOK; WORD USER_HeapSel = 0; /* USER heap selector */ static HMODULE graphics_driver; +static DWORD exiting_thread_id; extern void COMM_Init(void); +extern void WDML_NotifyThreadDetach(void); #define GET_USER_FUNC(name) USER_Driver.p##name = (void*)GetProcAddress( graphics_driver, #name ) @@ -257,20 +259,29 @@ static BOOL process_attach(void) /********************************************************************** - * thread + * USER_IsExitingThread + */ +BOOL USER_IsExitingThread( DWORD tid ) +{ + return (tid == exiting_thread_id); +} + + +/********************************************************************** + * thread_detach */ static void thread_detach(void) { HQUEUE16 hQueue = GetThreadQueue16( 0 ); - extern void WDML_NotifyThreadDetach(void); + exiting_thread_id = GetCurrentThreadId(); + WDML_NotifyThreadDetach(); if (hQueue) { TIMER_RemoveQueueTimers( hQueue ); HOOK_FreeQueueHooks(); - QUEUE_SetExitingQueue( hQueue ); WIN_DestroyThreadWindows( GetDesktopWindow() ); QUEUE_DeleteMsgQueue(); } @@ -290,6 +301,7 @@ static void thread_detach(void) CURSORICON_FreeModuleIcons( hModule ); } } + exiting_thread_id = 0; } diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c index b9023c734c7..380912e0bf1 100644 --- a/dlls/x11drv/window.c +++ b/dlls/x11drv/window.c @@ -872,7 +872,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode ) rect = wndPtr->rectWindow; SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect ); if (rect.left > rect.right || rect.top > rect.bottom) rect = wndPtr->rectWindow; - wndPtr->rectClient = rect; + WIN_SetRectangles( hwnd, &wndPtr->rectWindow, &rect ); X11DRV_sync_client_window_position( display, wndPtr ); X11DRV_register_window( display, hwnd, data ); @@ -1005,18 +1005,14 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent ) { Display *display = thread_display(); WND *wndPtr; - DWORD dwStyle; HWND retvalue; - if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0; - - dwStyle = wndPtr->dwStyle; - - if (!parent) parent = GetDesktopWindow(); - /* Windows hides the window first, then shows it again * including the WM_SHOWWINDOW messages and all */ - if (dwStyle & WS_VISIBLE) ShowWindow( hwnd, SW_HIDE ); + BOOL was_visible = ShowWindow( hwnd, SW_HIDE ); + + if (!IsWindow( parent )) return 0; + if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return 0; retvalue = wndPtr->parent; /* old parent */ if (parent != retvalue) @@ -1027,7 +1023,7 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent ) if (parent != GetDesktopWindow()) /* a child window */ { - if (!(dwStyle & WS_CHILD)) + if (!(wndPtr->dwStyle & WS_CHILD)) { HMENU menu = (HMENU)SetWindowLongW( hwnd, GWL_ID, 0 ); if (menu) DestroyMenu( menu ); @@ -1041,15 +1037,14 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent ) data->whole_rect.left, data->whole_rect.top ); wine_tsx11_unlock(); } - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); /* SetParent additionally needs to make hwnd the topmost window in the x-order and send the expected WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED notification messages. */ SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE| - ((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0)); + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) ); /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */ diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c index ba7e4fa67bf..5409293fd7a 100644 --- a/dlls/x11drv/winpos.c +++ b/dlls/x11drv/winpos.c @@ -523,7 +523,7 @@ static BOOL SWP_DoWinPosChanging( WINDOWPOS* pWinpos, RECT* pNewWindowRect, RECT if (!(pWinpos->flags & SWP_NOSENDCHANGING)) SendMessageA( pWinpos->hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)pWinpos ); - if (!(wndPtr = WIN_FindWndPtr( pWinpos->hwnd ))) return FALSE; + if (!(wndPtr = WIN_GetPtr( pWinpos->hwnd )) || wndPtr == WND_OTHER_PROCESS) return FALSE; /* Calculate new position and size */ @@ -547,43 +547,69 @@ static BOOL SWP_DoWinPosChanging( WINDOWPOS* pWinpos, RECT* pNewWindowRect, RECT pWinpos->y - wndPtr->rectWindow.top ); } pWinpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE; - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); return TRUE; } /*********************************************************************** * SWP_DoNCCalcSize */ -static UINT SWP_DoNCCalcSize( WND* wndPtr, WINDOWPOS* pWinpos, - RECT* pNewWindowRect, RECT* pNewClientRect ) +static UINT SWP_DoNCCalcSize( WINDOWPOS* pWinpos, RECT* pNewWindowRect, RECT* pNewClientRect ) { UINT wvrFlags = 0; + WND *wndPtr; + + if (!(wndPtr = WIN_GetPtr( pWinpos->hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0; /* Send WM_NCCALCSIZE message to get new client area */ if( (pWinpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE ) { - wvrFlags = WINPOS_SendNCCalcSize( pWinpos->hwnd, TRUE, pNewWindowRect, - &wndPtr->rectWindow, &wndPtr->rectClient, - pWinpos, pNewClientRect ); + NCCALCSIZE_PARAMS params; + WINDOWPOS winposCopy; + + params.rgrc[0] = *pNewWindowRect; + params.rgrc[1] = wndPtr->rectWindow; + params.rgrc[2] = wndPtr->rectClient; + params.lppos = &winposCopy; + winposCopy = *pWinpos; + WIN_ReleasePtr( wndPtr ); + + wvrFlags = SendMessageW( pWinpos->hwnd, WM_NCCALCSIZE, TRUE, (LPARAM)¶ms ); + + TRACE( "%d,%d-%d,%d\n", params.rgrc[0].left, params.rgrc[0].top, + params.rgrc[0].right, params.rgrc[0].bottom ); + + /* If the application send back garbage, ignore it */ + if (params.rgrc[0].left <= params.rgrc[0].right && + params.rgrc[0].top <= params.rgrc[0].bottom) + *pNewClientRect = params.rgrc[0]; + /* FIXME: WVR_ALIGNxxx */ - if( pNewClientRect->left != wndPtr->rectClient.left || - pNewClientRect->top != wndPtr->rectClient.top ) - pWinpos->flags &= ~SWP_NOCLIENTMOVE; + if (!(wndPtr = WIN_GetPtr( pWinpos->hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0; - if( (pNewClientRect->right - pNewClientRect->left != - wndPtr->rectClient.right - wndPtr->rectClient.left) || - (pNewClientRect->bottom - pNewClientRect->top != - wndPtr->rectClient.bottom - wndPtr->rectClient.top) ) - pWinpos->flags &= ~SWP_NOCLIENTSIZE; + if( pNewClientRect->left != wndPtr->rectClient.left || + pNewClientRect->top != wndPtr->rectClient.top ) + pWinpos->flags &= ~SWP_NOCLIENTMOVE; + + if( (pNewClientRect->right - pNewClientRect->left != + wndPtr->rectClient.right - wndPtr->rectClient.left) || + (pNewClientRect->bottom - pNewClientRect->top != + wndPtr->rectClient.bottom - wndPtr->rectClient.top) ) + pWinpos->flags &= ~SWP_NOCLIENTSIZE; } else - if( !(pWinpos->flags & SWP_NOMOVE) && (pNewClientRect->left != wndPtr->rectClient.left || - pNewClientRect->top != wndPtr->rectClient.top) ) + { + if (!(pWinpos->flags & SWP_NOMOVE) && + (pNewClientRect->left != wndPtr->rectClient.left || + pNewClientRect->top != wndPtr->rectClient.top)) pWinpos->flags &= ~SWP_NOCLIENTMOVE; + } + WIN_ReleasePtr( wndPtr ); return wvrFlags; } + /*********************************************************************** * SWP_DoOwnedPopups * @@ -783,7 +809,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos ) /* Common operations */ - wvrFlags = SWP_DoNCCalcSize( wndPtr, winpos, &newWindowRect, &newClientRect ); + wvrFlags = SWP_DoNCCalcSize( winpos, &newWindowRect, &newClientRect ); if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter) { @@ -816,8 +842,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos ) /* FIXME: actually do something with WVR_VALIDRECTS */ - wndPtr->rectWindow = newWindowRect; - wndPtr->rectClient = newClientRect; + WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect ); if (winpos->flags & SWP_SHOWWINDOW) wndPtr->dwStyle |= WS_VISIBLE; else if (winpos->flags & SWP_HIDEWINDOW) @@ -993,7 +1018,7 @@ static POINT WINPOS_FindIconPos( WND* wndPtr, POINT pt ) UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) { - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr; UINT swpFlags = 0; POINT size; WINDOWPLACEMENT wpl; @@ -1003,90 +1028,87 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) wpl.length = sizeof(wpl); GetWindowPlacement( hwnd, &wpl ); + if (HOOK_CallHooksA( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd )) + return SWP_NOSIZE | SWP_NOMOVE; + + if (IsIconic( hwnd )) + { + if (cmd == SW_MINIMIZE) return SWP_NOSIZE | SWP_NOMOVE; + if (!SendMessageA( hwnd, WM_QUERYOPEN, 0, 0 )) return SWP_NOSIZE | SWP_NOMOVE; + swpFlags |= SWP_NOCOPYBITS; + } + + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; + size.x = wndPtr->rectWindow.left; size.y = wndPtr->rectWindow.top; - if (!HOOK_CallHooksA(WH_CBT, HCBT_MINMAX, (WPARAM)wndPtr->hwndSelf, cmd)) + 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; + + X11DRV_set_iconic_state( wndPtr ); + + wpl.ptMinPosition = WINPOS_FindIconPos( wndPtr, wpl.ptMinPosition ); + + SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y, + GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) ); + swpFlags |= SWP_NOCOPYBITS; + break; + + case SW_MAXIMIZE: + WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL ); + if( wndPtr->dwStyle & WS_MINIMIZE ) { - if( !SendMessageA( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) ) - { - swpFlags = SWP_NOSIZE | SWP_NOMOVE; - goto done; - } - swpFlags |= SWP_NOCOPYBITS; + wndPtr->dwStyle &= ~WS_MINIMIZE; + WINPOS_ShowIconTitle( hwnd, FALSE ); + X11DRV_set_iconic_state( wndPtr ); } - 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; + 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 ) + { + wndPtr->dwStyle &= ~WS_MINIMIZE; + WINPOS_ShowIconTitle( hwnd, FALSE ); X11DRV_set_iconic_state( wndPtr ); - wpl.ptMinPosition = WINPOS_FindIconPos( wndPtr, wpl.ptMinPosition ); - - SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y, - GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) ); - swpFlags |= SWP_NOCOPYBITS; - break; - - case SW_MAXIMIZE: - WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL ); - - if( wndPtr->dwStyle & WS_MINIMIZE ) + if( wndPtr->flags & WIN_RESTORE_MAX) { - wndPtr->dwStyle &= ~WS_MINIMIZE; - WINPOS_ShowIconTitle( hwnd, FALSE ); - X11DRV_set_iconic_state( wndPtr ); + /* Restore to maximized position */ + WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL); + wndPtr->dwStyle |= WS_MAXIMIZE; + SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y ); + break; } - 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 ) - { - wndPtr->dwStyle &= ~WS_MINIMIZE; - WINPOS_ShowIconTitle( hwnd, FALSE ); - X11DRV_set_iconic_state( wndPtr ); - - if( wndPtr->flags & WIN_RESTORE_MAX) - { - /* Restore to maximized position */ - WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL); - wndPtr->dwStyle |= WS_MAXIMIZE; - SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y ); - break; - } - } - else - if( !(wndPtr->dwStyle & WS_MAXIMIZE) ) - { - swpFlags = (UINT16)(-1); - goto done; - } - else wndPtr->dwStyle &= ~WS_MAXIMIZE; - - /* Restore to normal position */ - - *rect = wpl.rcNormalPosition; - rect->right -= rect->left; - rect->bottom -= rect->top; - - break; } - } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE; + else + { + if (!(wndPtr->dwStyle & WS_MAXIMIZE)) break; + wndPtr->dwStyle &= ~WS_MAXIMIZE; + } + + /* Restore to normal position */ + + *rect = wpl.rcNormalPosition; + rect->right -= rect->left; + rect->bottom -= rect->top; + + break; + } - done: WIN_ReleaseWndPtr( wndPtr ); return swpFlags; } diff --git a/include/queue.h b/include/queue.h index baf84ffc547..394e34f668b 100644 --- a/include/queue.h +++ b/include/queue.h @@ -69,8 +69,6 @@ HWND PERQDATA_SetCaptureWnd( HWND hWndCapture, INT hittest ); extern MESSAGEQUEUE *QUEUE_Current(void); extern MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue ); extern void QUEUE_Unlock( MESSAGEQUEUE *queue ); -extern BOOL QUEUE_IsExitingQueue( HQUEUE16 hQueue ); -extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue ); extern void QUEUE_DeleteMsgQueue(void); #endif /* __WINE_QUEUE_H */ diff --git a/include/user.h b/include/user.h index 6b9dd355ed0..b1aab0877d3 100644 --- a/include/user.h +++ b/include/user.h @@ -35,7 +35,14 @@ struct DIDEVICEOBJECTDATA; typedef VOID CALLBACK (*LPMOUSE_EVENT_PROC)(DWORD,DWORD,DWORD,DWORD,DWORD); -struct tagWND; +/* internal messages codes */ +enum wine_internal_message +{ + WM_WINE_DESTROYWINDOW = 0x80000000, + WM_WINE_SETWINDOWPOS, + WM_WINE_SHOWWINDOW, + WM_WINE_SETPARENT +}; typedef struct tagUSER_DRIVER { /* keyboard functions */ @@ -99,6 +106,8 @@ extern void USER_Lock(void); extern void USER_Unlock(void); extern void USER_CheckNotLock(void); +extern BOOL USER_IsExitingThread( DWORD tid ); + VOID WINAPI MOUSE_Enable(LPMOUSE_EVENT_PROC lpMouseEventProc); VOID WINAPI MOUSE_Disable(VOID); diff --git a/include/win.h b/include/win.h index dcd7ed0074b..81c3df741da 100644 --- a/include/win.h +++ b/include/win.h @@ -88,12 +88,16 @@ extern HWND WIN_IsCurrentProcess( HWND hwnd ); 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 void WIN_SetRectangles( HWND hwnd, const RECT *rectWindow, const RECT *rectClient ); extern HWND WIN_FindWinToRepaint( HWND hwnd ); +extern LRESULT WIN_DestroyWindow( HWND hwnd ); extern void WIN_DestroyThreadWindows( HWND hwnd ); 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 ) diff --git a/include/winpos.h b/include/winpos.h index 25f8948aacb..0ca4a318d93 100644 --- a/include/winpos.h +++ b/include/winpos.h @@ -28,10 +28,6 @@ extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, POIN extern BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus ); extern BOOL WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); -extern LONG WINPOS_SendNCCalcSize(HWND hwnd, BOOL calcValidRect, - RECT *newWindowRect, RECT *oldWindowRect, - RECT *oldClientRect, WINDOWPOS *winpos, - RECT *newClientRect ); extern LONG WINPOS_HandleWindowPosChanging16(HWND hwnd, struct tagWINDOWPOS16 *winpos); extern LONG WINPOS_HandleWindowPosChanging(HWND hwnd, WINDOWPOS *winpos); extern HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ); diff --git a/windows/dce.c b/windows/dce.c index c8e1688624c..b6f6e669c48 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -144,11 +144,9 @@ DCE* DCE_FreeDCE( DCE *dce ) void DCE_FreeWindowDCE( HWND hwnd ) { DCE *pDCE; - WND *pWnd = WIN_FindWndPtr( hwnd ); + WND *pWnd = WIN_GetPtr( hwnd ); pDCE = firstDCE; - hwnd = pWnd->hwndSelf; /* make it a full handle */ - while( pDCE ) { if( pDCE->hwndCurrent == hwnd ) @@ -189,8 +187,7 @@ void DCE_FreeWindowDCE( HWND hwnd ) } pDCE = pDCE->next; } - - WIN_ReleaseWndPtr( pWnd ); + WIN_ReleasePtr( pWnd ); } @@ -359,14 +356,19 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) DWORD dcxFlags = 0; BOOL bUpdateVisRgn = TRUE; BOOL bUpdateClipOrigin = FALSE; - HWND parent; + HWND parent, full; TRACE("hwnd %04x, hrgnClip %04x, flags %08x\n", hwnd, hrgnClip, (unsigned)flags); if (!hwnd) hwnd = GetDesktopWindow(); - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; - hwnd = wndPtr->hwndSelf; /* make it a full handle */ + if (!(full = WIN_IsCurrentProcess( hwnd )) && full != GetDesktopWindow()) + { + FIXME( "not supported yet on other process window %x\n", full ); + return 0; + } + hwnd = full; + if (!(wndPtr = WIN_GetPtr( hwnd ))) return 0; /* fixup flags */ @@ -494,7 +496,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) TRACE("(%04x,%04x,0x%lx): returning %04x\n", hwnd, hrgnClip, flags, hdc); END: - WIN_ReleaseWndPtr(wndPtr); + WIN_ReleasePtr(wndPtr); return hdc; } diff --git a/windows/painting.c b/windows/painting.c index 6c854fec00c..450d8aff7d0 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -306,11 +306,20 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps ) BOOL bIcon; HRGN hrgnUpdate; RECT clipRect, clientRect; - WND *wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr) return 0; + HWND full_handle; + WND *wndPtr; - bIcon = (wndPtr->dwStyle & WS_MINIMIZE && GetClassLongA(hwnd, GCL_HICON)); + if (!(full_handle = WIN_IsCurrentThread( hwnd ))) + { + if (IsWindow(hwnd)) + FIXME( "window %x belongs to other thread\n", hwnd ); + return 0; + } + hwnd = full_handle; + bIcon = (IsIconic(hwnd) && GetClassLongA(hwnd, GCL_HICON)); + + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; /* send WM_NCPAINT and make sure hrgnUpdate is a valid rgn handle */ @@ -320,7 +329,7 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps ) * Make sure the window is still a window. All window locks are suspended * when the WM_NCPAINT is sent. */ - if (!IsWindow(wndPtr->hwndSelf)) + if (!IsWindow( hwnd )) { WIN_ReleaseWndPtr(wndPtr); return 0; @@ -336,7 +345,7 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps ) TRACE("hrgnUpdate = %04x, \n", hrgnUpdate); - if (GetClassLongA(wndPtr->hwndSelf, GCL_STYLE) & CS_PARENTDC) + if (GetClassLongA( hwnd, GCL_STYLE ) & CS_PARENTDC) { /* Don't clip the output to the update region for CS_PARENTDC window */ if( hrgnUpdate ) diff --git a/windows/queue.c b/windows/queue.c index 0e788c2cc5f..1829d6cf055 100644 --- a/windows/queue.c +++ b/windows/queue.c @@ -24,7 +24,6 @@ DEFAULT_DEBUG_CHANNEL(msg); -static HQUEUE16 hExitingQueue = 0; static PERQUEUEDATA *pQDataWin16 = NULL; /* Global perQData for Win16 tasks */ HQUEUE16 hActiveQueue = 0; @@ -324,24 +323,6 @@ void QUEUE_Unlock( MESSAGEQUEUE *queue ) } -/*********************************************************************** - * QUEUE_IsExitingQueue - */ -BOOL QUEUE_IsExitingQueue( HQUEUE16 hQueue ) -{ - return (hExitingQueue && (hQueue == hExitingQueue)); -} - - -/*********************************************************************** - * QUEUE_SetExitingQueue - */ -void QUEUE_SetExitingQueue( HQUEUE16 hQueue ) -{ - hExitingQueue = hQueue; -} - - /*********************************************************************** * QUEUE_CreateMsgQueue * @@ -417,7 +398,6 @@ void QUEUE_DeleteMsgQueue(void) msgQueue->magic = 0; if( hActiveQueue == hQueue ) hActiveQueue = 0; - if (hExitingQueue == hQueue) hExitingQueue = 0; HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */ diff --git a/windows/win.c b/windows/win.c index 106a60c4e5d..970bf0e0fe0 100644 --- a/windows/win.c +++ b/windows/win.c @@ -175,6 +175,18 @@ static HWND *list_window_children( HWND hwnd, ATOM atom, DWORD tid ) } +/******************************************************************* + * send_parent_notify + */ +static void send_parent_notify( HWND hwnd, UINT msg ) +{ + if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)) return; + if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_NOPARENTNOTIFY) return; + SendMessageW( GetParent(hwnd), WM_PARENTNOTIFY, + MAKEWPARAM( msg, GetWindowLongW( hwnd, GWL_ID )), (LPARAM)hwnd ); +} + + /*********************************************************************** * WIN_GetPtr * @@ -351,6 +363,14 @@ void WIN_UnlinkWindow( HWND hwnd ) void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ) { BOOL ret; + WND *wndPtr = WIN_GetPtr( hwnd ); + + if (!wndPtr) return; + if (wndPtr == WND_OTHER_PROCESS) + { + if (IsWindow(hwnd)) ERR(" cannot link other process window %x\n", hwnd ); + return; + } SERVER_START_REQ( link_window ) { @@ -360,18 +380,70 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ) ret = !SERVER_CALL_ERR(); } SERVER_END_REQ; - if (ret && parent) + if (ret && parent) wndPtr->parent = WIN_GetFullHandle(parent); + WIN_ReleasePtr( wndPtr ); +} + + +/*********************************************************************** + * WIN_SetOwner + * + * Change the owner of a window. + */ +void WIN_SetOwner( HWND hwnd, HWND owner ) +{ + WND *win = WIN_FindWndPtr( hwnd ); + if (win) { - WND *wndPtr = WIN_FindWndPtr( hwnd ); - if (wndPtr) - { - wndPtr->parent = WIN_GetFullHandle(parent); - WIN_ReleaseWndPtr( wndPtr ); - } + win->owner = owner; + WIN_ReleaseWndPtr( win ); } } +/*********************************************************************** + * WIN_SetRectangles + * + * Set the window and client rectangles. + */ +void WIN_SetRectangles( HWND hwnd, const RECT *rectWindow, const RECT *rectClient ) +{ + WND *win = WIN_GetPtr( hwnd ); + BOOL ret; + + if (!win) return; + if (win == WND_OTHER_PROCESS) + { + if (IsWindow( hwnd )) ERR( "cannot set rectangles of other process window %x\n", hwnd ); + return; + } + SERVER_START_REQ( set_window_rectangles ) + { + req->handle = hwnd; + req->window.left = rectWindow->left; + req->window.top = rectWindow->top; + req->window.right = rectWindow->right; + req->window.bottom = rectWindow->bottom; + req->client.left = rectClient->left; + req->client.top = rectClient->top; + req->client.right = rectClient->right; + req->client.bottom = rectClient->bottom; + ret = !SERVER_CALL(); + } + SERVER_END_REQ; + if (ret) + { + win->rectWindow = *rectWindow; + win->rectClient = *rectClient; + + TRACE( "win %x window (%d,%d)-(%d,%d) client (%d,%d)-(%d,%d)\n", hwnd, + rectWindow->left, rectWindow->top, rectWindow->right, rectWindow->bottom, + rectClient->left, rectClient->top, rectClient->right, rectClient->bottom ); + } + WIN_ReleasePtr( win ); +} + + /*********************************************************************** * find_child_to_repaint * @@ -481,18 +553,28 @@ HWND WIN_FindWinToRepaint( HWND hwnd ) * * Destroy storage associated to a window. "Internals" p.358 */ -static void WIN_DestroyWindow( HWND hwnd ) +LRESULT WIN_DestroyWindow( HWND hwnd ) { WND *wndPtr; HWND *list; TRACE("%04x\n", hwnd ); + if (!(hwnd = WIN_IsCurrentThread( hwnd ))) + { + ERR( "window doesn't belong to current thread\n" ); + return 0; + } + /* free child windows */ if ((list = WIN_ListChildren( hwnd ))) { int i; - for (i = 0; list[i]; i++) WIN_DestroyWindow( list[i] ); + for (i = 0; list[i]; i++) + { + if (WIN_IsCurrentThread( list[i] )) WIN_DestroyWindow( list[i] ); + else SendMessageW( list[i], WM_WINE_DESTROYWINDOW, 0, 0 ); + } HeapFree( GetProcessHeap(), 0, list ); } @@ -517,7 +599,7 @@ static void WIN_DestroyWindow( HWND hwnd ) TIMER_RemoveWindowTimers( hwnd ); - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return; + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; wndPtr->hmemTaskQ = 0; if (!(wndPtr->dwStyle & WS_CHILD)) @@ -538,6 +620,7 @@ static void WIN_DestroyWindow( HWND hwnd ) wndPtr->class = NULL; wndPtr->dwMagic = 0; /* Mark it as invalid */ WIN_ReleaseWndPtr( wndPtr ); + return 0; } /*********************************************************************** @@ -576,10 +659,10 @@ BOOL WIN_CreateDesktopWindow(void) WNDPROC winproc; DCE *dce; CREATESTRUCTA cs; + RECT rect; TRACE("Creating desktop window\n"); - if (!WINPOS_CreateInternalPosAtom() || !(class = CLASS_AddWindow( (ATOM)LOWORD(DESKTOP_CLASS_ATOM), 0, WIN_PROC_32W, &wndExtra, &winproc, &clsStyle, &dce ))) @@ -595,11 +678,6 @@ BOOL WIN_CreateDesktopWindow(void) pWndDesktop->owner = 0; pWndDesktop->class = class; pWndDesktop->hInstance = 0; - pWndDesktop->rectWindow.left = 0; - pWndDesktop->rectWindow.top = 0; - pWndDesktop->rectWindow.right = GetSystemMetrics(SM_CXSCREEN); - pWndDesktop->rectWindow.bottom = GetSystemMetrics(SM_CYSCREEN); - pWndDesktop->rectClient = pWndDesktop->rectWindow; pWndDesktop->text = NULL; pWndDesktop->hmemTaskQ = 0; pWndDesktop->hrgnUpdate = 0; @@ -625,13 +703,16 @@ BOOL WIN_CreateDesktopWindow(void) cs.hwndParent = 0; cs.x = 0; cs.y = 0; - cs.cx = pWndDesktop->rectWindow.right; - cs.cy = pWndDesktop->rectWindow.bottom; + cs.cx = GetSystemMetrics( SM_CXSCREEN ); + cs.cy = GetSystemMetrics( SM_CYSCREEN ); cs.style = pWndDesktop->dwStyle; cs.dwExStyle = pWndDesktop->dwExStyle; cs.lpszName = NULL; cs.lpszClass = DESKTOP_CLASS_ATOM; + SetRect( &rect, 0, 0, cs.cx, cs.cy ); + WIN_SetRectangles( hwndDesktop, &rect, &rect ); + if (!USER_Driver.pCreateWindow( hwndDesktop, &cs, FALSE )) return FALSE; pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND; @@ -721,6 +802,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, INT wndExtra; DWORD clsStyle; WNDPROC winproc; + RECT rect; DCE *dce; BOOL unicode = (type == WIN_PROC_32W); @@ -867,11 +949,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, /* Initialize the dimensions before sending WM_GETMINMAXINFO */ - wndPtr->rectWindow.left = cs->x; - wndPtr->rectWindow.top = cs->y; - wndPtr->rectWindow.right = cs->x + cs->cx; - wndPtr->rectWindow.bottom = cs->y + cs->cy; - wndPtr->rectClient = wndPtr->rectWindow; + 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 */ @@ -887,11 +966,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, if (cs->cx < 0) cs->cx = 0; if (cs->cy < 0) cs->cy = 0; - wndPtr->rectWindow.left = cs->x; - wndPtr->rectWindow.top = cs->y; - wndPtr->rectWindow.right = cs->x + cs->cx; - wndPtr->rectWindow.bottom = cs->y + cs->cy; - wndPtr->rectClient = wndPtr->rectWindow; + SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy ); + WIN_SetRectangles( hwnd, &rect, &rect ); /* Set the window menu */ @@ -923,17 +999,13 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, return 0; } - if( (wndPtr->dwStyle & WS_CHILD) && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) ) - { - /* Notify the parent window only */ + /* Notify the parent window only */ - SendMessageA( wndPtr->parent, WM_PARENTNOTIFY, - MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd ); - if( !IsWindow(hwnd) ) - { - hwnd = 0; - goto end; - } + send_parent_notify( hwnd, WM_CREATE ); + if( !IsWindow(hwnd) ) + { + hwnd = 0; + goto end; } if (cs->style & WS_VISIBLE) @@ -1188,17 +1260,17 @@ static void WIN_SendDestroyMsg( HWND hwnd ) */ BOOL WINAPI DestroyWindow( HWND hwnd ) { - WND * wndPtr; - BOOL retvalue; + BOOL is_child; HWND h; - hwnd = WIN_GetFullHandle( hwnd ); + if (!(hwnd = WIN_IsCurrentThread( hwnd )) || (hwnd == GetDesktopWindow())) + { + SetLastError( ERROR_ACCESS_DENIED ); + return FALSE; + } + TRACE("(%04x)\n", hwnd); - /* Initialization */ - - if (hwnd == GetDesktopWindow()) return FALSE; /* Can't destroy desktop */ - /* Look whether the focus is within the tree of windows we will * be destroying. */ @@ -1214,25 +1286,20 @@ BOOL WINAPI DestroyWindow( HWND hwnd ) if( HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0L) ) return FALSE; - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; - if (!(wndPtr->dwStyle & WS_CHILD) && !GetWindow( hwnd, GW_OWNER )) + is_child = (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) != 0; + + if (is_child) + { + if (!USER_IsExitingThread( GetCurrentThreadId() )) + send_parent_notify( hwnd, WM_DESTROY ); + } + else if (!GetWindow( hwnd, GW_OWNER )) { HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L ); /* FIXME: clean up palette - see "Internals" p.352 */ } - if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) ) - if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) ) - { - /* Notify the parent window only */ - SendMessageA( wndPtr->parent, WM_PARENTNOTIFY, - MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd ); - if( !IsWindow(hwnd) ) - { - retvalue = TRUE; - goto end; - } - } + if (!IsWindow(hwnd)) return TRUE; if (USER_Driver.pResetSelectionOwner) USER_Driver.pResetSelectionOwner( hwnd, FALSE ); /* before the window is unmapped */ @@ -1240,77 +1307,62 @@ BOOL WINAPI DestroyWindow( HWND hwnd ) /* Hide the window */ ShowWindow( hwnd, SW_HIDE ); - if (!IsWindow(hwnd)) - { - retvalue = TRUE; - goto end; - } + if (!IsWindow(hwnd)) return TRUE; /* Recursively destroy owned windows */ - if( !(wndPtr->dwStyle & WS_CHILD) ) + if (!is_child) { HWND owner; - for (;;) - { - int i, got_one = 0; - HWND *list = WIN_ListChildren( wndPtr->parent ); - if (list) - { - for (i = 0; list[i]; i++) - { - WND *siblingPtr; - if (GetWindow( list[i], GW_OWNER ) != hwnd) continue; - if (!(siblingPtr = WIN_FindWndPtr( list[i] ))) continue; - if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ) - { - WIN_ReleaseWndPtr( siblingPtr ); - DestroyWindow( list[i] ); - got_one = 1; - continue; - } - else siblingPtr->owner = 0; - WIN_ReleaseWndPtr( siblingPtr ); - } - HeapFree( GetProcessHeap(), 0, list ); - } - if (!got_one) break; - } + for (;;) + { + int i, got_one = 0; + HWND *list = WIN_ListChildren( GetDesktopWindow() ); + if (list) + { + for (i = 0; list[i]; i++) + { + if (GetWindow( list[i], GW_OWNER ) != hwnd) continue; + if (WIN_IsCurrentThread( list[i] )) + { + DestroyWindow( list[i] ); + got_one = 1; + continue; + } + WIN_SetOwner( list[i], 0 ); + } + HeapFree( GetProcessHeap(), 0, list ); + } + if (!got_one) break; + } - WINPOS_ActivateOtherWindow( hwnd ); + WINPOS_ActivateOtherWindow( hwnd ); - if ((owner = GetWindow( hwnd, GW_OWNER ))) - { - WND *ptr = WIN_FindWndPtr( owner ); - if (ptr) - { - if (ptr->hwndLastActive == hwnd) ptr->hwndLastActive = owner; - WIN_ReleaseWndPtr( ptr ); - } - } + if ((owner = GetWindow( hwnd, GW_OWNER ))) + { + WND *ptr = WIN_FindWndPtr( owner ); + if (ptr) + { + if (ptr->hwndLastActive == hwnd) ptr->hwndLastActive = owner; + WIN_ReleaseWndPtr( ptr ); + } + } } /* Send destroy messages */ WIN_SendDestroyMsg( hwnd ); - if (!IsWindow(hwnd)) - { - retvalue = TRUE; - goto end; - } + if (!IsWindow( hwnd )) return TRUE; /* Unlink now so we won't bother with the children later on */ - if( wndPtr->parent ) WIN_UnlinkWindow(hwnd); + WIN_UnlinkWindow( hwnd ); /* Destroy the window storage */ WIN_DestroyWindow( hwnd ); - retvalue = TRUE; -end: - WIN_ReleaseWndPtr(wndPtr); - return retvalue; + return TRUE; } @@ -1319,20 +1371,9 @@ end: */ BOOL WINAPI CloseWindow( HWND hwnd ) { - WND * wndPtr = WIN_FindWndPtr( hwnd ); - BOOL retvalue; - - if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) - { - retvalue = FALSE; - goto end; - } + if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) return FALSE; ShowWindow( hwnd, SW_MINIMIZE ); - retvalue = TRUE; -end: - WIN_ReleaseWndPtr(wndPtr); - return retvalue; - + return TRUE; } @@ -1523,14 +1564,7 @@ BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable ) */ BOOL WINAPI IsWindowEnabled(HWND hWnd) { - WND * wndPtr; - BOOL retvalue; - - if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE; - retvalue = !(wndPtr->dwStyle & WS_DISABLED); - WIN_ReleaseWndPtr(wndPtr); - return retvalue; - + return !(GetWindowLongW( hWnd, GWL_STYLE ) & WS_DISABLED); } @@ -2114,34 +2148,25 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type ) /***************************************************************** - * SetParent (USER32.@) + * WIN_SetParent + * + * Implementation of SetParent, runs in the thread owning the window. */ -HWND WINAPI SetParent( HWND hwnd, HWND parent ) +HWND WIN_SetParent( HWND hwnd, HWND parent ) { WND *wndPtr; - DWORD dwStyle; HWND retvalue; - - if (!parent) parent = GetDesktopWindow(); - else parent = WIN_GetFullHandle( parent ); - - /* sanity checks */ - if (WIN_GetFullHandle(hwnd) == GetDesktopWindow() || !IsWindow( parent )) - { - SetLastError( ERROR_INVALID_WINDOW_HANDLE ); - return 0; - } + BOOL was_visible; if (USER_Driver.pSetParent) return USER_Driver.pSetParent( hwnd, parent ); - if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0; - - dwStyle = wndPtr->dwStyle; - /* Windows hides the window first, then shows it again * including the WM_SHOWWINDOW messages and all */ - if (dwStyle & WS_VISIBLE) ShowWindow( hwnd, SW_HIDE ); + was_visible = ShowWindow( hwnd, SW_HIDE ); + + if (!IsWindow( parent )) return 0; + if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return 0; retvalue = wndPtr->parent; /* old parent */ if (parent != retvalue) @@ -2150,28 +2175,55 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent ) if (parent != GetDesktopWindow()) /* a child window */ { - if (!(dwStyle & WS_CHILD)) + if (!(wndPtr->dwStyle & WS_CHILD)) { HMENU menu = (HMENU)SetWindowLongW( hwnd, GWL_ID, 0 ); if (menu) DestroyMenu( menu ); } } } - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); /* SetParent additionally needs to make hwnd the topmost window in the x-order and send the expected WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED notification messages. */ SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE| - ((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0)); + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) ); /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */ return retvalue; } +/***************************************************************** + * 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.@) */ diff --git a/windows/winpos.c b/windows/winpos.c index 19697809dd0..64e11fed8ec 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -11,6 +11,7 @@ #include "wingdi.h" #include "winerror.h" #include "wine/winuser16.h" +#include "wine/server.h" #include "controls.h" #include "user.h" #include "region.h" @@ -83,7 +84,9 @@ void WINPOS_CheckInternalPos( HWND hwnd ) { LPINTERNALPOS lpPos; MESSAGEQUEUE *pMsgQ = 0; - WND *wndPtr = WIN_FindWndPtr( hwnd ); + WND *wndPtr = WIN_GetPtr( hwnd ); + + if (!wndPtr || wndPtr == WND_OTHER_PROCESS) return; lpPos = (LPINTERNALPOS) GetPropA( hwnd, atomInternalPos ); @@ -92,7 +95,7 @@ void WINPOS_CheckInternalPos( HWND hwnd ) if ( !pMsgQ ) { WARN("\tMessage queue not found. Exiting!\n" ); - WIN_ReleaseWndPtr( wndPtr ); + WIN_ReleasePtr( wndPtr ); return; } @@ -112,8 +115,7 @@ void WINPOS_CheckInternalPos( HWND hwnd ) } QUEUE_Unlock( pMsgQ ); - WIN_ReleaseWndPtr( wndPtr ); - return; + WIN_ReleasePtr( wndPtr ); } /*********************************************************************** @@ -169,16 +171,41 @@ void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore ) /*********************************************************************** * GetWindowRect (USER32.@) */ -BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect ) +BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect ) { - WND * wndPtr = WIN_FindWndPtr( hwnd ); + BOOL ret; + WND *wndPtr = WIN_GetPtr( hwnd ); + if (!wndPtr) return FALSE; - *rect = wndPtr->rectWindow; - WIN_ReleaseWndPtr(wndPtr); - MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 ); - TRACE("hwnd %04x (%d,%d)-(%d,%d)\n", - hwnd, rect->left, rect->top, rect->right, rect->bottom); - return TRUE; + + if (wndPtr != WND_OTHER_PROCESS) + { + *rect = wndPtr->rectWindow; + WIN_ReleasePtr( wndPtr ); + ret = TRUE; + } + else + { + SERVER_START_REQ( get_window_rectangles ) + { + req->handle = hwnd; + if ((ret = !SERVER_CALL_ERR())) + { + rect->left = req->window.left; + rect->top = req->window.top; + rect->right = req->window.right; + rect->bottom = req->window.bottom; + } + } + SERVER_END_REQ; + } + if (ret) + { + MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 ); + TRACE( "hwnd %04x (%d,%d)-(%d,%d)\n", + hwnd, rect->left, rect->top, rect->right, rect->bottom); + } + return ret; } @@ -246,19 +273,35 @@ int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw ) /*********************************************************************** * GetClientRect (USER32.@) */ -BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect ) +BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect ) { - WND * wndPtr = WIN_FindWndPtr( hwnd ); + BOOL ret; + WND *wndPtr = WIN_GetPtr( hwnd ); rect->left = rect->top = rect->right = rect->bottom = 0; if (!wndPtr) return FALSE; - rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left; - rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top; - WIN_ReleaseWndPtr(wndPtr); - TRACE("hwnd %04x (%d,%d)-(%d,%d)\n", - hwnd, rect->left, rect->top, rect->right, rect->bottom); - return TRUE; + if (wndPtr != WND_OTHER_PROCESS) + { + rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left; + rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top; + WIN_ReleasePtr( wndPtr ); + ret = TRUE; + } + else + { + SERVER_START_REQ( get_window_rectangles ) + { + req->handle = hwnd; + if ((ret = !SERVER_CALL_ERR())) + { + rect->right = req->client.right - req->client.left; + rect->bottom = req->client.bottom - req->client.top; + } + } + SERVER_END_REQ; + } + return ret; } @@ -316,8 +359,6 @@ static HWND find_child_from_point( HWND parent, POINT pt, INT *hittest, LPARAM l } else if (!PtInRect( &wndPtr->rectWindow, pt )) goto next; /* not in window -> skip */ - TRACE( "%ld,%ld is inside %04x\n", pt.x, pt.y, list[i] ); - /* If window is minimized or disabled, return at once */ if (wndPtr->dwStyle & WS_MINIMIZE) { @@ -401,7 +442,10 @@ HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ) xy.y -= wndScope->rectClient.top; WIN_ReleaseWndPtr( wndScope ); if ((ret = find_child_from_point( hwndScope, xy, hittest, MAKELONG( pt.x, pt.y ) ))) + { + TRACE( "found child %x\n", ret ); return ret; + } } else WIN_ReleaseWndPtr( wndScope ); @@ -409,15 +453,18 @@ HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ) if (!WIN_IsCurrentThread( hwndScope )) { *hittest = HTCLIENT; + TRACE( "returning %x\n", hwndScope ); return hwndScope; } res = SendMessageA( hwndScope, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y ) ); if (res != HTTRANSPARENT) { *hittest = res; /* Found the window */ + TRACE( "returning %x\n", hwndScope ); return hwndScope; } *hittest = HTNOWHERE; + TRACE( "nothing found\n" ); return 0; } @@ -483,59 +530,67 @@ HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags) * Calculate the offset between the origin of the two windows. Used * to implement MapWindowPoints. */ -static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, - POINT *offset ) +static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, POINT *offset ) { - WND * wndPtr = 0; - HWND *list; - int i; + WND * wndPtr; offset->x = offset->y = 0; - if (hwndFrom == hwndTo ) return; - /* Translate source window origin to screen coords */ + /* Translate source window origin to screen coords */ if (hwndFrom) { - if (!(wndPtr = WIN_FindWndPtr( hwndFrom ))) + HWND hwnd = hwndFrom; + + while (hwnd) { - ERR("bad hwndFrom = %04x\n",hwndFrom); - return; - } - if ((list = WIN_ListParents( hwndFrom ))) - { - for (i = 0; list[i]; i++) + if (hwnd == hwndTo) return; + if (!(wndPtr = WIN_GetPtr( hwnd ))) { - offset->x += wndPtr->rectClient.left; - offset->y += wndPtr->rectClient.top; - WIN_ReleaseWndPtr( wndPtr ); - if (!(wndPtr = WIN_FindWndPtr( list[i] ))) break; + ERR( "bad hwndFrom = %04x\n", hwnd ); + return; } - HeapFree( GetProcessHeap(), 0, list ); + if (wndPtr == WND_OTHER_PROCESS) goto other_process; + offset->x += wndPtr->rectClient.left; + offset->y += wndPtr->rectClient.top; + hwnd = wndPtr->parent; + WIN_ReleasePtr( wndPtr ); } - WIN_ReleaseWndPtr(wndPtr); } - /* Translate origin to destination window coords */ + /* Translate origin to destination window coords */ if (hwndTo) { - if (!(wndPtr = WIN_FindWndPtr( hwndTo ))) + HWND hwnd = hwndTo; + + while (hwnd) { - ERR("bad hwndTo = %04x\n", hwndTo ); - return; - } - if ((list = WIN_ListParents( hwndTo ))) - { - for (i = 0; list[i]; i++) + if (!(wndPtr = WIN_GetPtr( hwnd ))) { - offset->x -= wndPtr->rectClient.left; - offset->y -= wndPtr->rectClient.top; - WIN_ReleaseWndPtr( wndPtr ); - if (!(wndPtr = WIN_FindWndPtr( list[i] ))) break; + ERR( "bad hwndTo = %04x\n", hwnd ); + return; } - HeapFree( GetProcessHeap(), 0, list ); + if (wndPtr == WND_OTHER_PROCESS) goto other_process; + offset->x -= wndPtr->rectClient.left; + offset->y -= wndPtr->rectClient.top; + hwnd = wndPtr->parent; + WIN_ReleasePtr( wndPtr ); } - WIN_ReleaseWndPtr(wndPtr); } + return; + + other_process: /* one of the parents may belong to another process, do it the hard way */ + offset->x = offset->y = 0; + SERVER_START_REQ( get_windows_offset ) + { + req->from = hwndFrom; + req->to = hwndTo; + if (!SERVER_CALL()) + { + offset->x = req->x; + offset->y = req->y; + } + } + SERVER_END_REQ; } @@ -560,12 +615,11 @@ void WINAPI MapWindowPoints16( HWND16 hwndFrom, HWND16 hwndTo, /******************************************************************* * MapWindowPoints (USER32.@) */ -INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, - LPPOINT lppt, UINT count ) +INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, UINT count ) { POINT offset; - WINPOS_GetWinOffset( WIN_GetFullHandle(hwndFrom), WIN_GetFullHandle(hwndTo), &offset ); + WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset ); while (count--) { lppt->x += offset.x; @@ -581,12 +635,7 @@ INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, */ BOOL WINAPI IsIconic(HWND hWnd) { - BOOL retvalue; - WND * wndPtr = WIN_FindWndPtr(hWnd); - if (wndPtr == NULL) return FALSE; - retvalue = (wndPtr->dwStyle & WS_MINIMIZE) != 0; - WIN_ReleaseWndPtr(wndPtr); - return retvalue; + return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MINIMIZE) != 0; } @@ -595,12 +644,7 @@ BOOL WINAPI IsIconic(HWND hWnd) */ BOOL WINAPI IsZoomed(HWND hWnd) { - BOOL retvalue; - WND * wndPtr = WIN_FindWndPtr(hWnd); - if (wndPtr == NULL) return FALSE; - retvalue = (wndPtr->dwStyle & WS_MAXIMIZE) != 0; - WIN_ReleaseWndPtr(wndPtr); - return retvalue; + return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MAXIMIZE) != 0; } @@ -780,8 +824,7 @@ BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy, /*********************************************************************** * WINPOS_InitInternalPos */ -static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt, - LPRECT restoreRect ) +static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt, const RECT *restoreRect ) { LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( wnd->hwndSelf, atomInternalPos ); @@ -948,7 +991,11 @@ BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd ) */ BOOL WINAPI ShowWindow( HWND hwnd, INT cmd ) { - return USER_Driver.pShowWindow( hwnd, cmd ); + HWND full_handle; + + if ((full_handle = WIN_IsCurrentThread( hwnd ))) + return USER_Driver.pShowWindow( full_handle, cmd ); + return SendMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 ); } @@ -1360,7 +1407,6 @@ CLEANUP_END: BOOL WINPOS_ActivateOtherWindow(HWND hwnd) { BOOL bRet = 0; - WND *pWnd; HWND hwndActive = 0; HWND hwndTo = 0; HWND owner; @@ -1376,21 +1422,16 @@ BOOL WINPOS_ActivateOtherWindow(HWND hwnd) } } - pWnd = WIN_FindWndPtr( hwnd ); - hwnd = pWnd->hwndSelf; + if (!(hwnd = WIN_IsCurrentThread( hwnd ))) return 0; if( hwnd == hwndPrevActive ) hwndPrevActive = 0; - if( hwndActive != hwnd && - ( hwndActive || QUEUE_IsExitingQueue(pWnd->hmemTaskQ)) ) - { - WIN_ReleaseWndPtr( pWnd ); + if( hwndActive != hwnd && (hwndActive || USER_IsExitingThread( GetCurrentThreadId() ))) return 0; - } - owner = GetWindow( hwnd, GW_OWNER ); - if( !(pWnd->dwStyle & WS_POPUP) || !owner || + if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_POPUP) || + !(owner = GetWindow( hwnd, GW_OWNER )) || !WINPOS_CanActivate((hwndTo = GetAncestor( owner, GA_ROOT ))) ) { HWND tmp = GetAncestor( hwnd, GA_ROOT ); @@ -1403,7 +1444,6 @@ BOOL WINPOS_ActivateOtherWindow(HWND hwnd) if( !hwndTo ) break; } } - WIN_ReleaseWndPtr( pWnd ); bRet = WINPOS_SetActiveWindow( hwndTo, FALSE, TRUE ); @@ -1451,45 +1491,6 @@ BOOL WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg ) } -/*********************************************************************** - * WINPOS_SendNCCalcSize - * - * Send a WM_NCCALCSIZE message to a window. - * All parameters are read-only except newClientRect. - * oldWindowRect, oldClientRect and winpos must be non-NULL only - * when calcValidRect is TRUE. - */ -LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect, - RECT *newWindowRect, RECT *oldWindowRect, - RECT *oldClientRect, WINDOWPOS *winpos, - RECT *newClientRect ) -{ - NCCALCSIZE_PARAMS params; - WINDOWPOS winposCopy; - LONG result; - - params.rgrc[0] = *newWindowRect; - if (calcValidRect) - { - winposCopy = *winpos; - params.rgrc[1] = *oldWindowRect; - params.rgrc[2] = *oldClientRect; - params.lppos = &winposCopy; - } - result = SendMessageA( hwnd, WM_NCCALCSIZE, calcValidRect, - (LPARAM)¶ms ); - TRACE("%d,%d-%d,%d\n", - params.rgrc[0].left, params.rgrc[0].top, - params.rgrc[0].right, params.rgrc[0].bottom ); - - /* If the application send back garbage, ignore it */ - if (params.rgrc[0].left <= params.rgrc[0].right && params.rgrc[0].top <= params.rgrc[0].bottom) - *newClientRect = params.rgrc[0]; - - return result; -} - - /*********************************************************************** * WINPOS_HandleWindowPosChanging16 * @@ -1557,7 +1558,8 @@ BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter, winpos.cx = cx; winpos.cy = cy; winpos.flags = flags; - return USER_Driver.pSetWindowPos( &winpos ); + if (WIN_IsCurrentThread( hwnd )) return USER_Driver.pSetWindowPos( &winpos ); + return SendMessageW( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos ); } @@ -1599,31 +1601,13 @@ HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter, DWP *pDWP; int i; HDWP newhdwp = hdwp,retvalue; - /* HWND parent; */ - WND *pWnd; hwnd = WIN_GetFullHandle( hwnd ); if (hwnd == GetDesktopWindow()) return 0; if (!(pDWP = USER_HEAP_LIN_ADDR( hdwp ))) return 0; - if (!(pWnd = WIN_FindWndPtr( hwnd ))) return 0; - -/* Numega Bounds Checker Demo dislikes the following code. - In fact, I've not been able to find any "same parent" requirement in any docu - [AM 980509] - */ -#if 0 - /* All the windows of a DeferWindowPos() must have the same parent */ - parent = pWnd->parent->hwndSelf; - if (pDWP->actualCount == 0) pDWP->hwndParent = parent; - else if (parent != pDWP->hwndParent) - { - USER_HEAP_FREE( hdwp ); - retvalue = 0; - goto END; - } -#endif + USER_Lock(); for (i = 0; i < pDWP->actualCount; i++) { @@ -1638,7 +1622,7 @@ HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter, { pDWP->winPos[i].x = x; pDWP->winPos[i].y = y; - } + } if (!(flags & SWP_NOSIZE)) { pDWP->winPos[i].cx = cx; @@ -1676,7 +1660,7 @@ HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter, pDWP->actualCount++; retvalue = newhdwp; END: - WIN_ReleaseWndPtr(pWnd); + USER_Unlock(); return retvalue; } diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c index 8eb9910be29..e567a7c6854 100644 --- a/windows/x11drv/event.c +++ b/windows/x11drv/event.c @@ -1200,7 +1200,6 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event ) LPDRAGINFO16 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo); SEGPTR spDragInfo = K32WOWGlobalLock16(hDragInfo); Window w_aux_root, w_aux_child; - WND* pDropWnd; WND* pWnd; if( !lpDragInfo || !spDragInfo ) return; @@ -1224,76 +1223,73 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event ) bAccept = DRAG_QueryUpdate( hWnd, spDragInfo, TRUE ); x = lpDragInfo->pt.x; y = lpDragInfo->pt.y; } - pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope ); WIN_ReleaseWndPtr(pWnd); GlobalFree16( hDragInfo ); - - if( bAccept ) - { - TSXGetWindowProperty( event->display, DefaultRootWindow(event->display), - dndSelection, 0, 65535, FALSE, - AnyPropertyType, &u.atom_aux, (int *) &u.pt_aux.y, - &data_length, &aux_long, &p_data); - - if( !aux_long && p_data) /* don't bother if > 64K */ - { - signed char *p = (signed char*) p_data; - char *p_drop; - - aux_long = 0; - while( *p ) /* calculate buffer size */ - { - p_drop = p; - if((u.i = *p) != -1 ) - { - INT len = GetShortPathNameA( p, NULL, 0 ); - if (len) aux_long += len + 1; - else *p = -1; - } - p += strlen(p) + 1; - } - if( aux_long && aux_long < 65535 ) - { - HDROP hDrop; - DROPFILES *lpDrop; - - aux_long += sizeof(DROPFILES) + 1; - hDrop = GlobalAlloc( GMEM_SHARE, aux_long ); - lpDrop = (DROPFILES*)GlobalLock( hDrop ); - - if( lpDrop ) - { - lpDrop->pFiles = sizeof(DROPFILES); - lpDrop->pt.x = x; - lpDrop->pt.y = y; - lpDrop->fNC = - ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) || - y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) || - x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) || - y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) ); - lpDrop->fWide = FALSE; - p_drop = (char *)(lpDrop + 1); - p = p_data; - while(*p) - { - if( *p != -1 ) /* use only "good" entries */ - { - GetShortPathNameA( p, p_drop, 65535 ); - p_drop += strlen( p_drop ) + 1; - } - p += strlen(p) + 1; - } - *p_drop = '\0'; - PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L ); - } - } - } - if( p_data ) TSXFree(p_data); - - } /* WS_EX_ACCEPTFILES */ - WIN_ReleaseWndPtr(pDropWnd); + if (!bAccept) return; + + TSXGetWindowProperty( event->display, DefaultRootWindow(event->display), + dndSelection, 0, 65535, FALSE, + AnyPropertyType, &u.atom_aux, (int *) &u.pt_aux.y, + &data_length, &aux_long, &p_data); + + if( !aux_long && p_data) /* don't bother if > 64K */ + { + signed char *p = (signed char*) p_data; + char *p_drop; + + aux_long = 0; + while( *p ) /* calculate buffer size */ + { + p_drop = p; + if((u.i = *p) != -1 ) + { + INT len = GetShortPathNameA( p, NULL, 0 ); + if (len) aux_long += len + 1; + else *p = -1; + } + p += strlen(p) + 1; + } + if( aux_long && aux_long < 65535 ) + { + HDROP hDrop; + DROPFILES *lpDrop; + + aux_long += sizeof(DROPFILES) + 1; + hDrop = GlobalAlloc( GMEM_SHARE, aux_long ); + lpDrop = (DROPFILES*)GlobalLock( hDrop ); + + if( lpDrop ) + { + WND *pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope ); + lpDrop->pFiles = sizeof(DROPFILES); + lpDrop->pt.x = x; + lpDrop->pt.y = y; + lpDrop->fNC = + ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) || + y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) || + x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) || + y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) ); + lpDrop->fWide = FALSE; + WIN_ReleaseWndPtr(pDropWnd); + p_drop = (char *)(lpDrop + 1); + p = p_data; + while(*p) + { + if( *p != -1 ) /* use only "good" entries */ + { + GetShortPathNameA( p, p_drop, 65535 ); + p_drop += strlen( p_drop ) + 1; + } + p += strlen(p) + 1; + } + *p_drop = '\0'; + PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L ); + } + } + } + if( p_data ) TSXFree(p_data); } /********************************************************************** @@ -1306,8 +1302,6 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event ) */ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) { - WND *pDropWnd; - WND *pWnd; unsigned long data_length; unsigned long aux_long, drop_len = 0; unsigned char *p_data = NULL; /* property data */ @@ -1322,14 +1316,7 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) Window w_aux; } u; /* unused */ - pWnd = WIN_FindWndPtr(hWnd); - - if (!(pWnd->dwExStyle & WS_EX_ACCEPTFILES)) - { - WIN_ReleaseWndPtr(pWnd); - return; - } - WIN_ReleaseWndPtr(pWnd); + if (!(GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return; TSXGetWindowProperty( event->display, DefaultRootWindow(event->display), dndSelection, 0, 65535, FALSE, @@ -1362,13 +1349,12 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) TSXQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux, &x, &y, &u.i, &u.i, &u.i); - pDropWnd = WIN_FindWndPtr( hWnd ); - drop_len += sizeof(DROPFILES) + 1; hDrop = GlobalAlloc( GMEM_SHARE, drop_len ); lpDrop = (DROPFILES *) GlobalLock( hDrop ); if( lpDrop ) { + WND *pDropWnd = WIN_FindWndPtr( hWnd ); lpDrop->pFiles = sizeof(DROPFILES); lpDrop->pt.x = (INT)x; lpDrop->pt.y = (INT)y; @@ -1379,6 +1365,7 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) ); lpDrop->fWide = FALSE; p_drop = (char*)(lpDrop + 1); + WIN_ReleaseWndPtr(pDropWnd); } /* create message content */ @@ -1411,7 +1398,6 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) GlobalUnlock(hDrop); PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L ); } - WIN_ReleaseWndPtr(pDropWnd); } if( p_data ) TSXFree(p_data); }