- Fix wine post message test, corrected the peek message window selection.
- Add a check for dead windows and new message queue flags. 
- Other miscellaneous fix ups.

svn path=/trunk/; revision=51216
This commit is contained in:
James Tabor 2011-03-31 21:20:06 +00:00
parent 04afecea16
commit 951d604b0c
3 changed files with 103 additions and 42 deletions

View file

@ -78,12 +78,16 @@ typedef struct _USER_MESSAGE_QUEUE
HANDLE NewMessagesHandle;
/* Last time PeekMessage() was called. */
ULONG LastMsgRead;
/* Current window with focus (ie. receives keyboard input) for this queue. */
HWND FocusWindow;
/* Current active window for this queue. */
HWND ActiveWindow;
/* Current capture window for this queue. */
HWND CaptureWindow;
PWND spwndCapture;
/* Current window with focus (ie. receives keyboard input) for this queue. */
HWND FocusWindow;
PWND spwndFocus;
/* Current active window for this queue. */
HWND ActiveWindow;
PWND spwndActive;
PWND spwndActivePrev;
/* Current move/size window for this queue */
HWND MoveSize;
/* Current menu owner window for this queue */
@ -92,6 +96,8 @@ typedef struct _USER_MESSAGE_QUEUE
BYTE MenuState;
/* Caret information for this queue */
PTHRDCARETINFO CaretInfo;
/* Message Queue Flags */
DWORD QF_flags;
/* queue state tracking */
// Send list QS_SENDMESSAGE
@ -112,8 +118,28 @@ typedef struct _USER_MESSAGE_QUEUE
struct _DESKTOP *Desktop;
} USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
#define QF_UPDATEKEYSTATE 0x00000001
#define QF_FMENUSTATUSBREAK 0x00000004
#define QF_FMENUSTATUS 0x00000008
#define QF_FF10STATUS 0x00000010
#define QF_MOUSEMOVED 0x00000020 // See MouseMoved.
#define QF_ACTIVATIONCHANGE 0x00000040
#define QF_TABSWITCHING 0x00000080
#define QF_KEYSTATERESET 0x00000100
#define QF_INDESTROY 0x00000200
#define QF_LOCKNOREMOVE 0x00000400
#define QF_FOCUSNULLSINCEACTIVE 0x00000800
#define QF_DIALOGACTIVE 0x00004000
#define QF_EVENTDEACTIVATEREMOVED 0x00008000
#define QF_TRACKMOUSELEAVE 0x00020000
#define QF_TRACKMOUSEHOVER 0x00040000
#define QF_TRACKMOUSEFIRING 0x00080000
#define QF_CAPTURELOCKED 0x00100000
#define QF_ACTIVEWNDTRACKING 0x00200000
BOOL FASTCALL
MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue);
VOID CALLBACK HungAppSysTimerProc(HWND,UINT,UINT_PTR,DWORD);
NTSTATUS FASTCALL
co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam,

View file

