[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*/ /* Critical Section*/
extern RTL_CRITICAL_SECTION User32Crit; 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. */ /* FIXME: Belongs to some header. */
BOOL WINAPI GdiDllInitialize(HANDLE, DWORD, LPVOID); BOOL WINAPI GdiDllInitialize(HANDLE, DWORD, LPVOID);
void InitStockObjects(void); void InitStockObjects(void);

View file

@ -17,13 +17,6 @@ BOOL gfServerProcess = FALSE;
WCHAR szAppInit[KEY_LENGTH]; WCHAR szAppInit[KEY_LENGTH];
PUSER32_THREAD_DATA
User32GetThreadData()
{
return ((PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex));
}
BOOL BOOL
GetDllList() GetDllList()
{ {
@ -192,25 +185,12 @@ UnloadAppInitDlls()
BOOL BOOL
InitThread(VOID) 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; return TRUE;
} }
VOID VOID
CleanupThread(VOID) CleanupThread(VOID)
{ {
PUSER32_THREAD_DATA ThreadData;
ThreadData = (PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex);
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ThreadData);
TlsSetValue(User32TlsIndex, 0);
} }
BOOL BOOL

View file

@ -690,7 +690,7 @@
@ stdcall ToAsciiEx(long long ptr ptr long long) @ stdcall ToAsciiEx(long long ptr ptr long long)
@ stdcall ToUnicode(long long ptr ptr long long) @ stdcall ToUnicode(long long ptr ptr long long)
@ stdcall ToUnicodeEx(long long ptr ptr long 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 TrackPopupMenu(long long long long long long ptr)
@ stdcall TrackPopupMenuEx(long long long long long ptr) ; Direct call NtUserTrackPopupMenuEx @ stdcall TrackPopupMenuEx(long long long long long ptr) ; Direct call NtUserTrackPopupMenuEx
@ stdcall TranslateAccelerator(long long ptr) TranslateAcceleratorA @ stdcall TranslateAccelerator(long long ptr) TranslateAcceleratorA

View file

@ -530,242 +530,4 @@ mouse_event(
NtUserSendInput(1, &Input, sizeof(INPUT)); 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 */ /* 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); INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags);
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon); PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon);
BOOL UserSetCursorPos( INT x, INT y, BOOL SendMouseMoveMsg); BOOL UserSetCursorPos( INT x, INT y);
int UserShowCursor(BOOL bShow); int UserShowCursor(BOOL bShow);

View file

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

View file

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

View file

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

View file

@ -24,6 +24,12 @@ typedef struct _TIMER
#define TMRF_WAITING 0x0020 #define TMRF_WAITING 0x0020
#define TMRF_TIFROMWND 0x0040 #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; extern PKTIMER MasterTimer;
INIT_FUNCTION 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* PURPOSE: Window classes * PURPOSE: Window accelerator
* FILE: subsys/win32k/ntuser/class.c * FILE: subsystems/win32/win32k/ntuser/accelerator.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISION HISTORY: * REVISION HISTORY:
* 06-06-2001 CSH Created * 06-06-2001 CSH Created
@ -105,10 +86,14 @@ co_IntTranslateAccelerator(
WORD key, WORD key,
WORD cmd) WORD cmd)
{ {
INT mask = 0;
UINT mesg = 0; UINT mesg = 0;
HWND hWnd;
ASSERT_REFS_CO(Window); 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", 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); Window->head.h, message, wParam, lParam, fVirt, key, cmd);
@ -117,22 +102,6 @@ co_IntTranslateAccelerator(
return FALSE; return FALSE;
} }
if (message == WM_CHAR)
{
if (!(fVirt & FALT) && !(fVirt & FVIRTKEY))
{
DPRINT("found accel for WM_CHAR: ('%c')\n", wParam & 0xff);
goto found;
}
}
else
{
if ((fVirt & FVIRTKEY) > 0)
{
INT mask = 0;
DPRINT("found accel for virt_key %04x (scan %04x)\n",
wParam, 0xff & HIWORD(lParam));
DPRINT("NtUserGetKeyState(VK_SHIFT) = 0x%x\n", DPRINT("NtUserGetKeyState(VK_SHIFT) = 0x%x\n",
UserGetKeyState(VK_SHIFT)); UserGetKeyState(VK_SHIFT));
DPRINT("NtUserGetKeyState(VK_CONTROL) = 0x%x\n", DPRINT("NtUserGetKeyState(VK_CONTROL) = 0x%x\n",
@ -140,14 +109,26 @@ co_IntTranslateAccelerator(
DPRINT("NtUserGetKeyState(VK_MENU) = 0x%x\n", DPRINT("NtUserGetKeyState(VK_MENU) = 0x%x\n",
UserGetKeyState(VK_MENU)); UserGetKeyState(VK_MENU));
if (UserGetKeyState(VK_SHIFT) & 0x8000) if (UserGetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
mask |= FSHIFT; if (UserGetKeyState(VK_MENU) & 0x8000) mask |= FALT;
if (UserGetKeyState(VK_CONTROL) & 0x8000) if (UserGetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
mask |= FCONTROL;
if (UserGetKeyState(VK_MENU) & 0x8000) if (message == WM_CHAR || message == WM_SYSCHAR)
mask |= FALT; {
if (mask == (fVirt & (FSHIFT | FCONTROL | FALT))) if ( !(fVirt & FVIRTKEY) && (mask & FALT) == (fVirt & FALT) )
{
DPRINT("found accel for WM_CHAR: ('%c')\n", LOWORD(wParam) & 0xff);
goto found; goto found;
}
}
else
{
if (fVirt & FVIRTKEY)
{
DPRINT("found accel for virt_key %04x (scan %04x)\n",
wParam, 0xff & HIWORD(lParam));
if (mask == (fVirt & (FSHIFT | FCONTROL | FALT))) goto found;
DPRINT("but incorrect SHIFT/CTRL/ALT-state\n"); DPRINT("but incorrect SHIFT/CTRL/ALT-state\n");
} }
else else
@ -156,7 +137,7 @@ co_IntTranslateAccelerator(
{ {
if ((fVirt & FALT) && (lParam & 0x20000000)) if ((fVirt & FALT) && (lParam & 0x20000000))
{ /* ^^ ALT pressed */ { /* ^^ ALT pressed */
DPRINT("found accel for Alt-%c\n", wParam & 0xff); DPRINT("found accel for Alt-%c\n", LOWORD(wParam) & 0xff);
goto found; goto found;
} }
} }
@ -173,49 +154,89 @@ found:
mesg = 1; mesg = 1;
else if (IntGetCaptureWindow()) else if (IntGetCaptureWindow())
mesg = 2; mesg = 2;
else if (!IntIsWindowVisible(Window)) /* FIXME: WINE IsWindowEnabled == IntIsWindowVisible? */ else if (Window->style & WS_DISABLED)
mesg = 3; mesg = 3;
else else
{ {
#if 0 #if 0
HMENU hMenu, hSubMenu, hSysMenu; HMENU hMenu, hSubMenu, hSysMenu;
UINT uSysStat = (UINT)-1, uStat = (UINT)-1, nPos; 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); // hMenu = (UserGetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ? 0 : GetMenu(hWnd);
hSysMenu = get_win_sys_menu(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 */ /* find menu item and ask application to initialize it */
/* 1. in the system menu */ /* 1. in the system menu */
hSubMenu = hSysMenu; hSubMenu = hSysMenu;
nPos = cmd; // nPos = cmd;
if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) // if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
nPos = IntGetMenuItemByFlag( MenuObject,
cmd,
MF_BYCOMMAND,
&SubMenu,
&MenuItem,
NULL);
if (MenuItem && (nPos != (UINT)-1))
{
hSubMenu = MenuItem.hSubMenu;
if (IntGetCaptureWindow())
mesg = 2;
if (Window->style & WS_DISABLED)
mesg = 3;
else
{ {
co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L); co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L);
if(hSubMenu != hSysMenu) if(hSubMenu != hSysMenu)
{ {
nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu); nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu);
TRACE_(accel)("hSysMenu = %p, hSubMenu = %p, nPos = %d\n", hSysMenu, hSubMenu, nPos); DPRINT("hSysMenu = %p, hSubMenu = %p, nPos = %d\n", hSysMenu, hSubMenu, nPos);
co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE)); 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 */ else /* 2. in the window's menu */
{ {
MenuObject = IntGetMenuObject(hMenu);
hSubMenu = hMenu; hSubMenu = hMenu;
nPos = cmd; // nPos = cmd;
if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) // if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
nPos = IntGetMenuItemByFlag( MenuObject,
cmd,
MF_BYCOMMAND,
&SubMenu,
&MenuItem,
NULL);
if (MenuItem && (nPos != (UINT)-1))
{
if (IntGetCaptureWindow())
mesg = 2;
if (Window->style & WS_DISABLED)
mesg = 3;
else
{ {
co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L); co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L);
if(hSubMenu != hMenu) if(hSubMenu != hMenu)
{ {
nPos = MENU_FindSubMenu(&hMenu, hSubMenu); nPos = MENU_FindSubMenu(&hMenu, hSubMenu);
TRACE_(accel)("hMenu = %p, hSubMenu = %p, nPos = %d\n", hMenu, hSubMenu, nPos); DPRINT("hMenu = %p, hSubMenu = %p, nPos = %d\n", hMenu, hSubMenu, nPos);
co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE)); co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE));
} }
uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND); uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND);
} }
} }
}
if (mesg == 0)
{
if (uSysStat != (UINT)-1) if (uSysStat != (UINT)-1)
{ {
if (uSysStat & (MF_DISABLED|MF_GRAYED)) if (uSysStat & (MF_DISABLED|MF_GRAYED))
@ -227,7 +248,7 @@ found:
{ {
if (uStat != (UINT)-1) if (uStat != (UINT)-1)
{ {
if (IsIconic(hWnd)) if (Window->style & WS_MINIMIZE)
mesg=5; mesg=5;
else else
{ {
@ -242,11 +263,11 @@ found:
mesg=WM_COMMAND; mesg=WM_COMMAND;
} }
} }
}
#else #else
DPRINT1("Menu search not implemented\n"); DPRINT1("Menu search not implemented\n");
mesg = WM_COMMAND; mesg = WM_COMMAND;
#endif #endif
} }
if (mesg == WM_COMMAND) if (mesg == WM_COMMAND)

View file

@ -510,6 +510,8 @@ co_IntCallHookProc(INT HookId,
UserEnterCo(); UserEnterCo();
if (ResultPointer)
{
_SEH2_TRY _SEH2_TRY
{ {
ProbeForRead(ResultPointer, sizeof(LRESULT), 1); ProbeForRead(ResultPointer, sizeof(LRESULT), 1);
@ -522,6 +524,11 @@ co_IntCallHookProc(INT HookId,
Hit = TRUE; Hit = TRUE;
} }
_SEH2_END; _SEH2_END;
}
else
{
DPRINT1("ERROR: Hook ResultPointer 0x%x ResultLength %d\n",ResultPointer,ResultLength);
}
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {

View file

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

View file

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

View file

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

View file

@ -53,7 +53,7 @@ DWORD IntLastInputTick(BOOL LastInputTickSetGet);
if(mi.dx != 0 || mi.dy != 0) \ if(mi.dx != 0 || mi.dy != 0) \
mi.dwFlags |= MOUSEEVENTF_MOVE; \ mi.dwFlags |= MOUSEEVENTF_MOVE; \
if(mi.dwFlags) \ if(mi.dwFlags) \
IntMouseInput(&mi); \ IntMouseInput(&mi,FALSE); \
ClearMouseInput(mi); ClearMouseInput(mi);
@ -481,6 +481,7 @@ IntKeyboardSendWinKeyMsg()
static VOID APIENTRY static VOID APIENTRY
co_IntKeyboardSendAltKeyMsg() co_IntKeyboardSendAltKeyMsg()
{ {
DPRINT1("co_IntKeyboardSendAltKeyMsg\n");
co_MsqPostKeyboardMessage(WM_SYSCOMMAND,SC_KEYMENU,0); co_MsqPostKeyboardMessage(WM_SYSCOMMAND,SC_KEYMENU,0);
} }
@ -1073,7 +1074,7 @@ CLEANUP:
} }
BOOL FASTCALL BOOL FASTCALL
IntMouseInput(MOUSEINPUT *mi) IntMouseInput(MOUSEINPUT *mi, BOOL Injected)
{ {
const UINT SwapBtnMsg[2][2] = const UINT SwapBtnMsg[2][2] =
{ {
@ -1137,7 +1138,7 @@ IntMouseInput(MOUSEINPUT *mi)
if(mi->dwFlags & MOUSEEVENTF_MOVE) if(mi->dwFlags & MOUSEEVENTF_MOVE)
{ {
UserSetCursorPos(MousePos.x, MousePos.y, TRUE); UserSetCursorPos(MousePos.x, MousePos.y);
} }
if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN) if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
{ {
@ -1145,7 +1146,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[0][SwapButtons]; Msg.message = SwapBtnMsg[0][SwapButtons];
CurInfo->ButtonsDown |= SwapBtn[SwapButtons]; CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown; Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
else if(mi->dwFlags & MOUSEEVENTF_LEFTUP) else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
{ {
@ -1153,7 +1154,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[1][SwapButtons]; Msg.message = SwapBtnMsg[1][SwapButtons];
CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons]; CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown; Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN) if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
{ {
@ -1161,7 +1162,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = WM_MBUTTONDOWN; Msg.message = WM_MBUTTONDOWN;
CurInfo->ButtonsDown |= MK_MBUTTON; CurInfo->ButtonsDown |= MK_MBUTTON;
Msg.wParam |= CurInfo->ButtonsDown; Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP) else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
{ {
@ -1169,7 +1170,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = WM_MBUTTONUP; Msg.message = WM_MBUTTONUP;
CurInfo->ButtonsDown &= ~MK_MBUTTON; CurInfo->ButtonsDown &= ~MK_MBUTTON;
Msg.wParam |= CurInfo->ButtonsDown; Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN) if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
{ {
@ -1177,7 +1178,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[0][!SwapButtons]; Msg.message = SwapBtnMsg[0][!SwapButtons];
CurInfo->ButtonsDown |= SwapBtn[!SwapButtons]; CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown; Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP) else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
{ {
@ -1185,7 +1186,7 @@ IntMouseInput(MOUSEINPUT *mi)
Msg.message = SwapBtnMsg[1][!SwapButtons]; Msg.message = SwapBtnMsg[1][!SwapButtons];
CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons]; CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
Msg.wParam |= CurInfo->ButtonsDown; Msg.wParam |= CurInfo->ButtonsDown;
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
if((mi->dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) && if((mi->dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) &&
@ -1203,14 +1204,14 @@ IntMouseInput(MOUSEINPUT *mi)
gQueueKeyStateTable[VK_XBUTTON1] |= 0xc0; gQueueKeyStateTable[VK_XBUTTON1] |= 0xc0;
CurInfo->ButtonsDown |= MK_XBUTTON1; CurInfo->ButtonsDown |= MK_XBUTTON1;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1); Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
if(mi->mouseData & XBUTTON2) if(mi->mouseData & XBUTTON2)
{ {
gQueueKeyStateTable[VK_XBUTTON2] |= 0xc0; gQueueKeyStateTable[VK_XBUTTON2] |= 0xc0;
CurInfo->ButtonsDown |= MK_XBUTTON2; CurInfo->ButtonsDown |= MK_XBUTTON2;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2); Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
} }
else if(mi->dwFlags & MOUSEEVENTF_XUP) else if(mi->dwFlags & MOUSEEVENTF_XUP)
@ -1221,28 +1222,28 @@ IntMouseInput(MOUSEINPUT *mi)
gQueueKeyStateTable[VK_XBUTTON1] &= ~0x80; gQueueKeyStateTable[VK_XBUTTON1] &= ~0x80;
CurInfo->ButtonsDown &= ~MK_XBUTTON1; CurInfo->ButtonsDown &= ~MK_XBUTTON1;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1); Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
if(mi->mouseData & XBUTTON2) if(mi->mouseData & XBUTTON2)
{ {
gQueueKeyStateTable[VK_XBUTTON2] &= ~0x80; gQueueKeyStateTable[VK_XBUTTON2] &= ~0x80;
CurInfo->ButtonsDown &= ~MK_XBUTTON2; CurInfo->ButtonsDown &= ~MK_XBUTTON2;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2); Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
} }
if(mi->dwFlags & MOUSEEVENTF_WHEEL) if(mi->dwFlags & MOUSEEVENTF_WHEEL)
{ {
Msg.message = WM_MOUSEWHEEL; Msg.message = WM_MOUSEWHEEL;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, mi->mouseData); Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, mi->mouseData);
co_MsqInsertMouseMessage(&Msg); co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo);
} }
return TRUE; return TRUE;
} }
BOOL FASTCALL BOOL FASTCALL
IntKeyboardInput(KEYBDINPUT *ki) IntKeyboardInput(KEYBDINPUT *ki, BOOL Injected)
{ {
PUSER_MESSAGE_QUEUE FocusMessageQueue; PUSER_MESSAGE_QUEUE FocusMessageQueue;
MSG Msg; MSG Msg;
@ -1346,6 +1347,7 @@ IntKeyboardInput(KEYBDINPUT *ki)
KbdHookData.vkCode = vk_hook; KbdHookData.vkCode = vk_hook;
KbdHookData.scanCode = ki->wScan; KbdHookData.scanCode = ki->wScan;
KbdHookData.flags = flags >> 8; KbdHookData.flags = flags >> 8;
if (Injected) KbdHookData.flags |= LLKHF_INJECTED;
KbdHookData.time = Msg.time; KbdHookData.time = Msg.time;
KbdHookData.dwExtraInfo = ki->dwExtraInfo; KbdHookData.dwExtraInfo = ki->dwExtraInfo;
if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData)) if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
@ -1510,13 +1512,13 @@ NtUserSendInput(
switch(SafeInput.type) switch(SafeInput.type)
{ {
case INPUT_MOUSE: case INPUT_MOUSE:
if(IntMouseInput(&SafeInput.mi)) if(IntMouseInput(&SafeInput.mi, TRUE))
{ {
cnt++; cnt++;
} }
break; break;
case INPUT_KEYBOARD: case INPUT_KEYBOARD:
if(IntKeyboardInput(&SafeInput.ki)) if(IntKeyboardInput(&SafeInput.ki, TRUE))
{ {
cnt++; cnt++;
} }
@ -1541,4 +1543,280 @@ CLEANUP:
END_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 */ /* EOF */

View file

@ -400,7 +400,30 @@ DWORD FASTCALL UserGetAsyncKeyState(DWORD key)
return ret; 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 SHORT
APIENTRY APIENTRY

View file

@ -709,14 +709,14 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF
{ {
return FALSE; return FALSE;
} }
if( lpmii->fType & ~fTypeMask) if (lpmii->fType & ~fTypeMask)
{ {
DbgPrint("IntSetMenuItemInfo invalid fType flags %x\n", lpmii->fType & ~fTypeMask); DbgPrint("IntSetMenuItemInfo invalid fType flags %x\n", lpmii->fType & ~fTypeMask);
lpmii->fMask &= ~(MIIM_TYPE | MIIM_FTYPE); 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"); DbgPrint("IntSetMenuItemInfo: Invalid combination of fMask bits used\n");
/* this does not happen on Win9x/ME */ /* this does not happen on Win9x/ME */
@ -2056,11 +2056,13 @@ NtUserHiliteMenuItem(
if(!(Window = UserGetWindowObject(hWnd))) if(!(Window = UserGetWindowObject(hWnd)))
{ {
EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
RETURN(FALSE); RETURN(FALSE);
} }
if(!(Menu = UserGetMenuObject(hMenu))) if(!(Menu = UserGetMenuObject(hMenu)))
{ {
EngSetLastError(ERROR_INVALID_MENU_HANDLE);
RETURN(FALSE); RETURN(FALSE);
} }
@ -2228,6 +2230,9 @@ UserMenuItemInfo(
NULL, &MenuItem, NULL) < 0) NULL, &MenuItem, NULL) < 0)
{ {
EngSetLastError(ERROR_INVALID_PARAMETER); 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); return( FALSE);
} }

View file

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

View file

@ -277,56 +277,6 @@ NtUserGetImeHotKey(
return 0; 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 BOOL
APIENTRY APIENTRY
NtUserImpersonateDdeClientWindow( NtUserImpersonateDdeClientWindow(
@ -586,17 +536,6 @@ NtUserSetThreadState(
return 0; return 0;
} }
BOOL
APIENTRY
NtUserTrackMouseEvent(
LPTRACKMOUSEEVENT lpEventTrack)
{
UNIMPLEMENTED
return 0;
}
DWORD DWORD
APIENTRY APIENTRY
NtUserUpdateInputContext( NtUserUpdateInputContext(

View file

@ -473,7 +473,7 @@ NtUserCallTwoParam(
RETURN( (DWORD_PTR)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2)); RETURN( (DWORD_PTR)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
case TWOPARAM_ROUTINE_SETCURSORPOS: 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: case TWOPARAM_ROUTINE_UNHOOKWINDOWSHOOK:
RETURN( IntUnhookWindowsHook((int)Param1, (HOOKPROC)Param2)); RETURN( IntUnhookWindowsHook((int)Param1, (HOOKPROC)Param2));

View file

@ -17,6 +17,8 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
WORD FASTCALL get_key_state(void);
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
static LIST_ENTRY TimersListHead; static LIST_ENTRY TimersListHead;
@ -82,7 +84,7 @@ RemoveTimer(PTIMER pTmr)
{ {
/* Set the flag, it will be removed when ready */ /* Set the flag, it will be removed when ready */
RemoveEntryList(&pTmr->ptmrList); 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; UINT_PTR IDEvent;
@ -287,7 +289,73 @@ SystemTimerProc(HWND hwnd,
UINT_PTR idEvent, UINT_PTR idEvent,
DWORD dwTime) 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 VOID
@ -296,7 +364,9 @@ StartTheTimers(VOID)
{ {
// Need to start gdi syncro timers then start timer with Hang App proc // 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...... // 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 UINT_PTR
@ -347,6 +417,13 @@ PostTimerMessages(PWND Window)
pTmr->flags &= ~TMRF_READY; pTmr->flags &= ~TMRF_READY;
pti->cTimersReady++; pti->cTimersReady++;
Hit = TRUE; 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; break;
} }

View file

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