mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +00:00
[Win32k]
- 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:
parent
04afecea16
commit
951d604b0c
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue