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.
diff --git a/controls/icontitle.c b/controls/icontitle.c
index c048092..f3f62c4 100644
--- a/controls/icontitle.c
+++ b/controls/icontitle.c
@@ -43,7 +43,6 @@
*/
HWND ICONTITLE_Create( HWND owner )
{
- WND* wndPtr;
HWND hWnd;
HINSTANCE instance = GetWindowLongA( owner, GWL_HINSTANCE );
LONG style = WS_CLIPSIBLINGS;
@@ -57,10 +56,9 @@
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 7cf4cec..d375c29 100644
--- a/dlls/ttydrv/wnd.c
+++ b/dlls/ttydrv/wnd.c
@@ -566,9 +566,36 @@
/* 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 @@
/* 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 8c59896..04cd9ab 100644
--- a/dlls/user/message.c
+++ b/dlls/user/message.c
@@ -533,6 +533,10 @@
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 @@
break;
case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED:
+ case WM_WINE_SETWINDOWPOS:
minsize = sizeof(WINDOWPOS);
break;
case WM_COPYDATA:
@@ -1073,6 +1078,30 @@
/***********************************************************************
+ * 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 a window procedure and the corresponding hooks.
@@ -1082,7 +1111,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
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 c16bb6c..a4fa027 100644
--- a/dlls/user/user_main.c
+++ b/dlls/user/user_main.c
@@ -34,8 +34,10 @@
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 @@
/**********************************************************************
- * 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 @@
CURSORICON_FreeModuleIcons( hModule );
}
}
+ exiting_thread_id = 0;
}
diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c
index b9023c7..380912e 100644
--- a/dlls/x11drv/window.c
+++ b/dlls/x11drv/window.c
@@ -872,7 +872,7 @@
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 @@
{
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 @@
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 @@
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 ba7e4fa..5409293 100644
--- a/dlls/x11drv/winpos.c
+++ b/dlls/x11drv/winpos.c
@@ -523,7 +523,7 @@
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 @@
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 @@
/* 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 @@
/* 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 @@
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 @@
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;
+ }
- done:
+ /* Restore to normal position */
+
+ *rect = wpl.rcNormalPosition;
+ rect->right -= rect->left;
+ rect->bottom -= rect->top;
+
+ break;
+ }
+
WIN_ReleaseWndPtr( wndPtr );
return swpFlags;
}
diff --git a/include/queue.h b/include/queue.h
index baf84ff..394e34f 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -69,8 +69,6 @@
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 6b9dd35..b1aab08 100644
--- a/include/user.h
+++ b/include/user.h
@@ -35,7 +35,14 @@
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_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 dcd7ed0..81c3df7 100644
--- a/include/win.h
+++ b/include/win.h
@@ -88,12 +88,16 @@
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 25f8948..0ca4a31 100644
--- a/include/winpos.h
+++ b/include/winpos.h
@@ -28,10 +28,6 @@
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 c8e1688..b6f6e66 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -144,11 +144,9 @@
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 @@
}
pDCE = pDCE->next;
}
-
- WIN_ReleaseWndPtr( pWnd );
+ WIN_ReleasePtr( pWnd );
}
@@ -359,14 +356,19 @@
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 @@
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 6c854fe..450d8af 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -306,11 +306,20 @@
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 @@
* 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 @@
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 0e788c2..1829d6c 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;
@@ -325,24 +324,6 @@
/***********************************************************************
- * QUEUE_IsExitingQueue
- */
-BOOL QUEUE_IsExitingQueue( HQUEUE16 hQueue )
-{
- return (hExitingQueue && (hQueue == hExitingQueue));
-}
-
-
-/***********************************************************************
- * QUEUE_SetExitingQueue
- */
-void QUEUE_SetExitingQueue( HQUEUE16 hQueue )
-{
- hExitingQueue = hQueue;
-}
-
-
-/***********************************************************************
* QUEUE_CreateMsgQueue
*
* Creates a message queue. Doesn't link it into queue list!
@@ -417,7 +398,6 @@
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 106a60c..970bf0e 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -175,6 +175,18 @@
}
+/*******************************************************************
+ * 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_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,19 +380,71 @@
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
*
* Find a window that needs repaint among the children of the specified window.
@@ -481,18 +553,28 @@
*
* 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 @@
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 @@
wndPtr->class = NULL;
wndPtr->dwMagic = 0; /* Mark it as invalid */
WIN_ReleaseWndPtr( wndPtr );
+ return 0;
}
/***********************************************************************
@@ -576,10 +659,10 @@
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 @@
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 @@
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 @@
INT wndExtra;
DWORD clsStyle;
WNDPROC winproc;
+ RECT rect;
DCE *dce;
BOOL unicode = (type == WIN_PROC_32W);
@@ -867,11 +949,8 @@
/* 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 @@
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 @@
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 @@
*/
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 @@
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 @@
/* 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 @@
*/
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 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 @@
/*****************************************************************
- * 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 @@
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 1969780..64e11fe 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 @@
{
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 @@
if ( !pMsgQ )
{
WARN("\tMessage queue not found. Exiting!\n" );
- WIN_ReleaseWndPtr( wndPtr );
+ WIN_ReleasePtr( wndPtr );
return;
}
@@ -112,8 +115,7 @@
}
QUEUE_Unlock( pMsgQ );
- WIN_ReleaseWndPtr( wndPtr );
- return;
+ WIN_ReleasePtr( wndPtr );
}
/***********************************************************************
@@ -169,16 +171,41 @@
/***********************************************************************
* 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 @@
/***********************************************************************
* 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 @@
}
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 @@
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 @@
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 @@
* 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 @@
/*******************************************************************
* 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 @@
*/
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 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 @@
/***********************************************************************
* 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 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 @@
BOOL WINPOS_ActivateOtherWindow(HWND hwnd)
{
BOOL bRet = 0;
- WND *pWnd;
HWND hwndActive = 0;
HWND hwndTo = 0;
HWND owner;
@@ -1376,21 +1422,16 @@
}
}
- 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 @@
if( !hwndTo ) break;
}
}
- WIN_ReleaseWndPtr( pWnd );
bRet = WINPOS_SetActiveWindow( hwndTo, FALSE, TRUE );
@@ -1452,45 +1492,6 @@
/***********************************************************************
- * 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
*
* Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
@@ -1557,7 +1558,8 @@
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 @@
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 @@
{
pDWP->winPos[i].x = x;
pDWP->winPos[i].y = y;
- }
+ }
if (!(flags & SWP_NOSIZE))
{
pDWP->winPos[i].cx = cx;
@@ -1676,7 +1660,7 @@
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 8eb9910..e567a7c 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -1200,7 +1200,6 @@
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 @@
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_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 @@
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 @@
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 @@
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 @@
GlobalUnlock(hDrop);
PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
}
- WIN_ReleaseWndPtr(pDropWnd);
}
if( p_data ) TSXFree(p_data);
}