[User32|Win32k]

- Fix TrackMouseEvent! Keyboard and Mouse pass all the right flags. Update to accelerator code. Fixed recursion in global hooks. Hack-implement GetMouseMovePointsEx due to slack time and boredom, it passes the input tests but does nothing. Pass all the test_TrackMouseEvent!!! test_accelerators and test_menu_messages work too, so far no hangs.


svn path=/trunk/; revision=51283
This commit is contained in:
James Tabor 2011-04-08 19:29:15 +00:00
parent efe3b7a684
commit 5399e1d53e
22 changed files with 593 additions and 477 deletions

View file

@ -112,19 +112,6 @@ extern HINSTANCE hImmInstance;
/* Critical Section*/
extern RTL_CRITICAL_SECTION User32Crit;
typedef struct _USER32_TRACKINGLIST {
TRACKMOUSEEVENT tme;
POINT pos; /* center of hover rectangle */
UINT_PTR timer;
} USER32_TRACKINGLIST,*PUSER32_TRACKINGLIST;
typedef struct _USER32_THREAD_DATA
{
USER32_TRACKINGLIST tracking_info; /* TrackMouseEvent stuff */
} USER32_THREAD_DATA, *PUSER32_THREAD_DATA;
PUSER32_THREAD_DATA User32GetThreadData(VOID);
/* FIXME: Belongs to some header. */
BOOL WINAPI GdiDllInitialize(HANDLE, DWORD, LPVOID);
void InitStockObjects(void);

View file

@ -17,13 +17,6 @@ BOOL gfServerProcess = FALSE;
WCHAR szAppInit[KEY_LENGTH];
PUSER32_THREAD_DATA
User32GetThreadData()
{
return ((PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex));
}
BOOL
GetDllList()
{
@ -192,25 +185,12 @@ UnloadAppInitDlls()
BOOL
InitThread(VOID)
{
PUSER32_THREAD_DATA ThreadData;
ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(USER32_THREAD_DATA));
if (ThreadData == NULL)
return FALSE;
if (!TlsSetValue(User32TlsIndex, ThreadData))
return FALSE;
return TRUE;
}
VOID
CleanupThread(VOID)
{
PUSER32_THREAD_DATA ThreadData;
ThreadData = (PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex);
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ThreadData);
TlsSetValue(User32TlsIndex, 0);
}
BOOL

View file

@ -690,7 +690,7 @@
@ stdcall ToAsciiEx(long long ptr ptr long long)
@ stdcall ToUnicode(long long ptr ptr long long)
@ stdcall ToUnicodeEx(long long ptr ptr long long long)
@ stdcall TrackMouseEvent(ptr) ; Direct call NtUserTrackMouseEvent
@ stdcall TrackMouseEvent(ptr) NtUserTrackMouseEvent
@ stdcall TrackPopupMenu(long long long long long long ptr)
@ stdcall TrackPopupMenuEx(long long long long long ptr) ; Direct call NtUserTrackPopupMenuEx
@ stdcall TranslateAccelerator(long long ptr) TranslateAcceleratorA

View file

