Avoid returning an unlocked window pointer from WINPOS_WindowFromPoint.

Removed a few no longer used routines.
This commit is contained in:
Alexandre Julliard 2001-06-20 23:16:34 +00:00
parent 3ca9823941
commit ee8ab7af8a
8 changed files with 132 additions and 251 deletions

View File

@ -21,9 +21,6 @@ typedef struct tagQMSG
int type; int type;
MSG msg; MSG msg;
DWORD extraInfo; /* Only in 3.1 */ DWORD extraInfo; /* Only in 3.1 */
struct tagQMSG *nextMsg;
struct tagQMSG *prevMsg;
} QMSG; } QMSG;
#define QMSG_WIN16 0 #define QMSG_WIN16 0
@ -54,18 +51,10 @@ typedef struct tagMESSAGEQUEUE
HQUEUE16 self; /* Handle to self (was: reserved) */ HQUEUE16 self; /* Handle to self (was: reserved) */
TEB* teb; /* Thread owning queue */ TEB* teb; /* Thread owning queue */
HANDLE server_queue; /* Handle to server-side queue */ HANDLE server_queue; /* Handle to server-side queue */
CRITICAL_SECTION cSection; /* Queue access critical section */
DWORD magic; /* magic number should be QUEUE_MAGIC */ DWORD magic; /* magic number should be QUEUE_MAGIC */
DWORD lockCount; /* reference counter */ DWORD lockCount; /* reference counter */
QMSG* firstMsg; /* First message in linked list */
QMSG* lastMsg; /* Last message in linked list */
WORD wPostQMsg; /* PostQuitMessage flag */
WORD wExitCode; /* PostQuitMessage exit code */
WORD wPaintCount; /* Number of WM_PAINT needed */
DWORD GetMessageTimeVal; /* Value for GetMessageTime */ DWORD GetMessageTimeVal; /* Value for GetMessageTime */
DWORD GetMessagePosVal; /* Value for GetMessagePos */ DWORD GetMessagePosVal; /* Value for GetMessagePos */
DWORD GetMessageExtraInfoVal; /* Value for GetMessageExtraInfo */ DWORD GetMessageExtraInfoVal; /* Value for GetMessageExtraInfo */
@ -81,33 +70,22 @@ typedef struct tagMESSAGEQUEUE
#define QUEUE_MAGIC 0xD46E80AF #define QUEUE_MAGIC 0xD46E80AF
/* Per queue data management methods */ /* Per queue data management methods */
PERQUEUEDATA* PERQDATA_CreateInstance( void );
ULONG PERQDATA_Addref( PERQUEUEDATA* pQData );
ULONG PERQDATA_Release( PERQUEUEDATA* pQData );
HWND PERQDATA_GetFocusWnd( PERQUEUEDATA *pQData ); HWND PERQDATA_GetFocusWnd( PERQUEUEDATA *pQData );
HWND PERQDATA_SetFocusWnd( PERQUEUEDATA *pQData, HWND hWndFocus ); HWND PERQDATA_SetFocusWnd( PERQUEUEDATA *pQData, HWND hWndFocus );
HWND PERQDATA_GetActiveWnd( PERQUEUEDATA *pQData ); HWND PERQDATA_GetActiveWnd( PERQUEUEDATA *pQData );
HWND PERQDATA_SetActiveWnd( PERQUEUEDATA *pQData, HWND hWndActive ); HWND PERQDATA_SetActiveWnd( PERQUEUEDATA *pQData, HWND hWndActive );
HWND PERQDATA_GetCaptureWnd( PERQUEUEDATA *pQData ); HWND PERQDATA_GetCaptureWnd( INT *hittest );
HWND PERQDATA_SetCaptureWnd( PERQUEUEDATA *pQData, HWND hWndCapture ); HWND PERQDATA_SetCaptureWnd( HWND hWndCapture, INT hittest );
INT16 PERQDATA_GetCaptureInfo( PERQUEUEDATA *pQData );
INT16 PERQDATA_SetCaptureInfo( PERQUEUEDATA *pQData, INT16 nCaptureHT );
/* Message queue management methods */ /* Message queue management methods */
extern MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue ); extern MESSAGEQUEUE *QUEUE_Lock( HQUEUE16 hQueue );
extern void QUEUE_Unlock( MESSAGEQUEUE *queue ); extern void QUEUE_Unlock( MESSAGEQUEUE *queue );
extern void QUEUE_DumpQueue( HQUEUE16 hQueue );
extern BOOL QUEUE_IsExitingQueue( HQUEUE16 hQueue ); extern BOOL QUEUE_IsExitingQueue( HQUEUE16 hQueue );
extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue ); extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue );
extern void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD set, WORD clear );
extern void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit );
extern int QUEUE_WaitBits( WORD bits, DWORD timeout ); extern int QUEUE_WaitBits( WORD bits, DWORD timeout );
extern void QUEUE_IncPaintCount( HQUEUE16 hQueue );
extern void QUEUE_DecPaintCount( HQUEUE16 hQueue );
extern BOOL QUEUE_DeleteMsgQueue( HQUEUE16 hQueue ); extern BOOL QUEUE_DeleteMsgQueue( HQUEUE16 hQueue );
extern HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue ); extern HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue );
extern BOOL QUEUE_FindMsg( HWND hwnd, UINT first, UINT last, BOOL remove, QMSG *msg ); extern BOOL QUEUE_FindMsg( HWND hwnd, UINT first, UINT last, BOOL remove, QMSG *msg );
extern void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, QMSG *qmsg );
extern void QUEUE_CleanupWindow( HWND hwnd ); extern void QUEUE_CleanupWindow( HWND hwnd );
extern HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags ); extern HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags );

