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.
This commit is contained in:
Alexandre Julliard 2001-10-16 21:58:58 +00:00
parent 0d50965a13
commit fb0ff053c0
16 changed files with 659 additions and 545 deletions

View File

@ -43,7 +43,6 @@ const struct builtin_class_descr ICONTITLE_builtin_class =
*/ */
HWND ICONTITLE_Create( HWND owner ) HWND ICONTITLE_Create( HWND owner )
{ {
WND* wndPtr;
HWND hWnd; HWND hWnd;
HINSTANCE instance = GetWindowLongA( owner, GWL_HINSTANCE ); HINSTANCE instance = GetWindowLongA( owner, GWL_HINSTANCE );
LONG style = WS_CLIPSIBLINGS; LONG style = WS_CLIPSIBLINGS;
@ -57,10 +56,9 @@ HWND ICONTITLE_Create( HWND owner )
hWnd = CreateWindowExA( 0, ICONTITLE_CLASS_ATOM, NULL, hWnd = CreateWindowExA( 0, ICONTITLE_CLASS_ATOM, NULL,
style, 0, 0, 1, 1, style, 0, 0, 1, 1,
owner, 0, instance, NULL ); owner, 0, instance, NULL );
if (!(wndPtr = WIN_GetPtr( hWnd ))) return 0; WIN_SetOwner( hWnd, owner ); /* MDI depends on this */
wndPtr->owner = owner; /* MDI depends on this */ SetWindowLongW( hWnd, GWL_STYLE,
wndPtr->dwStyle &= ~(WS_CAPTION | WS_BORDER); GetWindowLongW( hWnd, GWL_STYLE ) & ~(WS_CAPTION | WS_BORDER) );
WIN_ReleasePtr(wndPtr);
return hWnd; return hWnd;
} }

View File

@ -566,9 +566,36 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
/* Send WM_NCCALCSIZE message to get new client area */ /* Send WM_NCCALCSIZE message to get new client area */
if( (winpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE ) if( (winpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
{ {
WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect, NCCALCSIZE_PARAMS params;
&wndPtr->rectWindow, &wndPtr->rectClient, WINDOWPOS winposCopy;
winpos, &newClientRect );
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)&params );
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) 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 */ /* FIXME: actually do something with WVR_VALIDRECTS */
wndPtr->rectWindow = newWindowRect; WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect );
wndPtr->rectClient = newClientRect;
if( winpos->flags & SWP_SHOWWINDOW ) if( winpos->flags & SWP_SHOWWINDOW )
{ {

View File

@ -533,6 +533,10 @@ static size_t pack_message( HWND hwnd, UINT message, WPARAM wparam, LPARAM lpara
if (lparam) return sizeof(BOOL); if (lparam) return sizeof(BOOL);
return 0; return 0;
case WM_WINE_SETWINDOWPOS:
push_data( data, (WINDOWPOS *)lparam, sizeof(WINDOWPOS) );
return 0;
/* these contain an HFONT */ /* these contain an HFONT */
case WM_SETFONT: case WM_SETFONT:
case WM_GETFONT: case WM_GETFONT:
@ -644,6 +648,7 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
break; break;
case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED: case WM_WINDOWPOSCHANGED:
case WM_WINE_SETWINDOWPOS:
minsize = sizeof(WINDOWPOS); minsize = sizeof(WINDOWPOS);
break; break;
case WM_COPYDATA: 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 * call_window_proc
* *
@ -1082,7 +1111,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
LRESULT result; LRESULT result;
WNDPROC winproc; WNDPROC winproc;
/* FIXME: should check for exiting queue */ if (msg & 0x80000000) return handle_internal_message( hwnd, msg, wparam, lparam );
/* first the WH_CALLWNDPROC hook */ /* first the WH_CALLWNDPROC hook */
if (HOOK_IsHooked( WH_CALLWNDPROC )) 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; unsigned int res;
int timeout = -1; int timeout = -1;
/* FIXME: should check for exiting queue */
if (info->type != MSG_NOTIFY && if (info->type != MSG_NOTIFY &&
info->type != MSG_CALLBACK && info->type != MSG_CALLBACK &&
info->type != MSG_POSTED && 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 ); 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()) 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 ); 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()) if (dest_tid == GetCurrentThreadId())
{ {
@ -1624,7 +1655,9 @@ BOOL WINAPI SendNotifyMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
return TRUE; 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()) if (dest_tid == GetCurrentThreadId())
{ {
@ -1676,7 +1709,9 @@ BOOL WINAPI SendMessageCallbackW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa
return TRUE; 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()) 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 ) BOOL WINAPI PostMessageW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{ {
struct send_message_info info; struct send_message_info info;
DWORD dest_tid;
if (is_pointer_message( msg )) 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 ); EnumWindows( broadcast_message_callback, (LPARAM)&info );
return TRUE; 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 ); SetLastError( ERROR_INVALID_PARAMETER );
return FALSE; return FALSE;
} }
if (USER_IsExitingThread( thread )) return TRUE;
info.type = MSG_POSTED; info.type = MSG_POSTED;
info.hwnd = 0; info.hwnd = 0;

View File

@ -34,8 +34,10 @@ WINE_LOOK TWEAK_WineLook = WIN31_LOOK;
WORD USER_HeapSel = 0; /* USER heap selector */ WORD USER_HeapSel = 0; /* USER heap selector */
static HMODULE graphics_driver; static HMODULE graphics_driver;
static DWORD exiting_thread_id;
extern void COMM_Init(void); extern void COMM_Init(void);
extern void WDML_NotifyThreadDetach(void);
#define GET_USER_FUNC(name) USER_Driver.p##name = (void*)GetProcAddress( graphics_driver, #name ) #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) static void thread_detach(void)
{ {
HQUEUE16 hQueue = GetThreadQueue16( 0 ); HQUEUE16 hQueue = GetThreadQueue16( 0 );
extern void WDML_NotifyThreadDetach(void); exiting_thread_id = GetCurrentThreadId();
WDML_NotifyThreadDetach(); WDML_NotifyThreadDetach();
if (hQueue) if (hQueue)
{ {
TIMER_RemoveQueueTimers( hQueue ); TIMER_RemoveQueueTimers( hQueue );
HOOK_FreeQueueHooks(); HOOK_FreeQueueHooks();
QUEUE_SetExitingQueue( hQueue );
WIN_DestroyThreadWindows( GetDesktopWindow() ); WIN_DestroyThreadWindows( GetDesktopWindow() );
QUEUE_DeleteMsgQueue(); QUEUE_DeleteMsgQueue();
} }
@ -290,6 +301,7 @@ static void thread_detach(void)
CURSORICON_FreeModuleIcons( hModule ); CURSORICON_FreeModuleIcons( hModule );
} }
} }
exiting_thread_id = 0;
} }

