- 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,6 +2021,9 @@ NtUserMessageCall( HWND hWnd,
UserEnterExclusive();
switch(dwType)
{
case FNID_DEFWINDOWPROC:
/* Validate input */
if (hWnd && (hWnd != INVALID_HANDLE_VALUE))
{
@ -2024,14 +2034,10 @@ NtUserMessageCall( HWND hWnd,
return FALSE;
}
}
switch(dwType)
{
case FNID_DEFWINDOWPROC:
if (Window) UserRefObjectCo(Window, &Ref);
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

@ -244,6 +244,12 @@ co_MsqInsertMouseMessage(MSG* Msg)
pwnd != NULL;
pwnd = pwnd->spwndNext )
{
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))
{
@ -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,7 +648,9 @@ 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;
@ -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))
@ -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 ) ) )
{
@ -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)
{
@ -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)))
{