View File

@ -37,7 +37,7 @@ extern LONG WINPOS_SendNCCalcSize(HWND hwnd, BOOL calcValidRect,
RECT *newClientRect ); RECT *newClientRect );
extern LONG WINPOS_HandleWindowPosChanging16(struct tagWND *wndPtr, struct tagWINDOWPOS16 *winpos); extern LONG WINPOS_HandleWindowPosChanging16(struct tagWND *wndPtr, struct tagWINDOWPOS16 *winpos);
extern LONG WINPOS_HandleWindowPosChanging(struct tagWND *wndPtr, WINDOWPOS *winpos); extern LONG WINPOS_HandleWindowPosChanging(struct tagWND *wndPtr, WINDOWPOS *winpos);
extern INT16 WINPOS_WindowFromPoint( struct tagWND* scopeWnd, POINT pt, struct tagWND **ppWnd ); extern HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest );
extern void WINPOS_CheckInternalPos( struct tagWND* wndPtr ); extern void WINPOS_CheckInternalPos( struct tagWND* wndPtr );
extern BOOL WINPOS_ActivateOtherWindow(struct tagWND* pWnd); extern BOOL WINPOS_ActivateOtherWindow(struct tagWND* pWnd);
extern BOOL WINPOS_CreateInternalPosAtom(void); extern BOOL WINPOS_CreateInternalPosAtom(void);

View File

@ -322,19 +322,18 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam,
break; break;
case WM_RBUTTONUP: case WM_RBUTTONUP:
if (wndPtr->hwndSelf == GetCapture())
{ {
/* release capture if we took it on WM_NCRBUTTONDOWN */ POINT pt;
ReleaseCapture();
} if (wndPtr->hwndSelf == GetCapture())
if ((wndPtr->flags & WIN_ISWIN32) || (TWEAK_WineLook > WIN31_LOOK)) /* release capture if we took it on WM_NCRBUTTONDOWN */
{ ReleaseCapture();
POINT pt;
pt.x = SLOWORD(lParam); pt.x = SLOWORD(lParam);
pt.y = SHIWORD(lParam); pt.y = SHIWORD(lParam);
ClientToScreen(wndPtr->hwndSelf, &pt); ClientToScreen(wndPtr->hwndSelf, &pt);
lParam = MAKELPARAM(pt.x, pt.y); pSendMessage( wndPtr->hwndSelf, WM_CONTEXTMENU,
pSendMessage( wndPtr->hwndSelf, WM_CONTEXTMENU, wndPtr->hwndSelf, lParam ); wndPtr->hwndSelf, MAKELPARAM(pt.x, pt.y) );
} }
break; break;

