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