@ -1233,6 +1233,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti->MessageQueue))
{
// FIXME - Set window hung and add to a list.
/* FIXME - Set a LastError? */
RETURN( FALSE);
}
@ -1258,7 +1259,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
}
while ((STATUS_TIMEOUT == Status) &&
(uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
!MsqIsHung(Window->head.pti->MessageQueue));
!MsqIsHung(Window->head.pti->MessageQueue)); // FIXME - Set window hung and add to a list.
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
@ -1348,7 +1349,13 @@ co_IntSendMessageNoWait(HWND hWnd,
&Result);
return Result;
}
/* MSDN:
If you send a message in the range below WM_USER to the asynchronous message
functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its
message parameters cannot include pointers. Otherwise, the operation will fail.
The functions will return before the receiving thread has had a chance to
process the message and the sender will free the memory before it is used.
*/
LRESULT FASTCALL
co_IntSendMessageWithCallBack( HWND hWnd,
UINT Msg,
@ -2014,24 +2021,23 @@ NtUserMessageCall( HWND hWnd,
UserEnterExclusive();
/* Validate input */
if (hWnd && (hWnd != INVALID_HANDLE_VALUE))
{
Window = UserGetWindowObject(hWnd);
if (!Window)
{
UserLeave();
return FALSE;
}
}
switch(dwType)
{
case FNID_DEFWINDOWPROC:
if (Window) UserRefObjectCo(Window, &Ref);
/* Validate input */
if (hWnd && (hWnd != INVALID_HANDLE_VALUE))
{
Window = UserGetWindowObject(hWnd);
if (!Window)
{
UserLeave();
return FALSE;
}
}
UserRefObjectCo(Window, &Ref);
lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi);
Ret = TRUE;
if (Window) UserDerefObjectCo(Window);
UserDerefObjectCo(Window);
break;
case FNID_SENDNOTIFYMESSAGE:
Ret = UserSendNotifyMessage(hWnd, Msg, wParam, lParam);
@ -2050,7 +2056,6 @@ NtUserMessageCall( HWND hWnd,
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Ret = FALSE;
_SEH2_YIELD(break);
}
_SEH2_END;
@ -2121,13 +2126,18 @@ NtUserMessageCall( HWND hWnd,
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Ret = FALSE;
_SEH2_YIELD(break);
}
_SEH2_END;
if (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam,
CallBackInfo.CallBack, CallBackInfo.Context, &uResult))
if (is_pointer_message(Msg))
{
EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
break;
}
if (!(Ret = co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam,
CallBackInfo.CallBack, CallBackInfo.Context, &uResult)))
{
DPRINT1("Callback failure!\n");
}
@ -2165,7 +2175,6 @@ NtUserMessageCall( HWND hWnd,
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Ret = FALSE;
_SEH2_YIELD(break);
}
_SEH2_END;

View file