View File

@ -400,19 +400,11 @@ HWND EVENT_Capture(HWND hwnd, INT16 ht)
WND* wndPtr = 0; WND* wndPtr = 0;
INT16 captureHT = 0; INT16 captureHT = 0;
/* Get the messageQ for the current thread */ capturePrev = GetCapture();
if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
{
WARN_(win)("\tCurrent message queue not found. Exiting!\n" );
goto CLEANUP;
}
/* Get the current capture window from the perQ data of the current message Q */
capturePrev = PERQDATA_GetCaptureWnd( pCurMsgQ->pQData );
if (!hwnd) if (!hwnd)
{ {
captureWnd = 0L; captureWnd = 0;
captureHT = 0; captureHT = 0;
} }
else else
@ -426,6 +418,13 @@ HWND EVENT_Capture(HWND hwnd, INT16 ht)
} }
} }
/* Get the messageQ for the current thread */
if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
{
WARN_(win)("\tCurrent message queue not found. Exiting!\n" );
goto CLEANUP;
}
/* Update the perQ capture window and send messages */ /* Update the perQ capture window and send messages */
if( capturePrev != captureWnd ) if( capturePrev != captureWnd )
{ {
@ -446,17 +445,9 @@ HWND EVENT_Capture(HWND hwnd, INT16 ht)
goto CLEANUP; goto CLEANUP;
} }
PERQDATA_SetCaptureWnd( pCurMsgQ->pQData, captureWnd ); PERQDATA_SetCaptureWnd( captureWnd, captureHT );
PERQDATA_SetCaptureInfo( pCurMsgQ->pQData, captureHT ); if (capturePrev) SendMessageA( capturePrev, WM_CAPTURECHANGED, 0, hwnd );
if( capturePrev )
{
WND* xwndPtr = WIN_FindWndPtr( capturePrev );
if( xwndPtr && (xwndPtr->flags & WIN_ISWIN32) )
SendMessageA( capturePrev, WM_CAPTURECHANGED, 0L, hwnd);
WIN_ReleaseWndPtr(xwndPtr);
} }
}
CLEANUP: CLEANUP:
/* Unlock the queues before returning */ /* Unlock the queues before returning */
@ -510,21 +501,8 @@ HWND16 WINAPI GetCapture16(void)
*/ */
HWND WINAPI GetCapture(void) HWND WINAPI GetCapture(void)
{ {
MESSAGEQUEUE *pCurMsgQ = 0; INT hittest;
HWND hwndCapture = 0; return PERQDATA_GetCaptureWnd( &hittest );
/* Get the messageQ for the current thread */
if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
{
TRACE_(win)("GetCapture: Current message queue not found. Exiting!\n" );
return 0;
}
/* Get the current capture window from the perQ data of the current message Q */
hwndCapture = PERQDATA_GetCaptureWnd( pCurMsgQ->pQData );
QUEUE_Unlock( pCurMsgQ );
return hwndCapture;
} }
/********************************************************************** /**********************************************************************

View File

@ -302,28 +302,17 @@ static BOOL process_raw_mouse_message( MSG *msg, ULONG_PTR extra_info )
/* find the window to dispatch this mouse message to */ /* find the window to dispatch this mouse message to */
if (!(msg->hwnd = GetCapture())) hittest = HTCLIENT;
if (!(msg->hwnd = PERQDATA_GetCaptureWnd( &ht )))
{ {
/* If no capture HWND, find window which contains the mouse position. /* If no capture HWND, find window which contains the mouse position.
* Also find the position of the cursor hot spot (hittest) */ * Also find the position of the cursor hot spot (hittest) */
HWND hWndScope = (HWND)extra_info; HWND hWndScope = (HWND)extra_info;
WND *pWndScope = IsWindow(hWndScope) ? WIN_FindWndPtr(hWndScope) : WIN_GetDesktop();
WND *pWnd;
ht = hittest = WINPOS_WindowFromPoint( pWndScope, msg->pt, &pWnd ); if (!IsWindow(hWndScope)) hWndScope = 0;
msg->hwnd = pWnd ? pWnd->hwndSelf : GetDesktopWindow(); if (!(msg->hwnd = WINPOS_WindowFromPoint( hWndScope, msg->pt, &hittest )))
WIN_ReleaseWndPtr( pWndScope ); msg->hwnd = GetDesktopWindow();
} ht = hittest;
else
{
MESSAGEQUEUE *queue = QUEUE_Lock( GetFastQueue16() );
ht = hittest = HTCLIENT;
if (queue)
{
ht = PERQDATA_GetCaptureInfo( queue->pQData );
QUEUE_Unlock(queue);
}
} }
if (HOOK_IsHooked( WH_JOURNALRECORD )) if (HOOK_IsHooked( WH_JOURNALRECORD ))