View File

@ -872,7 +872,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
rect = wndPtr->rectWindow; rect = wndPtr->rectWindow;
SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect ); SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect );
if (rect.left > rect.right || rect.top > rect.bottom) rect = wndPtr->rectWindow; 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_sync_client_window_position( display, wndPtr );
X11DRV_register_window( display, hwnd, data ); X11DRV_register_window( display, hwnd, data );
@ -1005,18 +1005,14 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
{ {
Display *display = thread_display(); Display *display = thread_display();
WND *wndPtr; WND *wndPtr;
DWORD dwStyle;
HWND retvalue; 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 /* Windows hides the window first, then shows it again
* including the WM_SHOWWINDOW messages and all */ * 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 */ retvalue = wndPtr->parent; /* old parent */
if (parent != retvalue) if (parent != retvalue)
@ -1027,7 +1023,7 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
if (parent != GetDesktopWindow()) /* a child window */ if (parent != GetDesktopWindow()) /* a child window */
{ {
if (!(dwStyle & WS_CHILD)) if (!(wndPtr->dwStyle & WS_CHILD))
{ {
HMENU menu = (HMENU)SetWindowLongW( hwnd, GWL_ID, 0 ); HMENU menu = (HMENU)SetWindowLongW( hwnd, GWL_ID, 0 );
if (menu) DestroyMenu( menu ); if (menu) DestroyMenu( menu );
@ -1041,15 +1037,14 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent )
data->whole_rect.left, data->whole_rect.top ); data->whole_rect.left, data->whole_rect.top );
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleasePtr( wndPtr );
/* SetParent additionally needs to make hwnd the topmost window /* SetParent additionally needs to make hwnd the topmost window
in the x-order and send the expected WM_WINDOWPOSCHANGING and in the x-order and send the expected WM_WINDOWPOSCHANGING and
WM_WINDOWPOSCHANGED notification messages. WM_WINDOWPOSCHANGED notification messages.
*/ */
SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0, SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE| SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) );
((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
/* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
* for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */ * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */

View File

@ -523,7 +523,7 @@ static BOOL SWP_DoWinPosChanging( WINDOWPOS* pWinpos, RECT* pNewWindowRect, RECT
if (!(pWinpos->flags & SWP_NOSENDCHANGING)) if (!(pWinpos->flags & SWP_NOSENDCHANGING))
SendMessageA( pWinpos->hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)pWinpos ); 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 */ /* Calculate new position and size */
@ -547,43 +547,69 @@ static BOOL SWP_DoWinPosChanging( WINDOWPOS* pWinpos, RECT* pNewWindowRect, RECT
pWinpos->y - wndPtr->rectWindow.top ); pWinpos->y - wndPtr->rectWindow.top );
} }
pWinpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE; pWinpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleasePtr( wndPtr );
return TRUE; return TRUE;
} }
/*********************************************************************** /***********************************************************************
* SWP_DoNCCalcSize * SWP_DoNCCalcSize
*/ */
static UINT SWP_DoNCCalcSize( WND* wndPtr, WINDOWPOS* pWinpos, static UINT SWP_DoNCCalcSize( WINDOWPOS* pWinpos, RECT* pNewWindowRect, RECT* pNewClientRect )
RECT* pNewWindowRect, RECT* pNewClientRect )
{ {
UINT wvrFlags = 0; 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 */ /* Send WM_NCCALCSIZE message to get new client area */
if( (pWinpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE ) if( (pWinpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
{ {
wvrFlags = WINPOS_SendNCCalcSize( pWinpos->hwnd, TRUE, pNewWindowRect, NCCALCSIZE_PARAMS params;
&wndPtr->rectWindow, &wndPtr->rectClient, WINDOWPOS winposCopy;
pWinpos, pNewClientRect );
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)&params );
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 */ /* FIXME: WVR_ALIGNxxx */
if( pNewClientRect->left != wndPtr->rectClient.left || if (!(wndPtr = WIN_GetPtr( pWinpos->hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
pNewClientRect->top != wndPtr->rectClient.top )
pWinpos->flags &= ~SWP_NOCLIENTMOVE;
if( (pNewClientRect->right - pNewClientRect->left != if( pNewClientRect->left != wndPtr->rectClient.left ||
wndPtr->rectClient.right - wndPtr->rectClient.left) || pNewClientRect->top != wndPtr->rectClient.top )
(pNewClientRect->bottom - pNewClientRect->top != pWinpos->flags &= ~SWP_NOCLIENTMOVE;
wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
pWinpos->flags &= ~SWP_NOCLIENTSIZE; 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 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; pWinpos->flags &= ~SWP_NOCLIENTMOVE;
}
WIN_ReleasePtr( wndPtr );
return wvrFlags; return wvrFlags;
} }
/*********************************************************************** /***********************************************************************
* SWP_DoOwnedPopups * SWP_DoOwnedPopups
* *
@ -783,7 +809,7 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
/* Common operations */ /* Common operations */
wvrFlags = SWP_DoNCCalcSize( wndPtr, winpos, &newWindowRect, &newClientRect ); wvrFlags = SWP_DoNCCalcSize( winpos, &newWindowRect, &newClientRect );
if(!(winpos->flags & SWP_NOZORDER) && winpos->hwnd != winpos->hwndInsertAfter) 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 */ /* FIXME: actually do something with WVR_VALIDRECTS */
wndPtr->rectWindow = newWindowRect; WIN_SetRectangles( winpos->hwnd, &newWindowRect, &newClientRect );
wndPtr->rectClient = newClientRect;
if (winpos->flags & SWP_SHOWWINDOW) wndPtr->dwStyle |= WS_VISIBLE; if (winpos->flags & SWP_SHOWWINDOW) wndPtr->dwStyle |= WS_VISIBLE;
else if (winpos->flags & SWP_HIDEWINDOW) 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 ) UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
{ {
WND *wndPtr = WIN_FindWndPtr( hwnd ); WND *wndPtr;
UINT swpFlags = 0; UINT swpFlags = 0;
POINT size; POINT size;
WINDOWPLACEMENT wpl; WINDOWPLACEMENT wpl;
@ -1003,90 +1028,87 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
wpl.length = sizeof(wpl); wpl.length = sizeof(wpl);
GetWindowPlacement( hwnd, &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.x = wndPtr->rectWindow.left;
size.y = wndPtr->rectWindow.top; 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( wndPtr->dwStyle & WS_MINIMIZE )
{ {
if( !SendMessageA( wndPtr->hwndSelf, WM_QUERYOPEN, 0, 0L ) ) wndPtr->dwStyle &= ~WS_MINIMIZE;
{ WINPOS_ShowIconTitle( hwnd, FALSE );
swpFlags = SWP_NOSIZE | SWP_NOMOVE; X11DRV_set_iconic_state( wndPtr );
goto done;
}
swpFlags |= SWP_NOCOPYBITS;
} }
switch( cmd ) wndPtr->dwStyle |= WS_MAXIMIZE;
{
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;
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 ); X11DRV_set_iconic_state( wndPtr );
wpl.ptMinPosition = WINPOS_FindIconPos( wndPtr, wpl.ptMinPosition ); if( wndPtr->flags & WIN_RESTORE_MAX)
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 )
{ {
wndPtr->dwStyle &= ~WS_MINIMIZE; /* Restore to maximized position */
WINPOS_ShowIconTitle( hwnd, FALSE ); WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL);
X11DRV_set_iconic_state( wndPtr ); 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 ); WIN_ReleaseWndPtr( wndPtr );
return swpFlags; return swpFlags;
} }

View File

@ -69,8 +69,6 @@ HWND PERQDATA_SetCaptureWnd( HWND hWndCapture, INT hittest );
extern MESSAGEQUEUE *QUEUE_Current(void); extern MESSAGEQUEUE *QUEUE_Current(void);
extern MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue ); extern MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue );
extern void QUEUE_Unlock( MESSAGEQUEUE *queue ); extern void QUEUE_Unlock( MESSAGEQUEUE *queue );
extern BOOL QUEUE_IsExitingQueue( HQUEUE16 hQueue );
extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue );
extern void QUEUE_DeleteMsgQueue(void); extern void QUEUE_DeleteMsgQueue(void);
#endif /* __WINE_QUEUE_H */ #endif /* __WINE_QUEUE_H */

View File

@ -35,7 +35,14 @@ struct DIDEVICEOBJECTDATA;
typedef VOID CALLBACK (*LPMOUSE_EVENT_PROC)(DWORD,DWORD,DWORD,DWORD,DWORD); 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 { typedef struct tagUSER_DRIVER {
/* keyboard functions */ /* keyboard functions */
@ -99,6 +106,8 @@ extern void USER_Lock(void);
extern void USER_Unlock(void); extern void USER_Unlock(void);
extern void USER_CheckNotLock(void); extern void USER_CheckNotLock(void);
extern BOOL USER_IsExitingThread( DWORD tid );
VOID WINAPI MOUSE_Enable(LPMOUSE_EVENT_PROC lpMouseEventProc); VOID WINAPI MOUSE_Enable(LPMOUSE_EVENT_PROC lpMouseEventProc);
VOID WINAPI MOUSE_Disable(VOID); VOID WINAPI MOUSE_Disable(VOID);

View File

@ -88,12 +88,16 @@ extern HWND WIN_IsCurrentProcess( HWND hwnd );
extern HWND WIN_IsCurrentThread( HWND hwnd ); extern HWND WIN_IsCurrentThread( HWND hwnd );
extern void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ); extern void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter );
extern void WIN_UnlinkWindow( HWND hwnd ); extern void WIN_UnlinkWindow( HWND hwnd );
extern void WIN_SetOwner( HWND hwnd, HWND owner );
extern void WIN_SetRectangles( HWND hwnd, const RECT *rectWindow, const RECT *rectClient );
extern HWND WIN_FindWinToRepaint( HWND hwnd ); extern HWND WIN_FindWinToRepaint( HWND hwnd );
extern LRESULT WIN_DestroyWindow( HWND hwnd );
extern void WIN_DestroyThreadWindows( HWND hwnd ); extern void WIN_DestroyThreadWindows( HWND hwnd );
extern BOOL WIN_CreateDesktopWindow(void); extern BOOL WIN_CreateDesktopWindow(void);
extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL ); extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL );
extern HWND *WIN_ListParents( HWND hwnd ); extern HWND *WIN_ListParents( HWND hwnd );
extern HWND *WIN_ListChildren( HWND hwnd ); extern HWND *WIN_ListChildren( HWND hwnd );
extern HWND WIN_SetParent( HWND hwnd, HWND parent );
extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly ); extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly );
inline static HWND WIN_GetFullHandle( HWND hwnd ) inline static HWND WIN_GetFullHandle( HWND hwnd )