@ -530,242 +530,4 @@ mouse_event(
NtUserSendInput(1, &Input, sizeof(INPUT));
}
/***********************************************************************
* get_key_state
*/
static WORD get_key_state(void)
{
WORD ret = 0;
if (GetSystemMetrics( SM_SWAPBUTTON ))
{
if (GetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON;
if (GetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON;
}
else
{
if (GetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON;
if (GetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON;
}
if (GetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON;
if (GetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT;
if (GetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL;
if (GetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1;
if (GetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2;
return ret;
}
static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
DWORD dwTime)
{
POINT pos;
POINT posClient;
HWND hwnd;
INT hoverwidth = 0, hoverheight = 0;
RECT client;
PUSER32_TRACKINGLIST ptracking_info;
ptracking_info = & User32GetThreadData()->tracking_info;
GetCursorPos(&pos);
hwnd = WindowFromPoint(pos);
SystemParametersInfoW(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
SystemParametersInfoW(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
/* see if this tracking event is looking for TME_LEAVE and that the */
/* mouse has left the window */
if (ptracking_info->tme.dwFlags & TME_LEAVE)
{
if (ptracking_info->tme.hwndTrack != hwnd)
{
if (ptracking_info->tme.dwFlags & TME_NONCLIENT)
{
PostMessageW(ptracking_info->tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
}
else
{
PostMessageW(ptracking_info->tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
}
/* remove the TME_LEAVE flag */
ptracking_info->tme.dwFlags &= ~TME_LEAVE;
}
else
{
GetClientRect(hwnd, &client);
MapWindowPoints(hwnd, NULL, (LPPOINT)&client, 2);
if (PtInRect(&client, pos))
{
if (ptracking_info->tme.dwFlags & TME_NONCLIENT)
{
PostMessageW(ptracking_info->tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
/* remove the TME_LEAVE flag */
ptracking_info->tme.dwFlags &= ~TME_LEAVE;
}
}
else
{
if (!(ptracking_info->tme.dwFlags & TME_NONCLIENT))
{
PostMessageW(ptracking_info->tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
/* remove the TME_LEAVE flag */
ptracking_info->tme.dwFlags &= ~TME_LEAVE;
}
}
}
}
/* see if we are tracking hovering for this hwnd */
if (ptracking_info->tme.dwFlags & TME_HOVER)
{
/* has the cursor moved outside the rectangle centered around pos? */
if ((abs(pos.x - ptracking_info->pos.x) > (hoverwidth / 2.0)) ||
(abs(pos.y - ptracking_info->pos.y) > (hoverheight / 2.0)))
{
/* record this new position as the current position and reset */
/* the iHoverTime variable to 0 */
ptracking_info->pos = pos;
}
else
{
posClient.x = pos.x;
posClient.y = pos.y;
ScreenToClient(hwnd, &posClient);
if (ptracking_info->tme.dwFlags & TME_NONCLIENT)
{
PostMessageW(ptracking_info->tme.hwndTrack, WM_NCMOUSEHOVER,
get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
}
else
{
PostMessageW(ptracking_info->tme.hwndTrack, WM_MOUSEHOVER,
get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
}
/* stop tracking mouse hover */
ptracking_info->tme.dwFlags &= ~TME_HOVER;
}
}
/* stop the timer if the tracking list is empty */
if (!(ptracking_info->tme.dwFlags & (TME_HOVER | TME_LEAVE)))
{
KillTimer(0, ptracking_info->timer);
RtlZeroMemory(ptracking_info,sizeof(USER32_TRACKINGLIST));
}
}
/***********************************************************************
* TrackMouseEvent [USER32]
*
* Requests notification of mouse events
*
* During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
* to the hwnd specified in the ptme structure. After the event message
* is posted to the hwnd, the entry in the queue is removed.
*
* If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
* ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
* immediately and the TME_LEAVE flag being ignored.
*
* PARAMS
* ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
*
* RETURNS
* Success: non-zero
* Failure: zero
*
*/
/*
* @implemented
*/
BOOL
WINAPI
TrackMouseEvent(
LPTRACKMOUSEEVENT ptme)
{
HWND hwnd;
POINT pos;
DWORD hover_time;
PUSER32_TRACKINGLIST ptracking_info;
TRACE("%lx, %lx, %p, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
WARN("wrong TRACKMOUSEEVENT size from app\n");
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
ptracking_info = & User32GetThreadData()->tracking_info;
/* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
if (ptme->dwFlags & TME_QUERY )
{
*ptme = ptracking_info->tme;
ptme->cbSize = sizeof(TRACKMOUSEEVENT);
return TRUE; /* return here, TME_QUERY is retrieving information */
}
if (!IsWindow(ptme->hwndTrack))
{
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
return FALSE;
}
hover_time = ptme->dwHoverTime;
/* if HOVER_DEFAULT was specified replace this with the systems current value */
if (hover_time == HOVER_DEFAULT || hover_time == 0)
{
SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0);
}
GetCursorPos(&pos);
hwnd = WindowFromPoint(pos);
if (ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT))
{
FIXME("Unknown flag(s) %08lx\n", ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT));
}
if (ptme->dwFlags & TME_CANCEL)
{
if (ptracking_info->tme.hwndTrack == ptme->hwndTrack)
{
ptracking_info->tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
/* if we aren't tracking on hover or leave remove this entry */
if (!(ptracking_info->tme.dwFlags & (TME_HOVER | TME_LEAVE)))
{
KillTimer(0, ptracking_info->timer);
RtlZeroMemory(ptracking_info,sizeof(USER32_TRACKINGLIST));
}
}
} else {
if (ptme->hwndTrack == hwnd)
{
/* Adding new mouse event to the tracking list */
ptracking_info->tme = *ptme;
ptracking_info->tme.dwHoverTime = hover_time;
/* Initialize HoverInfo variables even if not hover tracking */
ptracking_info->pos = pos;
if (!ptracking_info->timer)
{
ptracking_info->timer = SetTimer(0, 0, hover_time, TrackMouseEventProc);
}
}
}
return TRUE;
}
/* EOF */

View file

@ -69,7 +69,7 @@ BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxW
INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags);
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon);
BOOL UserSetCursorPos( INT x, INT y, BOOL SendMouseMoveMsg);
BOOL UserSetCursorPos( INT x, INT y);
int UserShowCursor(BOOL bShow);

View file

@ -9,6 +9,7 @@ typedef struct _DESKTOP
LIST_ENTRY ListEntry;
/* Pointer to the associated window station. */
struct _WINSTATION_OBJECT *rpwinstaParent;
DWORD dwDTFlags;
PWND spwndForeground;
PWND spwndTray;
PWND spwndMessage;
@ -27,12 +28,20 @@ typedef struct _DESKTOP
/* Pointer to the active queue. */
PVOID ActiveMessageQueue;
/* Handle of the desktop window. */
HANDLE DesktopWindow;
HWND DesktopWindow;
/* Thread blocking input */
PVOID BlockInputThread;
LIST_ENTRY ShellHookWindows;
} DESKTOP, *PDESKTOP;
// Desktop flags
#define DF_TME_HOVER 0x00000400
#define DF_TME_LEAVE 0x00000800
#define DF_DESTROYED 0x00008000
#define DF_DESKWNDDESTROYED 0x00010000
#define DF_DYING 0x00020000
extern PDESKTOP InputDesktop;
extern HDESK InputDesktopHandle;
extern PCLS DesktopWindowClass;
@ -125,6 +134,7 @@ BOOL IntRegisterShellHookWindow(HWND hWnd);
BOOL IntDeRegisterShellHookWindow(HWND hWnd);
VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam);
HDC FASTCALL UserGetDesktopDC(ULONG,BOOL,BOOL);
BOOL FASTCALL IntPaintDesktop(HDC hDC);
#define IntIsActiveDesktop(Desktop) \
((Desktop)->rpwinstaParent->ActiveDesktop == (Desktop))

View file

@ -42,8 +42,8 @@ VOID W32kUnregisterPrimitiveMessageQueue(VOID);
PKBL W32kGetDefaultKeyLayout(VOID);
VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyLayout, BYTE Prefix);
BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt);
BOOL FASTCALL IntMouseInput(MOUSEINPUT *mi);
BOOL FASTCALL IntKeyboardInput(KEYBDINPUT *ki);
BOOL FASTCALL IntMouseInput(MOUSEINPUT *mi, BOOL Injected);
BOOL FASTCALL IntKeyboardInput(KEYBDINPUT *ki, BOOL Injected);
BOOL UserInitDefaultKeyboardLayout(VOID);
PKBL UserHklToKbl(HKL hKl);

View file

@ -242,7 +242,7 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
VOID FASTCALL
MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam);
VOID FASTCALL
co_MsqInsertMouseMessage(MSG* Msg);
co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo);
BOOL FASTCALL
MsqIsClkLck(LPMSG Msg, BOOL Remove);
BOOL FASTCALL

View file

@ -24,6 +24,12 @@ typedef struct _TIMER
#define TMRF_WAITING 0x0020
#define TMRF_TIFROMWND 0x0040
#define ID_EVENT_SYSTIMER_MOUSEHOVER (-6)
#define ID_EVENT_SYSTIMER_FLASHWIN (-8)
#define ID_EVENT_SYSTIMER_TRACKWIN (-9)
#define ID_EVENT_SYSTIMER_ANIMATEDFADE (-10)
#define ID_EVENT_SYSTIMER_INVALIDATEDCES (-11)
extern PKTIMER MasterTimer;
INIT_FUNCTION

View file

@ -1,27 +1,8 @@
/*
* ReactOS W32 Subsystem
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Window classes
* FILE: subsys/win32k/ntuser/class.c
* PURPOSE: Window accelerator
* FILE: subsystems/win32/win32k/ntuser/accelerator.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISION HISTORY:
* 06-06-2001 CSH Created
@ -105,10 +86,14 @@ co_IntTranslateAccelerator(
WORD key,
WORD cmd)
{
INT mask = 0;
UINT mesg = 0;
HWND hWnd;
ASSERT_REFS_CO(Window);
hWnd = Window->head.h;
DPRINT("IntTranslateAccelerator(hwnd %x, message %x, wParam %x, lParam %x, fVirt %d, key %x, cmd %x)\n",
Window->head.h, message, wParam, lParam, fVirt, key, cmd);
@ -117,37 +102,33 @@ co_IntTranslateAccelerator(
return FALSE;
}
if (message == WM_CHAR)
DPRINT("NtUserGetKeyState(VK_SHIFT) = 0x%x\n",
UserGetKeyState(VK_SHIFT));
DPRINT("NtUserGetKeyState(VK_CONTROL) = 0x%x\n",
UserGetKeyState(VK_CONTROL));
DPRINT("NtUserGetKeyState(VK_MENU) = 0x%x\n",
UserGetKeyState(VK_MENU));
if (UserGetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
if (UserGetKeyState(VK_MENU) & 0x8000) mask |= FALT;
if (UserGetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
if (message == WM_CHAR || message == WM_SYSCHAR)
{
if (!(fVirt & FALT) && !(fVirt & FVIRTKEY))
if ( !(fVirt & FVIRTKEY) && (mask & FALT) == (fVirt & FALT) )
{
DPRINT("found accel for WM_CHAR: ('%c')\n", wParam & 0xff);
DPRINT("found accel for WM_CHAR: ('%c')\n", LOWORD(wParam) & 0xff);
goto found;
}
}
else
{
if ((fVirt & FVIRTKEY) > 0)
if (fVirt & FVIRTKEY)
{
INT mask = 0;
DPRINT("found accel for virt_key %04x (scan %04x)\n",
wParam, 0xff & HIWORD(lParam));
wParam, 0xff & HIWORD(lParam));
DPRINT("NtUserGetKeyState(VK_SHIFT) = 0x%x\n",
UserGetKeyState(VK_SHIFT));
DPRINT("NtUserGetKeyState(VK_CONTROL) = 0x%x\n",
UserGetKeyState(VK_CONTROL));
DPRINT("NtUserGetKeyState(VK_MENU) = 0x%x\n",
UserGetKeyState(VK_MENU));
if (UserGetKeyState(VK_SHIFT) & 0x8000)
mask |= FSHIFT;
if (UserGetKeyState(VK_CONTROL) & 0x8000)
mask |= FCONTROL;
if (UserGetKeyState(VK_MENU) & 0x8000)
mask |= FALT;
if (mask == (fVirt & (FSHIFT | FCONTROL | FALT)))
goto found;
if (mask == (fVirt & (FSHIFT | FCONTROL | FALT))) goto found;
DPRINT("but incorrect SHIFT/CTRL/ALT-state\n");
}
else
@ -156,7 +137,7 @@ co_IntTranslateAccelerator(
{
if ((fVirt & FALT) && (lParam & 0x20000000))
{ /* ^^ ALT pressed */
DPRINT("found accel for Alt-%c\n", wParam & 0xff);
DPRINT("found accel for Alt-%c\n", LOWORD(wParam) & 0xff);
goto found;
}
}
@ -173,80 +154,120 @@ found:
mesg = 1;
else if (IntGetCaptureWindow())
mesg = 2;
else if (!IntIsWindowVisible(Window)) /* FIXME: WINE IsWindowEnabled == IntIsWindowVisible? */
else if (Window->style & WS_DISABLED)
mesg = 3;
else
{
#if 0
HMENU hMenu, hSubMenu, hSysMenu;
UINT uSysStat = (UINT)-1, uStat = (UINT)-1, nPos;
PMENU_OBJECT MenuObject, SubMenu;
MENU_ITEM MenuItem;
hMenu = (UserGetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ? 0 : GetMenu(hWnd);
hSysMenu = get_win_sys_menu(hWnd);
// hMenu = (UserGetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ? 0 : GetMenu(hWnd);
// hSysMenu = get_win_sys_menu(hWnd);
hMenu = (Window->style & WS_CHILD) ? 0 : (HMENU)Window->IDMenu;
hSysMenu = Window->SystemMenu;
MenuObject = IntGetMenuObject(Window->SystemMenu);
/* find menu item and ask application to initialize it */
/* 1. in the system menu */
hSubMenu = hSysMenu;
nPos = cmd;
if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
// nPos = cmd;
// if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
nPos = IntGetMenuItemByFlag( MenuObject,
cmd,
MF_BYCOMMAND,
&SubMenu,
&MenuItem,
NULL);
if (MenuItem && (nPos != (UINT)-1))
{
co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L);
if(hSubMenu != hSysMenu)
{
nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu);
TRACE_(accel)("hSysMenu = %p, hSubMenu = %p, nPos = %d\n", hSysMenu, hSubMenu, nPos);
co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE));
hSubMenu = MenuItem.hSubMenu;
if (IntGetCaptureWindow())
mesg = 2;
if (Window->style & WS_DISABLED)
mesg = 3;
else
{
co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L);
if(hSubMenu != hSysMenu)
{
nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu);
DPRINT("hSysMenu = %p, hSubMenu = %p, nPos = %d\n", hSysMenu, hSubMenu, nPos);
co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE));
}
uSysStat = GetMenuState(GetSubMenu(hSysMenu, 0), cmd, MF_BYCOMMAND);
}
uSysStat = GetMenuState(GetSubMenu(hSysMenu, 0), cmd, MF_BYCOMMAND);
}
else /* 2. in the window's menu */
{
MenuObject = IntGetMenuObject(hMenu);
hSubMenu = hMenu;
nPos = cmd;
if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
// nPos = cmd;
// if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
nPos = IntGetMenuItemByFlag( MenuObject,
cmd,
MF_BYCOMMAND,
&SubMenu,
&MenuItem,
NULL);
if (MenuItem && (nPos != (UINT)-1))
{
co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L);
if(hSubMenu != hMenu)
if (IntGetCaptureWindow())
mesg = 2;
if (Window->style & WS_DISABLED)
mesg = 3;
else
{
nPos = MENU_FindSubMenu(&hMenu, hSubMenu);
TRACE_(accel)("hMenu = %p, hSubMenu = %p, nPos = %d\n", hMenu, hSubMenu, nPos);
co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE));
co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L);
if(hSubMenu != hMenu)
{
nPos = MENU_FindSubMenu(&hMenu, hSubMenu);
DPRINT("hMenu = %p, hSubMenu = %p, nPos = %d\n", hMenu, hSubMenu, nPos);
co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE));
}
uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND);
}
uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND);
}
}
if (uSysStat != (UINT)-1)
if (mesg == 0)
{
if (uSysStat & (MF_DISABLED|MF_GRAYED))
mesg=4;
else
mesg=WM_SYSCOMMAND;
}
else
{
if (uStat != (UINT)-1)
if (uSysStat != (UINT)-1)
{
if (IsIconic(hWnd))
mesg=5;
if (uSysStat & (MF_DISABLED|MF_GRAYED))
mesg=4;
else
{
if (uStat & (MF_DISABLED|MF_GRAYED))
mesg=6;
else
mesg=WM_COMMAND;
}
mesg=WM_SYSCOMMAND;
}
else
{
mesg=WM_COMMAND;
if (uStat != (UINT)-1)
{
if (Window->style & WS_MINIMIZE)
mesg=5;
else
{
if (uStat & (MF_DISABLED|MF_GRAYED))
mesg=6;
else
mesg=WM_COMMAND;
}
}
else
{
mesg=WM_COMMAND;
}
}
}
#else
DPRINT1("Menu search not implemented\n");
mesg = WM_COMMAND;
#endif
}
if (mesg == WM_COMMAND)