View File

@ -23,7 +23,6 @@
DEFAULT_DEBUG_CHANNEL(msg); DEFAULT_DEBUG_CHANNEL(msg);
#define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
static HQUEUE16 hExitingQueue = 0; static HQUEUE16 hExitingQueue = 0;
static PERQUEUEDATA *pQDataWin16 = NULL; /* Global perQData for Win16 tasks */ static PERQUEUEDATA *pQDataWin16 = NULL; /* Global perQData for Win16 tasks */
@ -31,6 +30,49 @@ static PERQUEUEDATA *pQDataWin16 = NULL; /* Global perQData for Win16 tasks */
HQUEUE16 hActiveQueue = 0; HQUEUE16 hActiveQueue = 0;
/***********************************************************************
* PERQDATA_Addref
*
* Increment reference count for the PERQUEUEDATA instance
* Returns reference count for debugging purposes
*/
static void PERQDATA_Addref( PERQUEUEDATA *pQData )
{
assert(pQData != 0 );
TRACE_(msg)("(): current refcount %lu ...\n", pQData->ulRefCount);
InterlockedIncrement( &pQData->ulRefCount );
}
/***********************************************************************
* PERQDATA_Release
*
* Release a reference to a PERQUEUEDATA instance.
* Destroy the instance if no more references exist
* Returns reference count for debugging purposes
*/
static void PERQDATA_Release( PERQUEUEDATA *pQData )
{
assert(pQData != 0 );
TRACE_(msg)("(): current refcount %lu ...\n",
(LONG)pQData->ulRefCount );
if (!InterlockedDecrement( &pQData->ulRefCount ))
{
DeleteCriticalSection( &pQData->cSection );
TRACE_(msg)("(): deleting PERQUEUEDATA instance ...\n" );
/* Deleting our global 16 bit perQData? */
if ( pQData == pQDataWin16 ) pQDataWin16 = 0;
/* Free the PERQUEUEDATA instance */
HeapFree( GetProcessHeap(), 0, pQData );
}
}
/*********************************************************************** /***********************************************************************
* PERQDATA_CreateInstance * PERQDATA_CreateInstance
* *
@ -43,7 +85,7 @@ HQUEUE16 hActiveQueue = 0;
* We only store the current values for Active, Capture and focus windows * We only store the current values for Active, Capture and focus windows
* currently. * currently.
*/ */
PERQUEUEDATA * PERQDATA_CreateInstance( ) static PERQUEUEDATA * PERQDATA_CreateInstance(void)
{ {
PERQUEUEDATA *pQData; PERQUEUEDATA *pQData;
@ -87,61 +129,6 @@ PERQUEUEDATA * PERQDATA_CreateInstance( )
} }
/***********************************************************************
* PERQDATA_Addref
*
* Increment reference count for the PERQUEUEDATA instance
* Returns reference count for debugging purposes
*/
ULONG PERQDATA_Addref( PERQUEUEDATA *pQData )
{
assert(pQData != 0 );
TRACE_(msg)("(): current refcount %lu ...\n", pQData->ulRefCount);
EnterCriticalSection( &pQData->cSection );
++pQData->ulRefCount;
LeaveCriticalSection( &pQData->cSection );
return pQData->ulRefCount;
}
/***********************************************************************
* PERQDATA_Release
*
* Release a reference to a PERQUEUEDATA instance.
* Destroy the instance if no more references exist
* Returns reference count for debugging purposes
*/
ULONG PERQDATA_Release( PERQUEUEDATA *pQData )
{
assert(pQData != 0 );
TRACE_(msg)("(): current refcount %lu ...\n",
(LONG)pQData->ulRefCount );
EnterCriticalSection( &pQData->cSection );
if ( --pQData->ulRefCount == 0 )
{
LeaveCriticalSection( &pQData->cSection );
DeleteCriticalSection( &pQData->cSection );
TRACE_(msg)("(): deleting PERQUEUEDATA instance ...\n" );
/* Deleting our global 16 bit perQData? */
if ( pQData == pQDataWin16 )
pQDataWin16 = 0;
/* Free the PERQUEUEDATA instance */
HeapFree( GetProcessHeap(), 0, pQData );
return 0;
}
LeaveCriticalSection( &pQData->cSection );
return pQData->ulRefCount;
}
/*********************************************************************** /***********************************************************************
* PERQDATA_GetFocusWnd * PERQDATA_GetFocusWnd
* *
@ -221,15 +208,21 @@ HWND PERQDATA_SetActiveWnd( PERQUEUEDATA *pQData, HWND hWndActive )
* *
* Get the capture hwnd member in a threadsafe manner * Get the capture hwnd member in a threadsafe manner
*/ */
HWND PERQDATA_GetCaptureWnd( PERQUEUEDATA *pQData ) HWND PERQDATA_GetCaptureWnd( INT *hittest )
{ {
MESSAGEQUEUE *queue;
PERQUEUEDATA *pQData;
HWND hWndCapture; HWND hWndCapture;
assert(pQData != 0 );
if (!(queue = QUEUE_Lock( GetFastQueue16() ))) return 0;
pQData = queue->pQData;
EnterCriticalSection( &pQData->cSection ); EnterCriticalSection( &pQData->cSection );
hWndCapture = pQData->hWndCapture; hWndCapture = pQData->hWndCapture;
*hittest = pQData->nCaptureHT;
LeaveCriticalSection( &pQData->cSection ); LeaveCriticalSection( &pQData->cSection );
QUEUE_Unlock( queue );
return hWndCapture; return hWndCapture;
} }
@ -239,56 +232,26 @@ HWND PERQDATA_GetCaptureWnd( PERQUEUEDATA *pQData )
* *
* Set the capture hwnd member in a threadsafe manner * Set the capture hwnd member in a threadsafe manner
*/ */
HWND PERQDATA_SetCaptureWnd( PERQUEUEDATA *pQData, HWND hWndCapture ) HWND PERQDATA_SetCaptureWnd( HWND hWndCapture, INT hittest )
{ {
MESSAGEQUEUE *queue;
PERQUEUEDATA *pQData;
HWND hWndCapturePrv; HWND hWndCapturePrv;
assert(pQData != 0 );
if (!(queue = QUEUE_Lock( GetFastQueue16() ))) return 0;
pQData = queue->pQData;
EnterCriticalSection( &pQData->cSection ); EnterCriticalSection( &pQData->cSection );
hWndCapturePrv = pQData->hWndCapture; hWndCapturePrv = pQData->hWndCapture;
pQData->hWndCapture = hWndCapture; pQData->hWndCapture = hWndCapture;
pQData->nCaptureHT = hittest;
LeaveCriticalSection( &pQData->cSection ); LeaveCriticalSection( &pQData->cSection );
QUEUE_Unlock( queue );
return hWndCapturePrv; return hWndCapturePrv;
} }
/***********************************************************************
* PERQDATA_GetCaptureInfo
*
* Get the capture info member in a threadsafe manner
*/
INT16 PERQDATA_GetCaptureInfo( PERQUEUEDATA *pQData )
{
INT16 nCaptureHT;
assert(pQData != 0 );
EnterCriticalSection( &pQData->cSection );
nCaptureHT = pQData->nCaptureHT;
LeaveCriticalSection( &pQData->cSection );
return nCaptureHT;
}
/***********************************************************************
* PERQDATA_SetCaptureInfo
*
* Set the capture info member in a threadsafe manner
*/
INT16 PERQDATA_SetCaptureInfo( PERQUEUEDATA *pQData, INT16 nCaptureHT )
{
INT16 nCaptureHTPrv;
assert(pQData != 0 );
EnterCriticalSection( &pQData->cSection );
nCaptureHTPrv = pQData->nCaptureHT;
pQData->nCaptureHT = nCaptureHT;
LeaveCriticalSection( &pQData->cSection );
return nCaptureHTPrv;
}
/*********************************************************************** /***********************************************************************
* QUEUE_Lock * QUEUE_Lock
@ -330,7 +293,6 @@ void QUEUE_Unlock( MESSAGEQUEUE *queue )
if ( --queue->lockCount == 0 ) if ( --queue->lockCount == 0 )
{ {
DeleteCriticalSection ( &queue->cSection );
if (queue->server_queue) if (queue->server_queue)
CloseHandle( queue->server_queue ); CloseHandle( queue->server_queue );
GlobalFree16( queue->self ); GlobalFree16( queue->self );
@ -341,36 +303,6 @@ void QUEUE_Unlock( MESSAGEQUEUE *queue )
} }
/***********************************************************************
* QUEUE_DumpQueue
*/
void QUEUE_DumpQueue( HQUEUE16 hQueue )
{
MESSAGEQUEUE *pq;
if (!(pq = QUEUE_Lock( hQueue )) )
{
WARN_(msg)("%04x is not a queue handle\n", hQueue );
return;
}
EnterCriticalSection( &pq->cSection );
DPRINTF( "thread: %10p Intertask SendMessage:\n"
"firstMsg: %8p lastMsg: %8p\n"
"lockCount: %7.4x\n"
"paints: %10.4x\n"
"hCurHook: %8.4x\n",
pq->teb, pq->firstMsg, pq->lastMsg,
(unsigned)pq->lockCount, pq->wPaintCount,
pq->hCurHook);
LeaveCriticalSection( &pq->cSection );
QUEUE_Unlock( pq );
}
/*********************************************************************** /***********************************************************************
* QUEUE_IsExitingQueue * QUEUE_IsExitingQueue
*/ */
@ -428,10 +360,6 @@ static HQUEUE16 QUEUE_CreateMsgQueue( BOOL16 bCreatePerQData )
} }
msgQueue->self = hQueue; msgQueue->self = hQueue;
InitializeCriticalSection( &msgQueue->cSection );
MakeCriticalSectionGlobal( &msgQueue->cSection );
msgQueue->lockCount = 1; msgQueue->lockCount = 1;
msgQueue->magic = QUEUE_MAGIC; msgQueue->magic = QUEUE_MAGIC;
@ -465,6 +393,7 @@ BOOL QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
msgQueue->magic = 0; msgQueue->magic = 0;
if( hActiveQueue == hQueue ) hActiveQueue = 0; if( hActiveQueue == hQueue ) hActiveQueue = 0;
if (hExitingQueue == hQueue) hExitingQueue = 0;
HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */ HeapLock( GetProcessHeap() ); /* FIXME: a bit overkill */

