1. move SendMessage calls out of the message queue processing code

2. fixed translation of coordinates calculation in different thread states (capturing, in menus, ...)
3. Proper implementation of Set/GetWindowText/Length() (as described in
4. speed improvements

svn path=/trunk/; revision=9152
This commit is contained in:
Thomas Bluemel 2004-04-15 23:36:03 +00:00
parent 1771d71894
commit 8eca059c02
10 changed files with 435 additions and 248 deletions

View file

@ -188,12 +188,12 @@ NtUserCallOneParam(
#define TWOPARAM_ROUTINE_SETMENUBARHEIGHT 0x50
#define TWOPARAM_ROUTINE_SETMENUITEMRECT 0x51
#define TWOPARAM_ROUTINE_SETGUITHRDHANDLE 0x52
#define TPR_SGTH_ACTIVE 0x01
#define TPR_SGTH_FOCUS 0x02
#define TPR_SGTH_CAPTURE 0x03
#define TPR_SGTH_MENUOWNER 0x04
#define TPR_SGTH_MOVESIZE 0x05
#define TPR_SGTH_CARET 0x06
#define MSQ_STATE_CAPTURE 0x1
#define MSQ_STATE_ACTIVE 0x2
#define MSQ_STATE_FOCUS 0x3
#define MSQ_STATE_MENUOWNER 0x4
#define MSQ_STATE_MOVESIZE 0x5
#define MSQ_STATE_CARET 0x6
#define TWOPARAM_ROUTINE_ENABLEWINDOW 0x53
#define TWOPARAM_ROUTINE_UNKNOWN 0x54
#define TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS 0x55

View file

@ -1,4 +1,4 @@
/* $Id: defwnd.c,v 1.133 2004/04/13 16:48:44 weiden Exp $
/* $Id: defwnd.c,v 1.134 2004/04/15 23:36:02 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@ -602,8 +602,9 @@ DefWndDoSizeMove(HWND hwnd, WORD wParam)
{
MapWindowPoints( hWndParent, 0, (LPPOINT)&mouseRect, 2 );
}
SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE, hwnd);
if (GetCapture() != hwnd) SetCapture( hwnd );
if (Style & WS_CHILD)
@ -746,7 +747,7 @@ DefWndDoSizeMove(HWND hwnd, WORD wParam)
DeleteObject(DesktopRgn);
}
}
NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE, NULL);
SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
@ -1572,7 +1573,7 @@ DefWindowProcW(HWND hWnd,
{
if (wParam > 1)
{
*((PWSTR)lParam) = '\0';
*((PWSTR)lParam) = L'\0';
}
return (LRESULT)NtUserInternalGetWindowText(hWnd, (PWSTR)lParam, wParam);
}

View file

@ -21,7 +21,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: menu.c,v 1.63 2004/04/09 21:01:02 navaraf Exp $
/* $Id: menu.c,v 1.64 2004/04/15 23:36:02 weiden Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/menu.c
@ -2736,6 +2736,7 @@ MenuDoNextMenu(MTRACKER* Mt, UINT Vk)
{
Mt->OwnerWnd = NewWnd;
SetCapture(Mt->OwnerWnd);
NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, Mt->OwnerWnd);
}
Mt->TopMenu = Mt->CurrentMenu = NewMenu; /* all subpopups are hidden */
@ -3098,6 +3099,7 @@ MenuTrackMenu(HMENU Menu, UINT Flags, INT x, INT y,
}
SetCapture(Mt.OwnerWnd);
NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, Mt.OwnerWnd);
while (! fEndMenu)
{
@ -3382,7 +3384,8 @@ MenuTrackMenu(HMENU Menu, UINT Flags, INT x, INT y,
Mt.TrackFlags &= ~TF_SKIPREMOVE;
}
}
NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
SetCapture(NULL); /* release the capture */
/* If dropdown is still painted and the close box is clicked on

View file

@ -865,7 +865,6 @@ DefWndDoButton(HWND hWnd, WPARAM wParam)
GetMessageW(&Msg, 0, 0, 0);
switch(Msg.message)
{
case WM_NCLBUTTONUP:
case WM_LBUTTONUP:
if(InBtn)
goto done;
@ -876,10 +875,10 @@ DefWndDoButton(HWND hWnd, WPARAM wParam)
ReleaseDC(hWnd, WindowDC);
return;
}
case WM_NCMOUSEMOVE:
case WM_MOUSEMOVE:
if(HasBtn)
{
ClientToScreen(hWnd, &Msg.pt);
CurBtn = DefWndNCHitTest(hWnd, Msg.pt);
if(InBtn != (CurBtn == OrigBtn))
{

View file

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.111 2004/04/14 23:17:55 weiden Exp $
/* $Id: window.c,v 1.112 2004/04/15 23:36:02 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@ -26,6 +26,8 @@
BOOL ControlsInitialized = FALSE;
LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn);
/* FUNCTIONS *****************************************************************/
@ -975,6 +977,38 @@ GetWindowRect(HWND hWnd,
int STDCALL
GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
{
DWORD ProcessId;
if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
{
return 0;
}
if(ProcessId != GetCurrentProcessId())
{
/* do not send WM_GETTEXT messages to other processes */
LPWSTR Buffer;
INT Length;
if (nMaxCount > 1)
{
*((PWSTR)lpString) = '\0';
}
Buffer = HeapAlloc(GetProcessHeap(), 0, nMaxCount * sizeof(WCHAR));
if (!Buffer)
return FALSE;
Length = NtUserInternalGetWindowText(hWnd, Buffer, nMaxCount);
if (Length > 0 && nMaxCount > 0 &&
!WideCharToMultiByte(CP_ACP, 0, Buffer, -1,
lpString, nMaxCount, NULL, NULL))
{
lpString[0] = '\0';
}
HeapFree(GetProcessHeap(), 0, Buffer);
return (LRESULT)Length;
}
return(SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString));
}
@ -985,7 +1019,19 @@ GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
int STDCALL
GetWindowTextLengthA(HWND hWnd)
{
return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
DWORD ProcessId;
if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
{
return 0;
}
if(ProcessId == GetCurrentProcessId())
{
return(SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0));
}
/* do not send WM_GETTEXT messages to other processes */
return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
}
@ -995,7 +1041,19 @@ GetWindowTextLengthA(HWND hWnd)
int STDCALL
GetWindowTextLengthW(HWND hWnd)
{
return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
DWORD ProcessId;
if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
{
return 0;
}
if(ProcessId == GetCurrentProcessId())
{
return(SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0));
}
/* do not send WM_GETTEXT messages to other processes */
return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
}
@ -1008,7 +1066,24 @@ GetWindowTextW(
LPWSTR lpString,
int nMaxCount)
{
return(SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString));
DWORD ProcessId;
if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
{
return 0;
}
if(ProcessId == GetCurrentProcessId())
{
return(SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString));
}
/* do not send WM_GETTEXT messages to other processes */
if (nMaxCount > 1)
{
*((PWSTR)lpString) = L'\0';
}
return (LRESULT)NtUserInternalGetWindowText(hWnd, (PWSTR)lpString, nMaxCount);
}
DWORD STDCALL
@ -1279,6 +1354,35 @@ BOOL STDCALL
SetWindowTextA(HWND hWnd,
LPCSTR lpString)
{
DWORD ProcessId;
if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
{
return FALSE;
}
if(ProcessId != GetCurrentProcessId())
{
/* do not send WM_GETTEXT messages to other processes */
ANSI_STRING AnsiString;
UNICODE_STRING UnicodeString;
if(lpString)
{
RtlInitAnsiString(&AnsiString, (LPSTR)lpString);
RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
NtUserDefSetText(hWnd, &UnicodeString);
RtlFreeUnicodeString(&UnicodeString);
}
else
NtUserDefSetText(hWnd, NULL);
if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
{
DefWndNCPaint(hWnd, (HRGN)1);
}
return TRUE;
}
return SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
}
@ -1290,6 +1394,29 @@ BOOL STDCALL
SetWindowTextW(HWND hWnd,
LPCWSTR lpString)
{
DWORD ProcessId;
if(!NtUserGetWindowThreadProcessId(hWnd, &ProcessId))
{
return FALSE;
}
if(ProcessId != GetCurrentProcessId())
{
/* do not send WM_GETTEXT messages to other processes */
UNICODE_STRING UnicodeString;
if(lpString)
RtlInitUnicodeString(&UnicodeString, (LPWSTR)lpString);
NtUserDefSetText(hWnd, (lpString ? &UnicodeString : NULL));
if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
{
DefWndNCPaint(hWnd, (HRGN)1);
}
return TRUE;
}
return SendMessageW(hWnd, WM_SETTEXT, 0, (LPARAM)lpString);
}