View File

@ -28,10 +28,6 @@ extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, POIN
extern BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, extern BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse,
BOOL fChangeFocus ); BOOL fChangeFocus );
extern BOOL WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); 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_HandleWindowPosChanging16(HWND hwnd, struct tagWINDOWPOS16 *winpos);
extern LONG WINPOS_HandleWindowPosChanging(HWND hwnd, WINDOWPOS *winpos); extern LONG WINPOS_HandleWindowPosChanging(HWND hwnd, WINDOWPOS *winpos);
extern HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ); extern HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest );

View File

@ -144,11 +144,9 @@ DCE* DCE_FreeDCE( DCE *dce )
void DCE_FreeWindowDCE( HWND hwnd ) void DCE_FreeWindowDCE( HWND hwnd )
{ {
DCE *pDCE; DCE *pDCE;
WND *pWnd = WIN_FindWndPtr( hwnd ); WND *pWnd = WIN_GetPtr( hwnd );
pDCE = firstDCE; pDCE = firstDCE;
hwnd = pWnd->hwndSelf; /* make it a full handle */
while( pDCE ) while( pDCE )
{ {
if( pDCE->hwndCurrent == hwnd ) if( pDCE->hwndCurrent == hwnd )
@ -189,8 +187,7 @@ void DCE_FreeWindowDCE( HWND hwnd )
} }
pDCE = pDCE->next; pDCE = pDCE->next;
} }
WIN_ReleasePtr( pWnd );
WIN_ReleaseWndPtr( pWnd );
} }
@ -359,14 +356,19 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
DWORD dcxFlags = 0; DWORD dcxFlags = 0;
BOOL bUpdateVisRgn = TRUE; BOOL bUpdateVisRgn = TRUE;
BOOL bUpdateClipOrigin = FALSE; BOOL bUpdateClipOrigin = FALSE;
HWND parent; HWND parent, full;
TRACE("hwnd %04x, hrgnClip %04x, flags %08x\n", TRACE("hwnd %04x, hrgnClip %04x, flags %08x\n",
hwnd, hrgnClip, (unsigned)flags); hwnd, hrgnClip, (unsigned)flags);
if (!hwnd) hwnd = GetDesktopWindow(); if (!hwnd) hwnd = GetDesktopWindow();
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; if (!(full = WIN_IsCurrentProcess( hwnd )) && full != GetDesktopWindow())
hwnd = wndPtr->hwndSelf; /* make it a full handle */ {
FIXME( "not supported yet on other process window %x\n", full );
return 0;
}
hwnd = full;
if (!(wndPtr = WIN_GetPtr( hwnd ))) return 0;
/* fixup flags */ /* 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); TRACE("(%04x,%04x,0x%lx): returning %04x\n", hwnd, hrgnClip, flags, hdc);
END: END:
WIN_ReleaseWndPtr(wndPtr); WIN_ReleasePtr(wndPtr);
return hdc; return hdc;
} }

View File

@ -306,11 +306,20 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
BOOL bIcon; BOOL bIcon;
HRGN hrgnUpdate; HRGN hrgnUpdate;
RECT clipRect, clientRect; RECT clipRect, clientRect;
WND *wndPtr = WIN_FindWndPtr( hwnd ); HWND full_handle;
if (!wndPtr) return 0; 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; wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
/* send WM_NCPAINT and make sure hrgnUpdate is a valid rgn handle */ /* 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 * Make sure the window is still a window. All window locks are suspended
* when the WM_NCPAINT is sent. * when the WM_NCPAINT is sent.
*/ */
if (!IsWindow(wndPtr->hwndSelf)) if (!IsWindow( hwnd ))
{ {
WIN_ReleaseWndPtr(wndPtr); WIN_ReleaseWndPtr(wndPtr);
return 0; return 0;
@ -336,7 +345,7 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
TRACE("hrgnUpdate = %04x, \n", hrgnUpdate); 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 */ /* Don't clip the output to the update region for CS_PARENTDC window */
if( hrgnUpdate ) if( hrgnUpdate )

View File

@ -24,7 +24,6 @@
DEFAULT_DEBUG_CHANNEL(msg); DEFAULT_DEBUG_CHANNEL(msg);
static HQUEUE16 hExitingQueue = 0;
static PERQUEUEDATA *pQDataWin16 = NULL; /* Global perQData for Win16 tasks */ static PERQUEUEDATA *pQDataWin16 = NULL; /* Global perQData for Win16 tasks */
HQUEUE16 hActiveQueue = 0; 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 * QUEUE_CreateMsgQueue
* *
@ -417,7 +398,6 @@ void QUEUE_DeleteMsgQueue(void)
msgQueue->magic = 0; msgQueue->magic = 0;
if( hActiveQueue == hQueue ) hActiveQueue = 0; if( hActiveQueue == hQueue ) hActiveQueue = 0;
if (hExitingQueue == hQueue) hExitingQueue = 0;
HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */ HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */

View File

@ -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 * WIN_GetPtr
* *
@ -351,6 +363,14 @@ void WIN_UnlinkWindow( HWND hwnd )
void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ) void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
{ {
BOOL ret; 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 ) SERVER_START_REQ( link_window )
{ {
@ -360,18 +380,70 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
ret = !SERVER_CALL_ERR(); ret = !SERVER_CALL_ERR();
} }
SERVER_END_REQ; 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 ); win->owner = owner;
if (wndPtr) WIN_ReleaseWndPtr( win );
{
wndPtr->parent = WIN_GetFullHandle(parent);
WIN_ReleaseWndPtr( wndPtr );
}
} }
} }
/***********************************************************************
* 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 * find_child_to_repaint
* *
@ -481,18 +553,28 @@ HWND WIN_FindWinToRepaint( HWND hwnd )
* *
* Destroy storage associated to a window. "Internals" p.358 * Destroy storage associated to a window. "Internals" p.358
*/ */
static void WIN_DestroyWindow( HWND hwnd ) LRESULT WIN_DestroyWindow( HWND hwnd )
{ {
WND *wndPtr; WND *wndPtr;
HWND *list; HWND *list;
TRACE("%04x\n", hwnd ); TRACE("%04x\n", hwnd );
if (!(hwnd = WIN_IsCurrentThread( hwnd )))
{
ERR( "window doesn't belong to current thread\n" );
return 0;
}
/* free child windows */ /* free child windows */
if ((list = WIN_ListChildren( hwnd ))) if ((list = WIN_ListChildren( hwnd )))
{ {
int i; 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 ); HeapFree( GetProcessHeap(), 0, list );
} }
@ -517,7 +599,7 @@ static void WIN_DestroyWindow( HWND hwnd )
TIMER_RemoveWindowTimers( hwnd ); TIMER_RemoveWindowTimers( hwnd );
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return; if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
wndPtr->hmemTaskQ = 0; wndPtr->hmemTaskQ = 0;
if (!(wndPtr->dwStyle & WS_CHILD)) if (!(wndPtr->dwStyle & WS_CHILD))
@ -538,6 +620,7 @@ static void WIN_DestroyWindow( HWND hwnd )
wndPtr->class = NULL; wndPtr->class = NULL;
wndPtr->dwMagic = 0; /* Mark it as invalid */ wndPtr->dwMagic = 0; /* Mark it as invalid */
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleaseWndPtr( wndPtr );
return 0;
} }
/*********************************************************************** /***********************************************************************
@ -576,10 +659,10 @@ BOOL WIN_CreateDesktopWindow(void)
WNDPROC winproc; WNDPROC winproc;
DCE *dce; DCE *dce;
CREATESTRUCTA cs; CREATESTRUCTA cs;
RECT rect;
TRACE("Creating desktop window\n"); TRACE("Creating desktop window\n");
if (!WINPOS_CreateInternalPosAtom() || if (!WINPOS_CreateInternalPosAtom() ||
!(class = CLASS_AddWindow( (ATOM)LOWORD(DESKTOP_CLASS_ATOM), 0, WIN_PROC_32W, !(class = CLASS_AddWindow( (ATOM)LOWORD(DESKTOP_CLASS_ATOM), 0, WIN_PROC_32W,
&wndExtra, &winproc, &clsStyle, &dce ))) &wndExtra, &winproc, &clsStyle, &dce )))
@ -595,11 +678,6 @@ BOOL WIN_CreateDesktopWindow(void)
pWndDesktop->owner = 0; pWndDesktop->owner = 0;
pWndDesktop->class = class; pWndDesktop->class = class;
pWndDesktop->hInstance = 0; 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->text = NULL;
pWndDesktop->hmemTaskQ = 0; pWndDesktop->hmemTaskQ = 0;
pWndDesktop->hrgnUpdate = 0; pWndDesktop->hrgnUpdate = 0;
@ -625,13 +703,16 @@ BOOL WIN_CreateDesktopWindow(void)
cs.hwndParent = 0; cs.hwndParent = 0;
cs.x = 0; cs.x = 0;
cs.y = 0; cs.y = 0;
cs.cx = pWndDesktop->rectWindow.right; cs.cx = GetSystemMetrics( SM_CXSCREEN );
cs.cy = pWndDesktop->rectWindow.bottom; cs.cy = GetSystemMetrics( SM_CYSCREEN );
cs.style = pWndDesktop->dwStyle; cs.style = pWndDesktop->dwStyle;
cs.dwExStyle = pWndDesktop->dwExStyle; cs.dwExStyle = pWndDesktop->dwExStyle;
cs.lpszName = NULL; cs.lpszName = NULL;
cs.lpszClass = DESKTOP_CLASS_ATOM; 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; if (!USER_Driver.pCreateWindow( hwndDesktop, &cs, FALSE )) return FALSE;
pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND; pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
@ -721,6 +802,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
INT wndExtra; INT wndExtra;
DWORD clsStyle; DWORD clsStyle;
WNDPROC winproc; WNDPROC winproc;
RECT rect;
DCE *dce; DCE *dce;
BOOL unicode = (type == WIN_PROC_32W); BOOL unicode = (type == WIN_PROC_32W);
@ -867,11 +949,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
/* Initialize the dimensions before sending WM_GETMINMAXINFO */ /* Initialize the dimensions before sending WM_GETMINMAXINFO */
wndPtr->rectWindow.left = cs->x; SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
wndPtr->rectWindow.top = cs->y; WIN_SetRectangles( hwnd, &rect, &rect );
wndPtr->rectWindow.right = cs->x + cs->cx;
wndPtr->rectWindow.bottom = cs->y + cs->cy;
wndPtr->rectClient = wndPtr->rectWindow;
/* Send the WM_GETMINMAXINFO message and fix the size if needed */ /* 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->cx < 0) cs->cx = 0;
if (cs->cy < 0) cs->cy = 0; if (cs->cy < 0) cs->cy = 0;
wndPtr->rectWindow.left = cs->x; SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
wndPtr->rectWindow.top = cs->y; WIN_SetRectangles( hwnd, &rect, &rect );
wndPtr->rectWindow.right = cs->x + cs->cx;
wndPtr->rectWindow.bottom = cs->y + cs->cy;
wndPtr->rectClient = wndPtr->rectWindow;
/* Set the window menu */ /* Set the window menu */
@ -923,17 +999,13 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
return 0; 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, send_parent_notify( hwnd, WM_CREATE );
MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd ); if( !IsWindow(hwnd) )
if( !IsWindow(hwnd) ) {
{ hwnd = 0;
hwnd = 0; goto end;
goto end;
}
} }
if (cs->style & WS_VISIBLE) if (cs->style & WS_VISIBLE)
@ -1188,17 +1260,17 @@ static void WIN_SendDestroyMsg( HWND hwnd )
*/ */
BOOL WINAPI DestroyWindow( HWND hwnd ) BOOL WINAPI DestroyWindow( HWND hwnd )
{ {
WND * wndPtr; BOOL is_child;
BOOL retvalue;
HWND h; HWND h;
hwnd = WIN_GetFullHandle( hwnd ); if (!(hwnd = WIN_IsCurrentThread( hwnd )) || (hwnd == GetDesktopWindow()))
{
SetLastError( ERROR_ACCESS_DENIED );
return FALSE;
}
TRACE("(%04x)\n", hwnd); 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 /* Look whether the focus is within the tree of windows we will
* be destroying. * be destroying.
*/ */
@ -1214,25 +1286,20 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
if( HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0L) ) return FALSE; if( HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0L) ) return FALSE;
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; is_child = (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) != 0;
if (!(wndPtr->dwStyle & WS_CHILD) && !GetWindow( hwnd, GW_OWNER ))
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 ); HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L );
/* FIXME: clean up palette - see "Internals" p.352 */ /* FIXME: clean up palette - see "Internals" p.352 */
} }
if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) ) if (!IsWindow(hwnd)) return TRUE;
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 (USER_Driver.pResetSelectionOwner) if (USER_Driver.pResetSelectionOwner)
USER_Driver.pResetSelectionOwner( hwnd, FALSE ); /* before the window is unmapped */ USER_Driver.pResetSelectionOwner( hwnd, FALSE ); /* before the window is unmapped */
@ -1240,77 +1307,62 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
/* Hide the window */ /* Hide the window */
ShowWindow( hwnd, SW_HIDE ); ShowWindow( hwnd, SW_HIDE );
if (!IsWindow(hwnd)) if (!IsWindow(hwnd)) return TRUE;
{
retvalue = TRUE;
goto end;
}
/* Recursively destroy owned windows */ /* Recursively destroy owned windows */
if( !(wndPtr->dwStyle & WS_CHILD) ) if (!is_child)
{ {
HWND owner; HWND owner;
for (;;) for (;;)
{ {
int i, got_one = 0; int i, got_one = 0;
HWND *list = WIN_ListChildren( wndPtr->parent ); HWND *list = WIN_ListChildren( GetDesktopWindow() );
if (list) if (list)
{ {
for (i = 0; list[i]; i++) for (i = 0; list[i]; i++)
{ {
WND *siblingPtr; if (GetWindow( list[i], GW_OWNER ) != hwnd) continue;
if (GetWindow( list[i], GW_OWNER ) != hwnd) continue; if (WIN_IsCurrentThread( list[i] ))
if (!(siblingPtr = WIN_FindWndPtr( list[i] ))) continue; {
if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ) DestroyWindow( list[i] );
{ got_one = 1;
WIN_ReleaseWndPtr( siblingPtr ); continue;
DestroyWindow( list[i] ); }
got_one = 1; WIN_SetOwner( list[i], 0 );
continue; }
} HeapFree( GetProcessHeap(), 0, list );
else siblingPtr->owner = 0; }
WIN_ReleaseWndPtr( siblingPtr ); if (!got_one) break;
} }
HeapFree( GetProcessHeap(), 0, list );
}
if (!got_one) break;
}
WINPOS_ActivateOtherWindow( hwnd ); WINPOS_ActivateOtherWindow( hwnd );
if ((owner = GetWindow( hwnd, GW_OWNER ))) if ((owner = GetWindow( hwnd, GW_OWNER )))
{ {
WND *ptr = WIN_FindWndPtr( owner ); WND *ptr = WIN_FindWndPtr( owner );
if (ptr) if (ptr)
{ {
if (ptr->hwndLastActive == hwnd) ptr->hwndLastActive = owner; if (ptr->hwndLastActive == hwnd) ptr->hwndLastActive = owner;
WIN_ReleaseWndPtr( ptr ); WIN_ReleaseWndPtr( ptr );
} }
} }
} }
/* Send destroy messages */ /* Send destroy messages */
WIN_SendDestroyMsg( hwnd ); WIN_SendDestroyMsg( hwnd );
if (!IsWindow(hwnd)) if (!IsWindow( hwnd )) return TRUE;
{
retvalue = TRUE;
goto end;
}
/* Unlink now so we won't bother with the children later on */ /* 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 */ /* Destroy the window storage */
WIN_DestroyWindow( hwnd ); WIN_DestroyWindow( hwnd );
retvalue = TRUE; return TRUE;
end:
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
} }
@ -1319,20 +1371,9 @@ end:
*/ */
BOOL WINAPI CloseWindow( HWND hwnd ) BOOL WINAPI CloseWindow( HWND hwnd )
{ {
WND * wndPtr = WIN_FindWndPtr( hwnd ); if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) return FALSE;
BOOL retvalue;
if (!wndPtr || (wndPtr->dwStyle & WS_CHILD))
{
retvalue = FALSE;
goto end;
}
ShowWindow( hwnd, SW_MINIMIZE ); ShowWindow( hwnd, SW_MINIMIZE );
retvalue = TRUE; return TRUE;
end:
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
} }
@ -1523,14 +1564,7 @@ BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
*/ */
BOOL WINAPI IsWindowEnabled(HWND hWnd) BOOL WINAPI IsWindowEnabled(HWND hWnd)
{ {
WND * wndPtr; return !(GetWindowLongW( hWnd, GWL_STYLE ) & WS_DISABLED);
BOOL retvalue;
if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
retvalue = !(wndPtr->dwStyle & WS_DISABLED);
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
} }
@ -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; WND *wndPtr;
DWORD dwStyle;
HWND retvalue; HWND retvalue;
BOOL was_visible;
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;
}
if (USER_Driver.pSetParent) if (USER_Driver.pSetParent)
return USER_Driver.pSetParent( hwnd, parent ); 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 /* Windows hides the window first, then shows it again
* including the WM_SHOWWINDOW messages and all */ * 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 */ retvalue = wndPtr->parent; /* old parent */
if (parent != retvalue) if (parent != retvalue)
@ -2150,28 +2175,55 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent )
if (parent != GetDesktopWindow()) /* a child window */ if (parent != GetDesktopWindow()) /* a child window */
{ {
if (!(dwStyle & WS_CHILD)) if (!(wndPtr->dwStyle & WS_CHILD))
{ {
HMENU menu = (HMENU)SetWindowLongW( hwnd, GWL_ID, 0 ); HMENU menu = (HMENU)SetWindowLongW( hwnd, GWL_ID, 0 );
if (menu) DestroyMenu( menu ); if (menu) DestroyMenu( menu );
} }
} }
} }
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleasePtr( wndPtr );
/* SetParent additionally needs to make hwnd the topmost window /* SetParent additionally needs to make hwnd the topmost window
in the x-order and send the expected WM_WINDOWPOSCHANGING and in the x-order and send the expected WM_WINDOWPOSCHANGING and
WM_WINDOWPOSCHANGED notification messages. WM_WINDOWPOSCHANGED notification messages.
*/ */
SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0, SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE| SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) );
((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
/* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
* for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */ * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
return retvalue; 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.@) * IsChild (USER32.@)
*/ */

View File

@ -11,6 +11,7 @@
#include "wingdi.h" #include "wingdi.h"
#include "winerror.h" #include "winerror.h"
#include "wine/winuser16.h" #include "wine/winuser16.h"
#include "wine/server.h"
#include "controls.h" #include "controls.h"
#include "user.h" #include "user.h"
#include "region.h" #include "region.h"
@ -83,7 +84,9 @@ void WINPOS_CheckInternalPos( HWND hwnd )
{ {
LPINTERNALPOS lpPos; LPINTERNALPOS lpPos;
MESSAGEQUEUE *pMsgQ = 0; 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 ); lpPos = (LPINTERNALPOS) GetPropA( hwnd, atomInternalPos );
@ -92,7 +95,7 @@ void WINPOS_CheckInternalPos( HWND hwnd )
if ( !pMsgQ ) if ( !pMsgQ )
{ {
WARN("\tMessage queue not found. Exiting!\n" ); WARN("\tMessage queue not found. Exiting!\n" );
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleasePtr( wndPtr );
return; return;
} }
@ -112,8 +115,7 @@ void WINPOS_CheckInternalPos( HWND hwnd )
} }
QUEUE_Unlock( pMsgQ ); QUEUE_Unlock( pMsgQ );
WIN_ReleaseWndPtr( wndPtr ); WIN_ReleasePtr( wndPtr );
return;
} }
/*********************************************************************** /***********************************************************************
@ -171,14 +173,39 @@ void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
*/ */
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; if (!wndPtr) return FALSE;
*rect = wndPtr->rectWindow;
WIN_ReleaseWndPtr(wndPtr); if (wndPtr != WND_OTHER_PROCESS)
MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 ); {
TRACE("hwnd %04x (%d,%d)-(%d,%d)\n", *rect = wndPtr->rectWindow;
hwnd, rect->left, rect->top, rect->right, rect->bottom); WIN_ReleasePtr( wndPtr );
return TRUE; 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;
} }
@ -248,17 +275,33 @@ int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
*/ */
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; rect->left = rect->top = rect->right = rect->bottom = 0;
if (!wndPtr) return FALSE; if (!wndPtr) return FALSE;
rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
WIN_ReleaseWndPtr(wndPtr); if (wndPtr != WND_OTHER_PROCESS)
TRACE("hwnd %04x (%d,%d)-(%d,%d)\n", {
hwnd, rect->left, rect->top, rect->right, rect->bottom); rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
return TRUE; 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 */ 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 window is minimized or disabled, return at once */
if (wndPtr->dwStyle & WS_MINIMIZE) if (wndPtr->dwStyle & WS_MINIMIZE)
{ {
@ -401,7 +442,10 @@ HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
xy.y -= wndScope->rectClient.top; xy.y -= wndScope->rectClient.top;
WIN_ReleaseWndPtr( wndScope ); WIN_ReleaseWndPtr( wndScope );
if ((ret = find_child_from_point( hwndScope, xy, hittest, MAKELONG( pt.x, pt.y ) ))) if ((ret = find_child_from_point( hwndScope, xy, hittest, MAKELONG( pt.x, pt.y ) )))
{
TRACE( "found child %x\n", ret );
return ret; return ret;
}
} }
else WIN_ReleaseWndPtr( wndScope ); else WIN_ReleaseWndPtr( wndScope );
@ -409,15 +453,18 @@ HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
if (!WIN_IsCurrentThread( hwndScope )) if (!WIN_IsCurrentThread( hwndScope ))
{ {
*hittest = HTCLIENT; *hittest = HTCLIENT;
TRACE( "returning %x\n", hwndScope );
return hwndScope; return hwndScope;
} }
res = SendMessageA( hwndScope, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y ) ); res = SendMessageA( hwndScope, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y ) );
if (res != HTTRANSPARENT) if (res != HTTRANSPARENT)
{ {
*hittest = res; /* Found the window */ *hittest = res; /* Found the window */
TRACE( "returning %x\n", hwndScope );
return hwndScope; return hwndScope;
} }
*hittest = HTNOWHERE; *hittest = HTNOWHERE;
TRACE( "nothing found\n" );
return 0; 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 * Calculate the offset between the origin of the two windows. Used
* to implement MapWindowPoints. * to implement MapWindowPoints.
*/ */
static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, POINT *offset )
POINT *offset )
{ {
WND * wndPtr = 0; WND * wndPtr;
HWND *list;
int i;
offset->x = offset->y = 0; 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 (hwndFrom)
{ {
if (!(wndPtr = WIN_FindWndPtr( hwndFrom ))) HWND hwnd = hwndFrom;
while (hwnd)
{ {
ERR("bad hwndFrom = %04x\n",hwndFrom); if (hwnd == hwndTo) return;
return; if (!(wndPtr = WIN_GetPtr( hwnd )))
}
if ((list = WIN_ListParents( hwndFrom )))
{
for (i = 0; list[i]; i++)
{ {
offset->x += wndPtr->rectClient.left; ERR( "bad hwndFrom = %04x\n", hwnd );
offset->y += wndPtr->rectClient.top; return;
WIN_ReleaseWndPtr( wndPtr );
if (!(wndPtr = WIN_FindWndPtr( list[i] ))) break;
} }
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 (hwndTo)
{ {
if (!(wndPtr = WIN_FindWndPtr( hwndTo ))) HWND hwnd = hwndTo;
while (hwnd)
{ {
ERR("bad hwndTo = %04x\n", hwndTo ); if (!(wndPtr = WIN_GetPtr( hwnd )))
return;
}
if ((list = WIN_ListParents( hwndTo )))
{
for (i = 0; list[i]; i++)
{ {
offset->x -= wndPtr->rectClient.left; ERR( "bad hwndTo = %04x\n", hwnd );
offset->y -= wndPtr->rectClient.top; return;
WIN_ReleaseWndPtr( wndPtr );
if (!(wndPtr = WIN_FindWndPtr( list[i] ))) break;
} }
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.@) * MapWindowPoints (USER32.@)
*/ */
INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, UINT count )
LPPOINT lppt, UINT count )
{ {
POINT offset; POINT offset;
WINPOS_GetWinOffset( WIN_GetFullHandle(hwndFrom), WIN_GetFullHandle(hwndTo), &offset ); WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
while (count--) while (count--)
{ {
lppt->x += offset.x; lppt->x += offset.x;
@ -581,12 +635,7 @@ INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo,
*/ */
BOOL WINAPI IsIconic(HWND hWnd) BOOL WINAPI IsIconic(HWND hWnd)
{ {
BOOL retvalue; return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MINIMIZE) != 0;
WND * wndPtr = WIN_FindWndPtr(hWnd);
if (wndPtr == NULL) return FALSE;
retvalue = (wndPtr->dwStyle & WS_MINIMIZE) != 0;
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
} }
@ -595,12 +644,7 @@ BOOL WINAPI IsIconic(HWND hWnd)
*/ */
BOOL WINAPI IsZoomed(HWND hWnd) BOOL WINAPI IsZoomed(HWND hWnd)
{ {
BOOL retvalue; return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MAXIMIZE) != 0;
WND * wndPtr = WIN_FindWndPtr(hWnd);
if (wndPtr == NULL) return FALSE;
retvalue = (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
} }
@ -780,8 +824,7 @@ BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
/*********************************************************************** /***********************************************************************
* WINPOS_InitInternalPos * WINPOS_InitInternalPos
*/ */
static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt, static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt, const RECT *restoreRect )
LPRECT restoreRect )
{ {
LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( wnd->hwndSelf, LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( wnd->hwndSelf,
atomInternalPos ); atomInternalPos );
@ -948,7 +991,11 @@ BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
*/ */
BOOL WINAPI ShowWindow( 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 WINPOS_ActivateOtherWindow(HWND hwnd)
{ {
BOOL bRet = 0; BOOL bRet = 0;
WND *pWnd;
HWND hwndActive = 0; HWND hwndActive = 0;
HWND hwndTo = 0; HWND hwndTo = 0;
HWND owner; HWND owner;
@ -1376,21 +1422,16 @@ BOOL WINPOS_ActivateOtherWindow(HWND hwnd)
} }
} }
pWnd = WIN_FindWndPtr( hwnd ); if (!(hwnd = WIN_IsCurrentThread( hwnd ))) return 0;
hwnd = pWnd->hwndSelf;
if( hwnd == hwndPrevActive ) if( hwnd == hwndPrevActive )
hwndPrevActive = 0; hwndPrevActive = 0;
if( hwndActive != hwnd && if( hwndActive != hwnd && (hwndActive || USER_IsExitingThread( GetCurrentThreadId() )))
( hwndActive || QUEUE_IsExitingQueue(pWnd->hmemTaskQ)) )
{
WIN_ReleaseWndPtr( pWnd );
return 0; return 0;
}
owner = GetWindow( hwnd, GW_OWNER ); if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_POPUP) ||
if( !(pWnd->dwStyle & WS_POPUP) || !owner || !(owner = GetWindow( hwnd, GW_OWNER )) ||
!WINPOS_CanActivate((hwndTo = GetAncestor( owner, GA_ROOT ))) ) !WINPOS_CanActivate((hwndTo = GetAncestor( owner, GA_ROOT ))) )
{ {
HWND tmp = GetAncestor( hwnd, GA_ROOT ); HWND tmp = GetAncestor( hwnd, GA_ROOT );
@ -1403,7 +1444,6 @@ BOOL WINPOS_ActivateOtherWindow(HWND hwnd)
if( !hwndTo ) break; if( !hwndTo ) break;
} }
} }
WIN_ReleaseWndPtr( pWnd );
bRet = WINPOS_SetActiveWindow( hwndTo, FALSE, TRUE ); 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)&params );
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 * WINPOS_HandleWindowPosChanging16
* *
@ -1557,7 +1558,8 @@ BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
winpos.cx = cx; winpos.cx = cx;
winpos.cy = cy; winpos.cy = cy;
winpos.flags = flags; 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; DWP *pDWP;
int i; int i;
HDWP newhdwp = hdwp,retvalue; HDWP newhdwp = hdwp,retvalue;
/* HWND parent; */
WND *pWnd;
hwnd = WIN_GetFullHandle( hwnd ); hwnd = WIN_GetFullHandle( hwnd );
if (hwnd == GetDesktopWindow()) return 0; if (hwnd == GetDesktopWindow()) return 0;
if (!(pDWP = USER_HEAP_LIN_ADDR( hdwp ))) return 0; if (!(pDWP = USER_HEAP_LIN_ADDR( hdwp ))) return 0;
if (!(pWnd = WIN_FindWndPtr( hwnd ))) return 0; USER_Lock();
/* 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
for (i = 0; i < pDWP->actualCount; i++) for (i = 0; i < pDWP->actualCount; i++)
{ {
@ -1676,7 +1660,7 @@ HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
pDWP->actualCount++; pDWP->actualCount++;
retvalue = newhdwp; retvalue = newhdwp;
END: END:
WIN_ReleaseWndPtr(pWnd); USER_Unlock();
return retvalue; return retvalue;
} }

View File

@ -1200,7 +1200,6 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
LPDRAGINFO16 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo); LPDRAGINFO16 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
SEGPTR spDragInfo = K32WOWGlobalLock16(hDragInfo); SEGPTR spDragInfo = K32WOWGlobalLock16(hDragInfo);
Window w_aux_root, w_aux_child; Window w_aux_root, w_aux_child;
WND* pDropWnd;
WND* pWnd; WND* pWnd;
if( !lpDragInfo || !spDragInfo ) return; if( !lpDragInfo || !spDragInfo ) return;
@ -1224,76 +1223,73 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
bAccept = DRAG_QueryUpdate( hWnd, spDragInfo, TRUE ); bAccept = DRAG_QueryUpdate( hWnd, spDragInfo, TRUE );
x = lpDragInfo->pt.x; y = lpDragInfo->pt.y; x = lpDragInfo->pt.x; y = lpDragInfo->pt.y;
} }
pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope );
WIN_ReleaseWndPtr(pWnd); WIN_ReleaseWndPtr(pWnd);
GlobalFree16( hDragInfo ); GlobalFree16( hDragInfo );
if( bAccept ) 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 */
{ {
TSXGetWindowProperty( event->display, DefaultRootWindow(event->display), signed char *p = (signed char*) p_data;
dndSelection, 0, 65535, FALSE, char *p_drop;
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 */ aux_long = 0;
{ while( *p ) /* calculate buffer size */
signed char *p = (signed char*) p_data; {
char *p_drop; 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 = 0; aux_long += sizeof(DROPFILES) + 1;
while( *p ) /* calculate buffer size */ hDrop = GlobalAlloc( GMEM_SHARE, aux_long );
{ lpDrop = (DROPFILES*)GlobalLock( hDrop );
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; if( lpDrop )
hDrop = GlobalAlloc( GMEM_SHARE, aux_long ); {
lpDrop = (DROPFILES*)GlobalLock( hDrop ); WND *pDropWnd = WIN_FindWndPtr( lpDragInfo->hScope );
lpDrop->pFiles = sizeof(DROPFILES);
if( lpDrop ) lpDrop->pt.x = x;
{ lpDrop->pt.y = y;
lpDrop->pFiles = sizeof(DROPFILES); lpDrop->fNC =
lpDrop->pt.x = x; ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) ||
lpDrop->pt.y = y; y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) ||
lpDrop->fNC = x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) || y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) || lpDrop->fWide = FALSE;
x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) || WIN_ReleaseWndPtr(pDropWnd);
y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) ); p_drop = (char *)(lpDrop + 1);
lpDrop->fWide = FALSE; p = p_data;
p_drop = (char *)(lpDrop + 1); while(*p)
p = p_data; {
while(*p) if( *p != -1 ) /* use only "good" entries */
{ {
if( *p != -1 ) /* use only "good" entries */ GetShortPathNameA( p, p_drop, 65535 );
{ p_drop += strlen( p_drop ) + 1;
GetShortPathNameA( p, p_drop, 65535 ); }
p_drop += strlen( p_drop ) + 1; p += strlen(p) + 1;
} }
p += strlen(p) + 1; *p_drop = '\0';
} PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
*p_drop = '\0'; }
PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L ); }
} }
} if( p_data ) TSXFree(p_data);
}
if( p_data ) TSXFree(p_data);
} /* WS_EX_ACCEPTFILES */
WIN_ReleaseWndPtr(pDropWnd);
} }
/********************************************************************** /**********************************************************************
@ -1306,8 +1302,6 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
*/ */
static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
{ {
WND *pDropWnd;
WND *pWnd;
unsigned long data_length; unsigned long data_length;
unsigned long aux_long, drop_len = 0; unsigned long aux_long, drop_len = 0;
unsigned char *p_data = NULL; /* property data */ unsigned char *p_data = NULL; /* property data */
@ -1322,14 +1316,7 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
Window w_aux; Window w_aux;
} u; /* unused */ } u; /* unused */
pWnd = WIN_FindWndPtr(hWnd); if (!(GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return;
if (!(pWnd->dwExStyle & WS_EX_ACCEPTFILES))
{
WIN_ReleaseWndPtr(pWnd);
return;
}
WIN_ReleaseWndPtr(pWnd);
TSXGetWindowProperty( event->display, DefaultRootWindow(event->display), TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
dndSelection, 0, 65535, FALSE, 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, TSXQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux,
&x, &y, &u.i, &u.i, &u.i); &x, &y, &u.i, &u.i, &u.i);
pDropWnd = WIN_FindWndPtr( hWnd );
drop_len += sizeof(DROPFILES) + 1; drop_len += sizeof(DROPFILES) + 1;
hDrop = GlobalAlloc( GMEM_SHARE, drop_len ); hDrop = GlobalAlloc( GMEM_SHARE, drop_len );
lpDrop = (DROPFILES *) GlobalLock( hDrop ); lpDrop = (DROPFILES *) GlobalLock( hDrop );
if( lpDrop ) { if( lpDrop ) {
WND *pDropWnd = WIN_FindWndPtr( hWnd );
lpDrop->pFiles = sizeof(DROPFILES); lpDrop->pFiles = sizeof(DROPFILES);
lpDrop->pt.x = (INT)x; lpDrop->pt.x = (INT)x;
lpDrop->pt.y = (INT)y; lpDrop->pt.y = (INT)y;
@ -1379,6 +1365,7 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) ); y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
lpDrop->fWide = FALSE; lpDrop->fWide = FALSE;
p_drop = (char*)(lpDrop + 1); p_drop = (char*)(lpDrop + 1);
WIN_ReleaseWndPtr(pDropWnd);
} }
/* create message content */ /* create message content */
@ -1411,7 +1398,6 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
GlobalUnlock(hDrop); GlobalUnlock(hDrop);
PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L ); PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
} }
WIN_ReleaseWndPtr(pDropWnd);
} }
if( p_data ) TSXFree(p_data); if( p_data ) TSXFree(p_data);
} }