@ -121,7 +121,7 @@ ClearMsgBitsMask(PUSER_MESSAGE_QUEUE Queue, UINT MessageBits)
pti = Queue->Thread->Tcb.Win32Thread;
if (MessageBits & QS_KEY)
{
{
if (--Queue->nCntsQBits[QSRosKey] == 0) ClrMask |= QS_KEY;
}
if (MessageBits & QS_MOUSEMOVE) // ReactOS hard coded.
@ -244,7 +244,13 @@ co_MsqInsertMouseMessage(MSG* Msg)
pwnd != NULL;
pwnd = pwnd->spwndNext )
{
if((pwnd->style & WS_VISIBLE) &&
if ( pwnd->state2 & WNDS2_INDESTROY || pwnd->state & WNDS_DESTROYED )
{
DPRINT("The Window is in DESTROY!\n");
continue;
}
if((pwnd->style & WS_VISIBLE) &&
IntPtInWindow(pwnd, Msg->pt.x, Msg->pt.y))
{
Msg->hwnd = pwnd->head.h;
@ -623,7 +629,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
UINT uTimeout, BOOL Block, INT HookMessage,
ULONG_PTR *uResult)
{
PTHREADINFO pti;
PTHREADINFO pti, ptirec;
PUSER_SENT_MESSAGE Message;
KEVENT CompletionEvent;
NTSTATUS WaitStatus;
@ -642,8 +648,10 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
pti = PsGetCurrentThreadWin32Thread();
ThreadQueue = pti->MessageQueue;
ptirec = MessageQueue->Thread->Tcb.Win32Thread;
ASSERT(ThreadQueue != MessageQueue);
ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!!
Timeout.QuadPart = (LONGLONG) uTimeout * (LONGLONG) -10000;
/* FIXME - increase reference counter of sender's message queue here */
@ -727,7 +735,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
Entry = Entry->Flink;
}
DPRINT("MsqSendMessage (blocked) timed out\n");
DPRINT("MsqSendMessage (blocked) timed out 1\n");
}
while (co_MsqDispatchOneSentMessage(ThreadQueue))
;
@ -787,7 +795,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
Entry = Entry->Flink;
}
DPRINT("MsqSendMessage timed out\n");
DPRINT("MsqSendMessage timed out 2\n");
break;
}
while (co_MsqDispatchOneSentMessage(ThreadQueue))
@ -860,7 +868,7 @@ static void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt )
if (pwndParent == pwndDesktop) break;
pt.x += pwnd->rcClient.left - pwndParent->rcClient.left;
pt.y += pwnd->rcClient.top - pwndParent->rcClient.top;
pwnd = pwndParent;
co_IntSendMessage( UserHMGetHandle(pwnd), WM_PARENTNOTIFY,
MAKEWPARAM( event, idChild ), MAKELPARAM( pt.x, pt.y ) );
@ -902,7 +910,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT
}
DPRINT("Got mouse message for 0x%x, hittest: 0x%x\n", msg->hwnd, hittest );
if (pwndMsg == NULL || pwndMsg->head.pti != pti)
{
/* Remove and ignore the message */
@ -972,7 +980,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT
}
}
if (!((first == 0 && last == 0) || (message >= first || message <= last)))
if (!((first == 0 && last == 0) || (message >= first || message <= last)))
{
DPRINT("Message out of range!!!\n");
RETURN(FALSE);
@ -1095,8 +1103,8 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT
if (pwndTop && pwndTop != pwndDesktop)
{
LONG ret = co_IntSendMessage( msg->hwnd,
WM_MOUSEACTIVATE,
LONG ret = co_IntSendMessage( msg->hwnd,
WM_MOUSEACTIVATE,
(WPARAM)UserHMGetHandle(pwndTop),
MAKELONG( hittest, msg->message));
switch(ret)
@ -1250,7 +1258,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
ListEntry);
do
do
{
if (IsListEmpty(CurrentEntry)) break;
if (!CurrentMessage) break;
@ -1296,7 +1304,7 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
PLIST_ENTRY CurrentEntry;
PUSER_MESSAGE CurrentMessage;
PLIST_ENTRY ListHead;
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
ListHead = &MessageQueue->PostedMessagesListHead;
@ -1309,8 +1317,15 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
if (IsListEmpty(CurrentEntry)) break;
if (!CurrentMessage) break;
CurrentEntry = CurrentEntry->Flink;
if ( ( !Window || Window == HWND_BOTTOM || Window->head.h == CurrentMessage->Msg.hwnd ) &&
/*
MSDN:
1: any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL.
2: retrieves only messages on the current thread's message queue whose hwnd value is NULL.
3: handle to the window whose messages are to be retrieved.
*/
if ( ( !Window || // 1
( Window == HWND_BOTTOM && CurrentMessage->Msg.hwnd == NULL ) || // 2
( Window != HWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) ) && // 3
( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
{
@ -1342,7 +1357,7 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter,
ret = KeWaitForSingleObject(MessageQueue->NewMessages,
Executive,
UserMode,
FALSE,
FALSE,
NULL);
UserEnterCo();
return ret;
@ -1357,6 +1372,15 @@ MsqIsHung(PUSER_MESSAGE_QUEUE MessageQueue)
return ((LargeTickCount.u.LowPart - MessageQueue->LastMsgRead) > MSQ_HUNG);
}
VOID
CALLBACK
HungAppSysTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
//DoTheScreenSaver();
DPRINT("HungAppSysTimerProc\n");
// Process list of windows that are hung and waiting.
}
BOOLEAN FASTCALL
MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQueue)
{
@ -1405,7 +1429,7 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
PUSER_MESSAGE CurrentMessage;
PUSER_SENT_MESSAGE CurrentSentMessage;
PTHREADINFO pti;
pti = MessageQueue->Thread->Tcb.Win32Thread;
@ -1428,7 +1452,7 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
/* remove the message from the dispatching list if needed */
if ((!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT))
if ((!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT))
&& (CurrentSentMessage->DispatchingListEntry.Flink != NULL))
{
RemoveEntryList(&CurrentSentMessage->DispatchingListEntry);
@ -1555,6 +1579,8 @@ MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
{
PDESKTOP desk;
MessageQueue->QF_flags |= QF_INDESTROY;
/* remove the message queue from any desktops */
if ((desk = InterlockedExchangePointer((PVOID*)&MessageQueue->Desktop, 0)))
{