View file

@ -173,6 +173,10 @@ VOID FASTCALL
MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam);
VOID FASTCALL
MsqInsertSystemMessage(MSG* Msg, BOOL RemMouseMoveMsg);
BOOL FASTCALL
MsqIsDblClk(LPMSG Msg, BOOL Remove);
HWND FASTCALL
MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd);
inline BOOL MsqIsSignaled( PUSER_MESSAGE_QUEUE queue );
inline VOID MsqSetQueueBits( PUSER_MESSAGE_QUEUE queue, WORD bits );
@ -203,6 +207,12 @@ LPARAM FASTCALL MsqGetMessageExtraInfo(VOID);
#define MsqIsSignaled(MsgQueue) \
((MsgQueue->WakeBits & MsgQueue->WakeMask) || (MsgQueue->ChangedBits & MsgQueue->ChangedMask))
#define IS_BTN_MESSAGE(message,code) \
((message) == WM_LBUTTON##code || \
(message) == WM_MBUTTON##code || \
(message) == WM_RBUTTON##code || \
(message) == WM_XBUTTON##code )
#endif /* _WIN32K_MSGQUEUE_H */
/* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: focus.c,v 1.20 2004/04/13 13:50:31 weiden Exp $
* $Id: focus.c,v 1.21 2004/04/15 23:36:03 weiden Exp $
*/
#include <win32k/win32k.h>
@ -401,16 +401,23 @@ NtUserSetCapture(HWND hWnd)
DPRINT("NtUserSetCapture(%x)\n", hWnd);
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
Window = IntGetWindowObject(hWnd);
if (Window != 0)
if((Window = IntGetWindowObject(hWnd)))
{
if (Window->MessageQueue != ThreadQueue)
if(Window->MessageQueue != ThreadQueue)
{
IntReleaseWindowObject(Window);
return 0;
return NULL;
}
}
hWndPrev = ThreadQueue->CaptureWindow;
hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, hWnd);
/* also remove other windows if not capturing anymore */
if(hWnd == NULL)
{
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MENUOWNER, NULL);
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, NULL);
}
IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
IntLockMessageQueue(ThreadQueue);
ThreadQueue->CaptureWindow = hWnd;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: message.c,v 1.58 2004/04/14 20:18:12 weiden Exp $
/* $Id: message.c,v 1.59 2004/04/15 23:36:03 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -33,6 +33,8 @@
#include <win32k/win32k.h>
#include <include/msgqueue.h>
#include <include/window.h>
#include <include/winpos.h>
#include <include/focus.h>
#include <include/class.h>
#include <include/error.h>
#include <include/object.h>
@ -175,7 +177,7 @@ NtUserTranslateMessage(LPMSG lpMsg,
VOID FASTCALL
IntSendSpecialMessages(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg)
IntSendHitTestMessages(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg)
{
if(!Msg->hwnd || ThreadQueue->CaptureWindow)
{
@ -232,10 +234,108 @@ IntSendSpecialMessages(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg)
}
}
BOOL FASTCALL
IntActivateWindowMouse(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, PWINDOW_OBJECT MsgWindow,
USHORT *HitTest)
{
ULONG Result;
if(*HitTest == (USHORT)HTTRANSPARENT)
{
/* eat the message, search again! */
return TRUE;
}
Result = IntSendMessage(MsgWindow->Self, WM_MOUSEACTIVATE, (WPARAM)NtUserGetParent(MsgWindow->Self), (LPARAM)MAKELONG(*HitTest, Msg->message));
switch (Result)
{
case MA_NOACTIVATEANDEAT:
return TRUE;
case MA_NOACTIVATE:
break;
case MA_ACTIVATEANDEAT:
IntMouseActivateWindow(MsgWindow);
return TRUE;
default:
/* MA_ACTIVATE */
IntMouseActivateWindow(MsgWindow);
break;
}
return FALSE;
}
BOOL FASTCALL
IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *HitTest, BOOL Remove)
{
PWINDOW_OBJECT Window;
if(!(Window = IntGetWindowObject(Msg->hwnd)))
{
/* FIXME - change the mouse cursor to an arrow, maybe do this a better way */
IntLoadDefaultCursors(TRUE);
/* let's just eat the message?! */
return TRUE;
}
if(ThreadQueue == Window->MessageQueue &&
ThreadQueue->CaptureWindow != Window->Self)
{
/* only send WM_NCHITTEST messages if we're not capturing the window! */
*HitTest = IntSendMessage(Window->Self, WM_NCHITTEST, 0,
MAKELONG(Msg->pt.x, Msg->pt.y));
}
else
{
*HitTest = HTCLIENT;
}
if(IS_BTN_MESSAGE(Msg->message, DOWN))
{
/* generate double click messages, if necessary */
if ((((*HitTest) != HTCLIENT) ||
(IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_DBLCLKS)) &&
MsqIsDblClk(Msg, Remove))
{
Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
}
}
if(Msg->message != WM_MOUSEWHEEL)
{
if ((*HitTest) != HTCLIENT)
{
Msg->message += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
if((Msg->message == WM_NCRBUTTONUP) &&
(((*HitTest) == HTCAPTION) || ((*HitTest) == HTSYSMENU)))
{
Msg->message = WM_CONTEXTMENU;
Msg->wParam = (WPARAM)Window->Self;
}
else
{
Msg->wParam = *HitTest;
}
}
else if(ThreadQueue->MoveSize == NULL &&
ThreadQueue->MenuOwner == NULL)
{
Msg->pt.x -= Window->ClientRect.left;
Msg->pt.y -= Window->ClientRect.top;
Msg->lParam = MAKELONG(Msg->pt.x, Msg->pt.y);
}
}
IntReleaseWindowObject(Window);
return FALSE;
}
/*
* Internal version of PeekMessage() doing all the work
*/
BOOL STDCALL
BOOL FASTCALL
IntPeekMessage(LPMSG Msg,
HWND Wnd,
UINT MsgFilterMin,
@ -244,25 +344,27 @@ IntPeekMessage(LPMSG Msg,
{
LARGE_INTEGER LargeTickCount;
PUSER_MESSAGE_QUEUE ThreadQueue;
BOOLEAN Present;
PUSER_MESSAGE Message;
BOOLEAN RemoveMessages;
BOOL Present, RemoveMessages;
/* The queues and order in which they are checked are documented in the MSDN
article on GetMessage() */
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
KeQueryTickCount(&LargeTickCount);
ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
/* Inspect RemoveMsg flags */
/* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */
RemoveMessages = RemoveMsg & PM_REMOVE;
CheckMessages:
Present = FALSE;
KeQueryTickCount(&LargeTickCount);
ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
/* Dispatch sent messages here. */
while (MsqDispatchOneSentMessage(ThreadQueue))
;
while (MsqDispatchOneSentMessage(ThreadQueue));
/* Now look for a quit message. */
@ -275,9 +377,9 @@ IntPeekMessage(LPMSG Msg,
Msg->wParam = ThreadQueue->QuitExitCode;
Msg->lParam = 0;
if (RemoveMessages)
{
ThreadQueue->QuitPosted = FALSE;
}
{
ThreadQueue->QuitPosted = FALSE;
}
return TRUE;
}
@ -290,16 +392,15 @@ IntPeekMessage(LPMSG Msg,
MsgFilterMax,
&Message);
if (Present)
{
RtlCopyMemory(Msg, &Message->Msg, sizeof(MSG));
if (RemoveMessages)
{
RtlCopyMemory(Msg, &Message->Msg, sizeof(MSG));
if (RemoveMessages)
{
MsqDestroyMessage(Message);
IntSendSpecialMessages(ThreadQueue, Msg);
}
return TRUE;
MsqDestroyMessage(Message);
}
goto MessageFound;
}
/* Check for hardware events. */
Present = MsqFindMessage(ThreadQueue,
TRUE,
@ -309,27 +410,87 @@ IntPeekMessage(LPMSG Msg,
MsgFilterMax,
&Message);
if (Present)
{
RtlCopyMemory(Msg, &Message->Msg, sizeof(MSG));
if (RemoveMessages)
{
RtlCopyMemory(Msg, &Message->Msg, sizeof(MSG));
if (RemoveMessages)
{
MsqDestroyMessage(Message);
IntSendSpecialMessages(ThreadQueue, Msg);
}
return TRUE;
MsqDestroyMessage(Message);
}
goto MessageFound;
}
/* Check for sent messages again. */
while (MsqDispatchOneSentMessage(ThreadQueue))
;
while (MsqDispatchOneSentMessage(ThreadQueue));
/* Check for paint messages. */
if (IntGetPaintMessage(Wnd, PsGetWin32Thread(), Msg, RemoveMessages))
{
return TRUE;
}
/* FIXME - get WM_(SYS)TIMER messages */
if(Present)
{
MessageFound:
if(RemoveMessages)
{
PWINDOW_OBJECT MsgWindow = NULL;;
if(Msg->hwnd && (MsgWindow = IntGetWindowObject(Msg->hwnd)) &&
Msg->message >= WM_MOUSEFIRST && Msg->message <= WM_MOUSELAST)
{
USHORT HitTest;
if(IntTranslateMouseMessage(ThreadQueue, Msg, &HitTest, TRUE))
/* FIXME - check message filter again, if the message doesn't match anymore,
search again */
{
IntReleaseWindowObject(MsgWindow);
/* eat the message, search again */
goto CheckMessages;
}
if(ThreadQueue->CaptureWindow == NULL)
{
IntSendHitTestMessages(ThreadQueue, Msg);
if((Msg->message != WM_MOUSEMOVE && Msg->message != WM_NCMOUSEMOVE) &&
IS_BTN_MESSAGE(Msg->message, DOWN) &&
IntActivateWindowMouse(ThreadQueue, Msg, MsgWindow, &HitTest))
{
IntReleaseWindowObject(MsgWindow);
/* eat the message, search again */
goto CheckMessages;
}
}
}
else
{
IntSendHitTestMessages(ThreadQueue, Msg);
}
if(MsgWindow)
{
IntReleaseWindowObject(MsgWindow);
}
return TRUE;
}
USHORT HitTest;
if((Msg->hwnd && Msg->message >= WM_MOUSEFIRST && Msg->message <= WM_MOUSELAST) &&
IntTranslateMouseMessage(ThreadQueue, Msg, &HitTest, FALSE))
/* FIXME - check message filter again, if the message doesn't match anymore,
search again */
{
/* eat the message, search again */
goto CheckMessages;
}
return TRUE;
}
return FALSE;
return Present;
}
BOOL STDCALL

View file

@ -1,4 +1,4 @@
/* $Id: misc.c,v 1.61 2004/04/14 23:40:43 weiden Exp $
/* $Id: misc.c,v 1.62 2004/04/15 23:36:03 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -264,33 +264,10 @@ NtUserCallTwoParam(
case TWOPARAM_ROUTINE_SETGUITHRDHANDLE:
{
HWND *hwnd;
PUSER_MESSAGE_QUEUE MsgQueue = PsGetCurrentThread()->Win32Thread->MessageQueue;
switch(Param1)
{
case TPR_SGTH_ACTIVE:
hwnd = &MsgQueue->ActiveWindow;
break;
case TPR_SGTH_FOCUS:
hwnd = &MsgQueue->FocusWindow;
break;
case TPR_SGTH_CAPTURE:
hwnd = &MsgQueue->CaptureWindow;
break;
case TPR_SGTH_MENUOWNER:
hwnd = &MsgQueue->MenuOwner;
break;
case TPR_SGTH_MOVESIZE:
hwnd = &MsgQueue->MoveSize;
break;
case TPR_SGTH_CARET:
hwnd = &MsgQueue->CaretInfo->hWnd;
break;
default:
return 0;
}
return (DWORD)(*hwnd = (HWND)Param2);
ASSERT(MsgQueue);
return (DWORD)MsqSetStateWindow(MsgQueue, (ULONG)Param1, (HWND)Param2);
}
case TWOPARAM_ROUTINE_ENABLEWINDOW:

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: msgqueue.c,v 1.87 2004/04/14 19:07:14 weiden Exp $
/* $Id: msgqueue.c,v 1.88 2004/04/15 23:36:03 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -184,8 +184,8 @@ MsqInsertSystemMessage(MSG* Msg, BOOL RemMouseMoveMsg)
KeSetEvent(&HardwareMessageEvent, IO_NO_INCREMENT, FALSE);
}
BOOL STATIC FASTCALL
MsqIsDblClk(PWINDOW_OBJECT Window, PUSER_MESSAGE Message, BOOL Remove)
BOOL FASTCALL
MsqIsDblClk(LPMSG Msg, BOOL Remove)
{
PWINSTATION_OBJECT WinStaObject;
PSYSTEM_CURSORINFO CurInfo;
@ -202,13 +202,13 @@ MsqIsDblClk(PWINDOW_OBJECT Window, PUSER_MESSAGE Message, BOOL Remove)
return FALSE;
}
CurInfo = &WinStaObject->SystemCursor;
Res = (Message->Msg.hwnd == (HWND)CurInfo->LastClkWnd) &&
((Message->Msg.time - CurInfo->LastBtnDown) < CurInfo->DblClickSpeed);
Res = (Msg->hwnd == (HWND)CurInfo->LastClkWnd) &&
((Msg->time - CurInfo->LastBtnDown) < CurInfo->DblClickSpeed);
if(Res)
{
dX = CurInfo->LastBtnDownX - Message->Msg.pt.x;
dY = CurInfo->LastBtnDownY - Message->Msg.pt.y;
dX = CurInfo->LastBtnDownX - Msg->pt.x;
dY = CurInfo->LastBtnDownY - Msg->pt.y;
if(dX < 0) dX = -dX;
if(dY < 0) dY = -dY;
@ -221,16 +221,16 @@ MsqIsDblClk(PWINDOW_OBJECT Window, PUSER_MESSAGE Message, BOOL Remove)
if (Res)
{
CurInfo->LastBtnDown = 0;
CurInfo->LastBtnDownX = Message->Msg.pt.x;
CurInfo->LastBtnDownY = Message->Msg.pt.y;
CurInfo->LastBtnDownX = Msg->pt.x;
CurInfo->LastBtnDownY = Msg->pt.y;
CurInfo->LastClkWnd = NULL;
}
else
{
CurInfo->LastBtnDownX = Message->Msg.pt.x;
CurInfo->LastBtnDownY = Message->Msg.pt.y;
CurInfo->LastClkWnd = (HANDLE)Message->Msg.hwnd;
CurInfo->LastBtnDown = Message->Msg.time;
CurInfo->LastBtnDownX = Msg->pt.x;
CurInfo->LastBtnDownY = Msg->pt.y;
CurInfo->LastClkWnd = (HANDLE)Msg->hwnd;
CurInfo->LastBtnDown = Msg->time;
}
}
@ -239,120 +239,31 @@ MsqIsDblClk(PWINDOW_OBJECT Window, PUSER_MESSAGE Message, BOOL Remove)
}
BOOL STATIC STDCALL
MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh,
MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT FilterLow, UINT FilterHigh,
PUSER_MESSAGE Message, BOOL Remove, PBOOL Freed, BOOL RemoveWhenFreed,
PWINDOW_OBJECT ScopeWin, PUSHORT HitTest,
PPOINT ScreenPoint, BOOL FromGlobalQueue)
PWINDOW_OBJECT ScopeWin, PPOINT ScreenPoint, BOOL FromGlobalQueue)
{
PUSER_MESSAGE_QUEUE ThreadQueue;
USHORT Msg = Message->Msg.message;
PWINDOW_OBJECT Window = NULL;
HWND CaptureWin;
POINT Point;
ThreadQueue = PsGetWin32Thread()->MessageQueue;
if (Msg == WM_LBUTTONDOWN ||
Msg == WM_MBUTTONDOWN ||
Msg == WM_RBUTTONDOWN ||
Msg == WM_XBUTTONDOWN)
{
*HitTest = WinPosWindowFromPoint(ScopeWin, ThreadQueue, &Message->Msg.pt, &Window);
/*
**Make sure that we have a window that is not already in focus
*/
if (Window && (Window->Self != IntGetFocusWindow()))
{
if(ThreadQueue == Window->MessageQueue)
{
/* only get a more detailed hit-test if the window is in the same thread! */
*HitTest = IntSendMessage(Window->Self, WM_NCHITTEST, 0,
MAKELONG(Message->Msg.pt.x, Message->Msg.pt.y));
}
if(*HitTest != (USHORT)HTTRANSPARENT)
{
LRESULT Result;
/* Sending a message to another thread might lock up our own when it's
hung, so just send messages to our own thread */
if(Window->MessageQueue == ThreadQueue)
Result = IntSendMessage(Window->Self, WM_MOUSEACTIVATE, (WPARAM)NtUserGetParent(Window->Self), (LPARAM)MAKELONG(*HitTest, Msg));
else
{
/* just post WM_MOUSEACTIVATE to the other thread */
NtUserPostMessage(Window->Self, WM_MOUSEACTIVATE, (WPARAM)NtUserGetParent(Window->Self), (LPARAM)MAKELONG(*HitTest, Msg));
/* and assume that windows of other threads should always be activated. */
Result = MA_ACTIVATE;
}
switch (Result)
{
case MA_NOACTIVATEANDEAT:
*Freed = FALSE;
IntReleaseWindowObject(Window);
return TRUE;
case MA_NOACTIVATE:
break;
case MA_ACTIVATEANDEAT:
IntMouseActivateWindow(Window);
IntReleaseWindowObject(Window);
*Freed = FALSE;
return TRUE;
default:
/* MA_ACTIVATE */
IntMouseActivateWindow(Window);
break;
}
}
else
{
IntReleaseWindowObject(Window);
if(RemoveWhenFreed)
{
RemoveEntryList(&Message->ListEntry);
}
ExFreePool(Message);
*Freed = TRUE;
return(FALSE);
}
}
}
CaptureWin = IntGetCaptureWindow();
if (CaptureWin == NULL)
{
if(Msg == WM_MOUSEWHEEL)
{
*HitTest = HTCLIENT;
if(Window)
IntReleaseWindowObject(Window);
Window = IntGetWindowObject(IntGetFocusWindow());
}
else
{
if(!Window)
{
*HitTest = WinPosWindowFromPoint(ScopeWin, ThreadQueue, &Message->Msg.pt, &Window);
if(Window && (ThreadQueue == Window->MessageQueue))
{
*HitTest = IntSendMessage(Window->Self, WM_NCHITTEST, 0,
MAKELONG(Message->Msg.pt.x, Message->Msg.pt.y));
}
if(!Window)
{
/* change the cursor on desktop background */
IntLoadDefaultCursors(TRUE);
}
}
WinPosWindowFromPoint(ScopeWin, NULL, &Message->Msg.pt, &Window);
}
}
else
{
if(Window)
IntReleaseWindowObject(Window);
/* FIXME - window messages should go to the right window if no buttons are
pressed */
Window = IntGetWindowObject(CaptureWin);
*HitTest = HTCLIENT;
}
if (Window == NULL)
@ -366,7 +277,7 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh,
return(FALSE);
}
if (Window->MessageQueue != ThreadQueue)
if (Window->MessageQueue != MessageQueue)
{
if (! FromGlobalQueue)
{
@ -381,9 +292,9 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh,
/* remove the pointer for the current WM_MOUSEMOVE message in case we
just removed it */
if(ThreadQueue->MouseMoveMsg == Message)
if(MessageQueue->MouseMoveMsg == Message)
{
ThreadQueue->MouseMoveMsg = NULL;
MessageQueue->MouseMoveMsg = NULL;
}
}
@ -414,48 +325,7 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh,
/* From here on, we're in the same message queue as the caller! */
switch (Msg)
{
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_XBUTTONDOWN:
{
if ((((*HitTest) != HTCLIENT) ||
(IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_DBLCLKS)) &&
MsqIsDblClk(Window, Message, Remove))
{
Msg += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
}
break;
}
}
*ScreenPoint = Message->Msg.pt;
Point = Message->Msg.pt;
if ((*HitTest) != HTCLIENT)
{
Msg += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
if((Msg == WM_NCRBUTTONUP) &&
(((*HitTest) == HTCAPTION) || ((*HitTest) == HTSYSMENU)))
{
Msg = WM_CONTEXTMENU;
Message->Msg.wParam = (WPARAM)Window->Self;
}
else
{
Message->Msg.wParam = *HitTest;
}
}
else
{
if(Msg != WM_MOUSEWHEEL)
{
Point.x -= Window->ClientRect.left;
Point.y -= Window->ClientRect.top;
}
}
if((hWnd != NULL && Window->Self != hWnd) ||
((FilterLow != 0 || FilterLow != 0) && (Msg < FilterLow || Msg > FilterHigh)))
@ -496,13 +366,11 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh,
*Freed = FALSE;
return(FALSE);
}
if (Remove)
{
Message->Msg.hwnd = Window->Self;
Message->Msg.message = Msg;
Message->Msg.lParam = MAKELONG(Point.x, Point.y);
}
/* FIXME - only assign if removing? */
Message->Msg.hwnd = Window->Self;
Message->Msg.message = Msg;
Message->Msg.lParam = MAKELONG(Message->Msg.pt.x, Message->Msg.pt.y);
/* remove the reference to the current WM_(NC)MOUSEMOVE message, if this message
is it */
@ -544,7 +412,6 @@ MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
PUSER_MESSAGE* Message)
{
KIRQL OldIrql;
USHORT HitTest;
POINT ScreenPoint;
BOOL Accept, Freed;
PLIST_ENTRY CurrentEntry;
@ -584,10 +451,9 @@ MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
if (Current->Msg.message >= WM_MOUSEFIRST &&
Current->Msg.message <= WM_MOUSELAST)
{
Accept = MsqTranslateMouseMessage(hWnd, FilterLow, FilterHigh,
Accept = MsqTranslateMouseMessage(MessageQueue, hWnd, FilterLow, FilterHigh,
Current, Remove, &Freed, TRUE,
DesktopWindow, &HitTest,
&ScreenPoint, FALSE);
DesktopWindow, &ScreenPoint, FALSE);
if (Accept)
{
if (Remove)
@ -653,10 +519,9 @@ MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
{
const ULONG ActiveStamp = HardwareMessageQueueStamp;
/* Translate the message. */
Accept = MsqTranslateMouseMessage(hWnd, FilterLow, FilterHigh,
Accept = MsqTranslateMouseMessage(MessageQueue, hWnd, FilterLow, FilterHigh,
Current, Remove, &Freed, FALSE,
DesktopWindow, &HitTest,
&ScreenPoint, TRUE);
DesktopWindow, &ScreenPoint, TRUE);
if (Accept)
{
/* Check for no more messages in the system queue. */
@ -1217,4 +1082,41 @@ MsqGetMessageExtraInfo(VOID)
return MessageQueue->ExtraInfo;
}
HWND FASTCALL
MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd)
{
HWND Prev;
switch(Type)
{
case MSQ_STATE_CAPTURE:
Prev = MessageQueue->CaptureWindow;
MessageQueue->CaptureWindow = hWnd;
return Prev;
case MSQ_STATE_ACTIVE:
Prev = MessageQueue->ActiveWindow;
MessageQueue->ActiveWindow = hWnd;
return Prev;
case MSQ_STATE_FOCUS:
Prev = MessageQueue->FocusWindow;
MessageQueue->FocusWindow = hWnd;
return Prev;
case MSQ_STATE_MENUOWNER:
Prev = MessageQueue->MenuOwner;
MessageQueue->MenuOwner = hWnd;
return Prev;
case MSQ_STATE_MOVESIZE:
Prev = MessageQueue->MoveSize;
MessageQueue->MoveSize = hWnd;
return Prev;
case MSQ_STATE_CARET:
ASSERT(MessageQueue->CaretInfo);
Prev = MessageQueue->CaretInfo->hWnd;
MessageQueue->CaretInfo->hWnd = hWnd;
return Prev;
}
return NULL;
}
/* EOF */