View file

@ -510,18 +510,25 @@ co_IntCallHookProc(INT HookId,
UserEnterCo();
_SEH2_TRY
if (ResultPointer)
{
ProbeForRead(ResultPointer, sizeof(LRESULT), 1);
/* Simulate old behaviour: copy into our local buffer */
Result = *(LRESULT*)ResultPointer;
_SEH2_TRY
{
ProbeForRead(ResultPointer, sizeof(LRESULT), 1);
/* Simulate old behaviour: copy into our local buffer */
Result = *(LRESULT*)ResultPointer;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Result = 0;
Hit = TRUE;
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
else
{
Result = 0;
Hit = TRUE;
DPRINT1("ERROR: Hook ResultPointer 0x%x ResultLength %d\n",ResultPointer,ResultLength);
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{

View file

@ -159,7 +159,7 @@ UserSetCursor(
return OldCursor;
}
BOOL UserSetCursorPos( INT x, INT y, BOOL SendMouseMoveMsg)
BOOL UserSetCursorPos( INT x, INT y)
{
PWND DesktopWindow;
PSYSTEM_CURSORINFO CurInfo;
@ -194,21 +194,17 @@ BOOL UserSetCursorPos( INT x, INT y, BOOL SendMouseMoveMsg)
pt.x = x;
pt.y = y;
/* 3. Generate a mouse move message, this sets the htEx. */
Msg.message = WM_MOUSEMOVE;
Msg.wParam = CurInfo->ButtonsDown;
Msg.lParam = MAKELPARAM(x, y);
Msg.pt = pt;
co_MsqInsertMouseMessage(&Msg, 0, 0);
if (SendMouseMoveMsg)
{
/* Generate a mouse move message */
Msg.message = WM_MOUSEMOVE;
Msg.wParam = CurInfo->ButtonsDown;
Msg.lParam = MAKELPARAM(x, y);
Msg.pt = pt;
co_MsqInsertMouseMessage(&Msg);
}
/* Store the new cursor position */
/* 1. Store the new cursor position */
gpsi->ptCursor = pt;
/* Move the mouse pointer */
/* 2. Move the mouse pointer */
GreMovePointer(hDC, x, y);
return TRUE;
@ -681,7 +677,7 @@ UserClipCursor(
{
CurInfo->bClipped = TRUE;
RECTL_bIntersectRect(&CurInfo->rcClip, prcl, &DesktopWindow->rcWindow);
UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE);
UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y);
}
else
{

View file

@ -595,7 +595,7 @@ co_UserSetCapture(HWND hWnd)
mi.dwFlags = MOUSEEVENTF_MOVE;
mi.time = 0;
mi.dwExtraInfo = 0;
IntMouseInput(&mi);
IntMouseInput(&mi,FALSE);
}
return hWndPrev;
}

View file

@ -1003,6 +1003,10 @@ co_HOOK_CallHooks( INT HookId,
ClientInfo = pti->pClientInfo;
SaveHook = pti->sphkCurrent;
/* Note: Setting pti->sphkCurrent will also lock the next hook to this
* hook ID. So, the CallNextHookEx will only call to that hook ID
* chain anyway. For Thread Hooks....
*/
/* Load it for the next call. */
pti->sphkCurrent = Hook;
@ -1042,7 +1046,7 @@ co_HOOK_CallHooks( INT HookId,
ObDereferenceObject(Hook->Thread);
}
if ( Global )
if ( Global && !pti->sphkCurrent)
{
PTHREADINFO ptiHook;
@ -1057,6 +1061,7 @@ co_HOOK_CallHooks( INT HookId,
* hook ID, this will have to post to each of the thread message queues
* or make a direct call.
*/
pti->sphkCurrent = Hook; // Prevent recursion within this thread.
do
{
/* Hook->Thread is null, we hax around this with Hook->head.pti. */
@ -1104,6 +1109,7 @@ co_HOOK_CallHooks( INT HookId,
}
while ( Hook );
DPRINT("Ret: Global HookId %d Result 0x%x\n", HookId,Result);
pti->sphkCurrent = NULL;
}
Exit:
return Result;

View file

@ -53,7 +53,7 @@ DWORD IntLastInputTick(BOOL LastInputTickSetGet);
if(mi.dx != 0 || mi.dy != 0) \
mi.dwFlags |= MOUSEEVENTF_MOVE; \
if(mi.dwFlags) \
IntMouseInput(&mi); \
IntMouseInput(&mi,FALSE); \
ClearMouseInput(mi);
@ -481,6 +481,7 @@ IntKeyboardSendWinKeyMsg()
static VOID APIENTRY
co_IntKeyboardSendAltKeyMsg()
{
DPRINT1("co_IntKeyboardSendAltKeyMsg\n");
co_MsqPostKeyboardMessage(WM_SYSCOMMAND,SC_KEYMENU,0);
}
@ -1073,7 +1074,7 @@ CLEANUP:
}
BOOL FASTCALL
IntMouseInput(MOUSEINPUT *mi)
IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
{
const UINT SwapBtnMsg[2][2] =
{
@ -1137,7 +1138,7 @@ IntMouseInput(MOUSEINPUT *mi)
if(mi->dwFlags & MOUSEEVENTF_MOVE)
{
UserSetCursorPos(MousePos.x, MousePos.y, TRUE);
UserSetCursorPos(MousePos.x, MousePos.y);
}
if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
{
@ -1145,7 +1146,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[0][SwapButtons];
CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
{
@ -1153,7 +1154,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[1][SwapButtons];
CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
{
@ -1161,7 +1162,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = WM_MBUTTONDOWN;
CurInfo->ButtonsDown |= MK_MBUTTON;
Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
{
@ -1169,7 +1170,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = WM_MBUTTONUP;
CurInfo->ButtonsDown &= ~MK_MBUTTON;
Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
{
@ -1177,7 +1178,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[0][!SwapButtons];
CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
{
@ -1185,7 +1186,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[1][!SwapButtons];
CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
if((mi->dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) &&
@ -1203,14 +1204,14 @@ IntMouseInput(MOUSEINPUT *mi)
gQueueKeyStateTable[VK_XBUTTON1] |= 0xc0;
CurInfo->ButtonsDown |= MK_XBUTTON1;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
if(mi->mouseData & XBUTTON2)
{
gQueueKeyStateTable[VK_XBUTTON2] |= 0xc0;
CurInfo->ButtonsDown |= MK_XBUTTON2;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
}
else if(mi->dwFlags & MOUSEEVENTF_XUP)
@ -1221,28 +1222,28 @@ IntMouseInput(MOUSEINPUT *mi)
gQueueKeyStateTable[VK_XBUTTON1] &= ~0x80;
CurInfo->ButtonsDown &= ~MK_XBUTTON1;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
if(mi->mouseData & XBUTTON2)
{
gQueueKeyStateTable[VK_XBUTTON2] &= ~0x80;
CurInfo->ButtonsDown &= ~MK_XBUTTON2;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
}
if(mi->dwFlags & MOUSEEVENTF_WHEEL)
{
Msg.message = WM_MOUSEWHEEL;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, mi->mouseData);
co_MsqInsertMouseMessage(&Msg);
co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
}
return TRUE;
}
BOOL FASTCALL
IntKeyboardInput(KEYBDINPUT *ki)
IntKeyboardInput(KEYBDINPUT *ki, BOOL Injected)
{
PUSER_MESSAGE_QUEUE FocusMessageQueue;
MSG Msg;
@ -1346,6 +1347,7 @@ IntKeyboardInput(KEYBDINPUT *ki)
KbdHookData.vkCode = vk_hook;
KbdHookData.scanCode = ki->wScan;
KbdHookData.flags = flags >> 8;
if (Injected) KbdHookData.flags |= LLKHF_INJECTED;
KbdHookData.time = Msg.time;
KbdHookData.dwExtraInfo = ki->dwExtraInfo;
if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
@ -1510,13 +1512,13 @@ NtUserSendInput(
switch(SafeInput.type)
{
case INPUT_MOUSE:
if(IntMouseInput(&SafeInput.mi))
if(IntMouseInput(&SafeInput.mi, TRUE))
{
cnt++;
}
break;
case INPUT_KEYBOARD:
if(IntKeyboardInput(&SafeInput.ki))
if(IntKeyboardInput(&SafeInput.ki, TRUE))
{
cnt++;
}
@ -1541,4 +1543,280 @@ CLEANUP:
END_CLEANUP;
}
BOOL
FASTCALL
IntQueryTrackMouseEvent(
LPTRACKMOUSEEVENT lpEventTrack)
{
PDESKTOP pDesk;
PTHREADINFO pti;
pti = PsGetCurrentThreadWin32Thread();
pDesk = pti->rpdesk;
/* Always cleared with size set and return true. */
RtlZeroMemory(lpEventTrack ,sizeof(TRACKMOUSEEVENT));
lpEventTrack->cbSize = sizeof(TRACKMOUSEEVENT);
if ( pDesk->dwDTFlags & (DF_TME_LEAVE|DF_TME_HOVER) &&
pDesk->spwndTrack &&
pti->MessageQueue == pDesk->spwndTrack->head.pti->MessageQueue )
{
if ( pDesk->htEx != HTCLIENT )
lpEventTrack->dwFlags |= TME_NONCLIENT;
if ( pDesk->dwDTFlags & DF_TME_LEAVE )
lpEventTrack->dwFlags |= TME_LEAVE;
if ( pDesk->dwDTFlags & DF_TME_HOVER )
{
lpEventTrack->dwFlags |= TME_HOVER;
lpEventTrack->dwHoverTime = pDesk->dwMouseHoverTime;
}
lpEventTrack->hwndTrack = UserHMGetHandle(pDesk->spwndTrack);
}
return TRUE;
}
BOOL
FASTCALL
IntTrackMouseEvent(
LPTRACKMOUSEEVENT lpEventTrack)
{
PDESKTOP pDesk;
PTHREADINFO pti;
PWND pWnd;
POINT point;
pti = PsGetCurrentThreadWin32Thread();
pDesk = pti->rpdesk;
if (!(pWnd = UserGetWindowObject(lpEventTrack->hwndTrack)))
return FALSE;
if ( pDesk->spwndTrack != pWnd ||
(pDesk->htEx != HTCLIENT) ^ !!(lpEventTrack->dwFlags & TME_NONCLIENT) )
{
if ( lpEventTrack->dwFlags & TME_LEAVE && !(lpEventTrack->dwFlags & TME_CANCEL) )
{
UserPostMessage( lpEventTrack->hwndTrack,
lpEventTrack->dwFlags & TME_NONCLIENT ? WM_NCMOUSELEAVE : WM_MOUSELEAVE,
0, 0);
}
DPRINT("IntTrackMouseEvent spwndTrack 0x%x pwnd 0x%x\n", pDesk->spwndTrack,pWnd);
return TRUE;
}
/* Tracking spwndTrack same as pWnd */
if ( lpEventTrack->dwFlags & TME_CANCEL ) // Canceled mode.
{
if ( lpEventTrack->dwFlags & TME_LEAVE )
pDesk->dwDTFlags &= ~DF_TME_LEAVE;
if ( lpEventTrack->dwFlags & TME_HOVER )
{
if ( pDesk->dwDTFlags & DF_TME_HOVER )
{ // Kill hover timer.
IntKillTimer(pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE);
pDesk->dwDTFlags &= ~DF_TME_HOVER;
}
}
}
else // Not Canceled.
{
if ( lpEventTrack->dwFlags & TME_LEAVE )
pDesk->dwDTFlags |= DF_TME_LEAVE;
if ( lpEventTrack->dwFlags & TME_HOVER )
{
pDesk->dwDTFlags |= DF_TME_HOVER;
if ( !lpEventTrack->dwHoverTime || lpEventTrack->dwHoverTime == HOVER_DEFAULT )
pDesk->dwMouseHoverTime = gspv.iMouseHoverTime; // use the system default hover time-out.
else
pDesk->dwMouseHoverTime = lpEventTrack->dwHoverTime;
// Start timer for the hover period.
IntSetTimer( pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, pDesk->dwMouseHoverTime, SystemTimerProc, TMRF_SYSTEM);
// Get windows thread message points.
point = pWnd->head.pti->ptLast;
// Set desktop mouse hover from the system default hover rectangle.
RECTL_vSetRect(&pDesk->rcMouseHover,
point.x - gspv.iMouseHoverWidth / 2,
point.y - gspv.iMouseHoverHeight / 2,
point.x + gspv.iMouseHoverWidth / 2,
point.y + gspv.iMouseHoverHeight / 2);
}
}
return TRUE;
}
BOOL
APIENTRY
NtUserTrackMouseEvent(
LPTRACKMOUSEEVENT lpEventTrack)
{
TRACKMOUSEEVENT saveTME;
BOOL Ret = FALSE;
DPRINT("Enter NtUserTrackMouseEvent\n");
UserEnterExclusive();
_SEH2_TRY
{
ProbeForRead(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1);
RtlCopyMemory(&saveTME, lpEventTrack, sizeof(TRACKMOUSEEVENT));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
_SEH2_YIELD(goto Exit;)
}
_SEH2_END;
if ( saveTME.cbSize != sizeof(TRACKMOUSEEVENT) )
{
EngSetLastError(ERROR_INVALID_PARAMETER);
goto Exit;
}
if (saveTME.dwFlags & ~(TME_CANCEL|TME_QUERY|TME_NONCLIENT|TME_LEAVE|TME_HOVER) )
{
EngSetLastError(ERROR_INVALID_FLAGS);
goto Exit;
}
if ( saveTME.dwFlags & TME_QUERY )
{
Ret = IntQueryTrackMouseEvent(&saveTME);
_SEH2_TRY
{
ProbeForWrite(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1);
RtlCopyMemory(lpEventTrack, &saveTME, sizeof(TRACKMOUSEEVENT));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
Ret = FALSE;
}
_SEH2_END;
}
else
{
Ret = IntTrackMouseEvent(&saveTME);
}
Exit:
DPRINT("Leave NtUserTrackMouseEvent, ret=%i\n",Ret);
UserLeave();
return Ret;
}
extern MOUSEMOVEPOINT MouseHistoryOfMoves[];
extern INT gcur_count;
DWORD
APIENTRY
NtUserGetMouseMovePointsEx(
UINT cbSize,
LPMOUSEMOVEPOINT lpptIn,
LPMOUSEMOVEPOINT lpptOut,
int nBufPoints,
DWORD resolution)
{
MOUSEMOVEPOINT Safeppt;
BOOL Hit;
INT Count = -1;
DECLARE_RETURN(DWORD);
DPRINT("Enter NtUserGetMouseMovePointsEx\n");
UserEnterExclusive();
if ((cbSize != sizeof(MOUSEMOVEPOINT)) || (nBufPoints < 0) || (nBufPoints > 64))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
RETURN( -1);
}
if (!lpptIn || (!lpptOut && nBufPoints))
{
EngSetLastError(ERROR_NOACCESS);
RETURN( -1);
}
_SEH2_TRY
{
ProbeForRead( lpptIn, cbSize, 1);
RtlCopyMemory(&Safeppt, lpptIn, cbSize);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
_SEH2_YIELD(RETURN( -1))
}
_SEH2_END;
// http://msdn.microsoft.com/en-us/library/ms646259(v=vs.85).aspx
// This explains the math issues in transforming points.
Count = gcur_count; // FIFO is forward so retrieve backward.
Hit = FALSE;
do
{
if (Safeppt.x == 0 && Safeppt.y == 0)
break; // No test.
// Finds the point, it returns the last nBufPoints prior to and including the supplied point.
if (MouseHistoryOfMoves[Count].x == Safeppt.x && MouseHistoryOfMoves[Count].y == Safeppt.y)
{
if ( Safeppt.time ) // Now test time and it seems to be absolute.
{
if (Safeppt.time == MouseHistoryOfMoves[Count].time)
{
Hit = TRUE;
break;
}
else
{
if (--Count < 0) Count = 63;
continue;
}
}
Hit = TRUE;
break;
}
if (--Count < 0) Count = 63;
}
while ( Count != gcur_count);
switch(resolution)
{
case GMMP_USE_DISPLAY_POINTS:
if (nBufPoints)
{
_SEH2_TRY
{
ProbeForWrite(lpptOut, cbSize, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
_SEH2_YIELD(RETURN( -1))
}
_SEH2_END;
}
Count = nBufPoints;
break;
case GMMP_USE_HIGH_RESOLUTION_POINTS:
break;
default:
EngSetLastError(ERROR_POINT_NOT_FOUND);
RETURN( -1);
}
RETURN( Count);
CLEANUP:
DPRINT("Leave NtUserGetMouseMovePointsEx, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/* EOF */

View file

@ -400,7 +400,30 @@ DWORD FASTCALL UserGetAsyncKeyState(DWORD key)
return ret;
}
/***********************************************************************
* get_key_state
*/
WORD FASTCALL get_key_state(void)
{
WORD ret = 0;
if (gpsi->aiSysMet[SM_SWAPBUTTON])
{
if (UserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON;
if (UserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON;
}
else
{
if (UserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON;
if (UserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON;
}
if (UserGetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON;
if (UserGetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT;
if (UserGetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL;
if (UserGetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1;
if (UserGetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2;
return ret;
}
SHORT
APIENTRY

View file

@ -709,14 +709,14 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF
{
return FALSE;
}
if( lpmii->fType & ~fTypeMask)
if (lpmii->fType & ~fTypeMask)
{
DbgPrint("IntSetMenuItemInfo invalid fType flags %x\n", lpmii->fType & ~fTypeMask);
lpmii->fMask &= ~(MIIM_TYPE | MIIM_FTYPE);
}
if(lpmii->fMask & MIIM_TYPE)
if (lpmii->fMask & MIIM_TYPE)
{
if(lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP))
if (lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP))
{
DbgPrint("IntSetMenuItemInfo: Invalid combination of fMask bits used\n");
/* this does not happen on Win9x/ME */
@ -2056,11 +2056,13 @@ NtUserHiliteMenuItem(
if(!(Window = UserGetWindowObject(hWnd)))
{
EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
RETURN(FALSE);
}
if(!(Menu = UserGetMenuObject(hMenu)))
{
EngSetLastError(ERROR_INVALID_MENU_HANDLE);
RETURN(FALSE);
}
@ -2228,6 +2230,9 @@ UserMenuItemInfo(
NULL, &MenuItem, NULL) < 0)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
// This will crash menu (line 80) correct_behavior test!
// "NT4 and below can't handle a bigger MENUITEMINFO struct"
//EngSetLastError(ERROR_MENU_ITEM_NOT_FOUND);
return( FALSE);
}

View file

@ -20,6 +20,8 @@
/* GLOBALS *******************************************************************/
static PAGED_LOOKASIDE_LIST MessageLookasideList;
MOUSEMOVEPOINT MouseHistoryOfMoves[64];
INT gcur_count = 0;
/* FUNCTIONS *****************************************************************/
@ -189,7 +191,7 @@ MsqPostMouseMove(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg)
}
VOID FASTCALL
co_MsqInsertMouseMessage(MSG* Msg)
co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo)
{
LARGE_INTEGER LargeTickCount;
MSLLHOOKSTRUCT MouseHookData;
@ -219,9 +221,9 @@ co_MsqInsertMouseMessage(MSG* Msg)
break;
}
MouseHookData.flags = 0;
MouseHookData.flags = flags; // LLMHF_INJECTED
MouseHookData.time = Msg->time;
MouseHookData.dwExtraInfo = 0;
MouseHookData.dwExtraInfo = dwExtraInfo;
/* If the hook procedure returned non zero, dont send the message */
if (co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData))
@ -232,11 +234,22 @@ co_MsqInsertMouseMessage(MSG* Msg)
if(!pwndDesktop)
return;
/* Set hit somewhere on the desktop */
pDesk = pwndDesktop->head.rpdesk;
pDesk->htEx = HTNOWHERE;
pDesk->spwndTrack = pwndDesktop;
/* Check if the mouse is captured */
Msg->hwnd = IntGetCaptureWindow();
if(Msg->hwnd != NULL)
{
pwnd = UserGetWindowObject(Msg->hwnd);
if ((pwnd->style & WS_VISIBLE) &&
IntPtInWindow(pwnd, Msg->pt.x, Msg->pt.y))
{
pDesk->htEx = HTCLIENT;
pDesk->spwndTrack = pwnd;
}
}
else
{
@ -255,7 +268,6 @@ co_MsqInsertMouseMessage(MSG* Msg)
IntPtInWindow(pwnd, Msg->pt.x, Msg->pt.y))
{
Msg->hwnd = pwnd->head.h;
pDesk = pwnd->head.rpdesk;
pDesk->htEx = HTCLIENT;
pDesk->spwndTrack = pwnd;
break;
@ -277,6 +289,13 @@ co_MsqInsertMouseMessage(MSG* Msg)
MsqPostMessage(pwnd->head.pti->MessageQueue, Msg, TRUE, QS_MOUSEBUTTON);
}
}
/* Do GetMouseMovePointsEx FIFO. */
MouseHistoryOfMoves[gcur_count].x = Msg->pt.x;
MouseHistoryOfMoves[gcur_count].y = Msg->pt.y;
MouseHistoryOfMoves[gcur_count].time = Msg->time;
MouseHistoryOfMoves[gcur_count].dwExtraInfo = 0; // need to be passed from IntMouseInput mi.dwExtraInfo.
if (gcur_count++ == 64) gcur_count = 0; // 0 - 63 is 64, FIFO forwards.
}
//
@ -1276,7 +1295,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
if (Remove)
{
RemoveEntryList(&CurrentMessage->ListEntry);
ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
ClearMsgBitsMask(MessageQueue, QS_INPUT);
MsqDestroyMessage(CurrentMessage);
}
@ -1336,7 +1355,7 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
if (Remove)
{
RemoveEntryList(&CurrentMessage->ListEntry);
ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
ClearMsgBitsMask(MessageQueue, QS_POSTMESSAGE);
MsqDestroyMessage(CurrentMessage);
}
return(TRUE);

View file

@ -277,56 +277,6 @@ NtUserGetImeHotKey(
return 0;
}
DWORD
APIENTRY
NtUserGetMouseMovePointsEx(
UINT cbSize,
LPMOUSEMOVEPOINT lppt,
LPMOUSEMOVEPOINT lpptBuf,
int nBufPoints,
DWORD resolution)
{
UserEnterExclusive();
if ((cbSize != sizeof(MOUSEMOVEPOINT)) || (nBufPoints < 0) || (nBufPoints > 64))
{
UserLeave();
EngSetLastError(ERROR_INVALID_PARAMETER);
return -1;
}
_SEH2_TRY
{
ProbeForRead(lppt, cbSize, 1);
ProbeForWrite(lpptBuf, cbSize, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
EngSetLastError(ERROR_NOACCESS);
}
_SEH2_END;
/*
Call a subfunction of GetMouseMovePointsEx!
switch(resolution)
{
case GMMP_USE_DISPLAY_POINTS:
case GMMP_USE_HIGH_RESOLUTION_POINTS:
break;
default:
EngSetLastError(GMMP_ERR_POINT_NOT_FOUND);
return GMMP_ERR_POINT_NOT_FOUND;
}
*/
UNIMPLEMENTED
UserLeave();
return -1;
}
BOOL
APIENTRY
NtUserImpersonateDdeClientWindow(
@ -586,17 +536,6 @@ NtUserSetThreadState(
return 0;
}
BOOL
APIENTRY
NtUserTrackMouseEvent(
LPTRACKMOUSEEVENT lpEventTrack)
{
UNIMPLEMENTED
return 0;
}
DWORD
APIENTRY
NtUserUpdateInputContext(

View file

@ -473,7 +473,7 @@ NtUserCallTwoParam(
RETURN( (DWORD_PTR)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
case TWOPARAM_ROUTINE_SETCURSORPOS:
RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2, FALSE));
RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2));
case TWOPARAM_ROUTINE_UNHOOKWINDOWSHOOK:
RETURN( IntUnhookWindowsHook((int)Param1, (HOOKPROC)Param2));

View file

@ -17,6 +17,8 @@
#define NDEBUG
#include <debug.h>
WORD FASTCALL get_key_state(void);
/* GLOBALS *******************************************************************/
static LIST_ENTRY TimersListHead;
@ -82,7 +84,7 @@ RemoveTimer(PTIMER pTmr)
{
/* Set the flag, it will be removed when ready */
RemoveEntryList(&pTmr->ptmrList);
if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM)))
if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM))) // System timers are reusable.
{
UINT_PTR IDEvent;
@ -287,7 +289,73 @@ SystemTimerProc(HWND hwnd,
UINT_PTR idEvent,
DWORD dwTime)
{
DPRINT( "Timer Running!\n" );
PDESKTOP pDesk;
PWND pWnd = NULL;
if (hwnd)
{
pWnd = UserGetWindowObject(hwnd);
if (!pWnd)
{
DPRINT1( "System Timer Proc has invalid window handle! 0x%x Id: %d\n", hwnd, idEvent);
return;
}
}
else
{
DPRINT( "Windowless Timer Running!\n" );
return;
}
switch (idEvent)
{
/*
Used in NtUserTrackMouseEvent.
*/
case ID_EVENT_SYSTIMER_MOUSEHOVER:
{
POINT Point;
UINT Msg;
WPARAM wParam;
pDesk = pWnd->head.rpdesk;
if ( pDesk->dwDTFlags & DF_TME_HOVER &&
pWnd == pDesk->spwndTrack )
{
Point = gpsi->ptCursor;
if ( IntPtInRect(&pDesk->rcMouseHover, Point) )
{
if (pDesk->htEx == HTCLIENT) // In a client area.
{
wParam = get_key_state();
Msg = WM_MOUSEHOVER;
if (pWnd->ExStyle & WS_EX_LAYOUTRTL)
{
Point.x = pWnd->rcClient.right - Point.x - 1;
}
else
Point.x -= pWnd->rcClient.left;
Point.y -= pWnd->rcClient.top;
}
else
{
wParam = pDesk->htEx; // Need to support all HTXYZ hits.
Msg = WM_NCMOUSEHOVER;
}
UserPostMessage(hwnd, Msg, wParam, MAKELPARAM(Point.x, Point.y));
pDesk->dwDTFlags &= ~DF_TME_HOVER;
break; // Kill this timer.
}
}
}
return; // Not this window so just return.
default:
DPRINT1( "System Timer Proc invalid id %d!\n", idEvent );
break;
}
IntKillTimer(pWnd, idEvent, TRUE);
}
VOID
@ -296,7 +364,9 @@ StartTheTimers(VOID)
{
// Need to start gdi syncro timers then start timer with Hang App proc
// that calles Idle process so the screen savers will know to run......
IntSetTimer(NULL, 0, 1000, SystemTimerProc, TMRF_RIT);
IntSetTimer(NULL, 0, 1000, HungAppSysTimerProc, TMRF_RIT);
// Test Timers
// IntSetTimer(NULL, 0, 1000, SystemTimerProc, TMRF_RIT);
}
UINT_PTR
@ -347,6 +417,13 @@ PostTimerMessages(PWND Window)
pTmr->flags &= ~TMRF_READY;
pti->cTimersReady++;
Hit = TRUE;
// Now move this entry to the end of the list so it will not be
// called again in the next msg loop.
if (pLE != &TimersListHead)
{
RemoveEntryList(&pTmr->ptmrList);
InsertTailList(&TimersListHead, &pTmr->ptmrList);
}
break;
}

View file

@ -1692,7 +1692,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
DPRINT("Created object with handle %X\n", hWnd);
if (NULL == pti->rpdesk->DesktopWindow)
{
{ /*HACK! Helper for win32csr/desktopbg.c */
/* If there is no desktop window yet, we must be creating it */
pti->rpdesk->DesktopWindow = hWnd;
pti->rpdesk->pDeskInfo->spwnd = pWnd;
@ -1891,7 +1891,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
return pWnd;
AllocError:
DPRINT1("IntCreateWindow Allocation Error.\n");
if(pWnd)
UserDereferenceObject(pWnd);
@ -2575,7 +2575,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
msg.wParam = IntGetSysCursorInfo()->ButtonsDown;
msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
msg.pt = gpsi->ptCursor;
co_MsqInsertMouseMessage(&msg);
co_MsqInsertMouseMessage(&msg, 0, 0);
if (!IntIsWindow(Window->head.h))
{