View File

@ -364,20 +364,23 @@ BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
* *
* Find the window and hittest for a given point. * Find the window and hittest for a given point.
*/ */
INT16 WINPOS_WindowFromPoint( WND* wndScope, POINT pt, WND **ppWnd ) HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
{ {
WND *wndPtr; WND *wndScope, *wndPtr, *wndTmp;
INT16 hittest = HTERROR; HWND hwnd_ret = 0;
INT16 retvalue;
POINT xy = pt; POINT xy = pt;
TRACE("scope %04x %ld,%ld\n", wndScope->hwndSelf, pt.x, pt.y); TRACE("scope %04x %ld,%ld\n", hwndScope, pt.x, pt.y);
*ppWnd = NULL;
if (!hwndScope) hwndScope = GetDesktopWindow();
if (!(wndScope = WIN_FindWndPtr( hwndScope ))) return 0;
*hittest = HTERROR;
wndPtr = WIN_LockWndPtr(wndScope->child); wndPtr = WIN_LockWndPtr(wndScope->child);
if( wndScope->dwStyle & WS_DISABLED ) if( wndScope->dwStyle & WS_DISABLED )
{ {
retvalue = HTERROR; *hittest = HTERROR;
goto end; goto end;
} }
@ -413,17 +416,17 @@ INT16 WINPOS_WindowFromPoint( WND* wndScope, POINT pt, WND **ppWnd )
(xy.y < wndPtr->rectWindow.bottom)))) (xy.y < wndPtr->rectWindow.bottom))))
{ {
TRACE("%ld,%ld is inside %04x\n", xy.x, xy.y, wndPtr->hwndSelf); TRACE("%ld,%ld is inside %04x\n", xy.x, xy.y, wndPtr->hwndSelf);
*ppWnd = wndPtr; /* Got a suitable window */ hwnd_ret = wndPtr->hwndSelf; /* Got a suitable window */
/* If window is minimized or disabled, return at once */ /* If window is minimized or disabled, return at once */
if (wndPtr->dwStyle & WS_MINIMIZE) if (wndPtr->dwStyle & WS_MINIMIZE)
{ {
retvalue = HTCAPTION; *hittest = HTCAPTION;
goto end; goto end;
} }
if (wndPtr->dwStyle & WS_DISABLED) if (wndPtr->dwStyle & WS_DISABLED)
{ {
retvalue = HTERROR; *hittest = HTERROR;
goto end; goto end;
} }
@ -445,40 +448,43 @@ INT16 WINPOS_WindowFromPoint( WND* wndScope, POINT pt, WND **ppWnd )
hittest: hittest:
/* If nothing found, try the scope window */ /* If nothing found, try the scope window */
if (!*ppWnd) *ppWnd = wndScope; if (!hwnd_ret) hwnd_ret = hwndScope;
/* Send the WM_NCHITTEST message (only if to the same task) */ /* Send the WM_NCHITTEST message (only if to the same task) */
if ((*ppWnd)->hmemTaskQ == GetFastQueue16()) if (GetWindowThreadProcessId( hwnd_ret, NULL ) == GetCurrentThreadId())
{ {
hittest = SendMessageA( (*ppWnd)->hwndSelf, WM_NCHITTEST, INT res = SendMessageA( hwnd_ret, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y ) );
0, MAKELONG( pt.x, pt.y ) ); if (res != HTTRANSPARENT)
if (hittest != HTTRANSPARENT)
{ {
retvalue = hittest; /* Found the window */ *hittest = res; /* Found the window */
goto end; goto end;
} }
} }
else else
{ {
retvalue = HTCLIENT; *hittest = HTCLIENT;
goto end; goto end;
} }
if (!(wndTmp = WIN_FindWndPtr( hwnd_ret ))) break;
/* If no children found in last search, make point relative to parent */ /* If no children found in last search, make point relative to parent */
if (!wndPtr) if (!wndPtr)
{ {
xy.x += (*ppWnd)->rectClient.left; xy.x += wndTmp->rectClient.left;
xy.y += (*ppWnd)->rectClient.top; xy.y += wndTmp->rectClient.top;
} }
/* Restart the search from the next sibling */ /* Restart the search from the next sibling */
WIN_UpdateWndPtr(&wndPtr,(*ppWnd)->next); WIN_UpdateWndPtr(&wndPtr,wndTmp->next);
*ppWnd = (*ppWnd)->parent; hwnd_ret = wndTmp->parent ? wndTmp->parent->hwndSelf : 0;
WIN_ReleaseWndPtr( wndTmp );
} }
end: end:
WIN_ReleaseWndPtr(wndPtr); WIN_ReleaseWndPtr(wndPtr);
return retvalue; WIN_ReleaseWndPtr(wndScope);
return hwnd_ret;
} }
@ -499,10 +505,8 @@ HWND16 WINAPI WindowFromPoint16( POINT16 pt )
*/ */
HWND WINAPI WindowFromPoint( POINT pt ) HWND WINAPI WindowFromPoint( POINT pt )
{ {
WND *pWnd; INT hittest;
WINPOS_WindowFromPoint( WIN_GetDesktop(), pt, &pWnd ); return WINPOS_WindowFromPoint( 0, pt, &hittest );
WIN_ReleaseDesktop();
return (HWND)pWnd->hwndSelf;
} }
@ -1577,13 +1581,13 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
if ((list = WIN_BuildWinArray( pDesktop, 0, NULL ))) if ((list = WIN_BuildWinArray( pDesktop, 0, NULL )))
{ {
DWORD new_thread = GetWindowThreadProcessId( hwndActive, NULL );
for (ppWnd = list; *ppWnd; ppWnd++) for (ppWnd = list; *ppWnd; ppWnd++)
{ {
if (!IsWindow( (*ppWnd)->hwndSelf )) continue; if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
if ((*ppWnd)->hmemTaskQ == hOldActiveQueue) if ((*ppWnd)->hmemTaskQ == hOldActiveQueue)
SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP, SendMessageW( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP, 0, new_thread );
0, QUEUE_GetQueueTask(hNewActiveQueue) );
} }
WIN_ReleaseWinArray(list); WIN_ReleaseWinArray(list);
} }
@ -1592,13 +1596,13 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus)
if ((list = WIN_BuildWinArray(pDesktop, 0, NULL ))) if ((list = WIN_BuildWinArray(pDesktop, 0, NULL )))
{ {
DWORD old_thread = GetWindowThreadProcessId( hwndPrevActive, NULL );
for (ppWnd = list; *ppWnd; ppWnd++) for (ppWnd = list; *ppWnd; ppWnd++)
{ {
if (!IsWindow( (*ppWnd)->hwndSelf )) continue; if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
if ((*ppWnd)->hmemTaskQ == hNewActiveQueue) if ((*ppWnd)->hmemTaskQ == hNewActiveQueue)
SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP, SendMessageW( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP, 1, old_thread );
1, QUEUE_GetQueueTask( hOldActiveQueue ) );
} }
WIN_ReleaseWinArray(list); WIN_ReleaseWinArray(list);
} }

View File

@ -2018,7 +2018,11 @@ INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
case WM_WININICHANGE: case WM_WININICHANGE:
FIXME_(msg)("message %04x needs translation\n", msg32 ); FIXME_(msg)("message %04x needs translation\n", msg32 );
return -1; return -1;
case WM_SIZING: /* should not be send to 16-bit apps */ /* following messages should not be sent to 16-bit apps */
case WM_SIZING:
case WM_CAPTURECHANGED:
case WM_STYLECHANGING:
case WM_STYLECHANGED:
return -1; return -1;
default: /* No translation needed */ default: /* No translation needed */
return 0; return 0;