diff --git "a/win32ss/user/ntuser/cursoricon.c" "b/win32ss/user/ntuser/cursoricon.c" index 6560a44852d..4d52d011f0e 100644 --- "a/win32ss/user/ntuser/cursoricon.c" +++ "b/win32ss/user/ntuser/cursoricon.c" @@ -23,6 +23,7 @@ DBG_DEFAULT_CHANNEL(UserIcon); SYSTEM_CURSORINFO gSysCursorInfo; +PWND FASTCALL IntTopLevelWindowFromPoint(INT x, INT y); PCURICON_OBJECT gcurFirst = NULL; // After all is done, this should be WINLOGO! @@ -242,12 +243,52 @@ BOOL UserSetCursorPos( INT x, INT y, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Ho MSG Msg; RECTL rcClip; POINT pt; + BOOL mmNeeded = FALSE; // Mouse Move Needed + PWND pWnd = NULL; + HWND hWnd = NULL; + UNICODE_STRING ucClassName, *pucClassName = &ucClassName; + UNICODE_STRING ucWindowName, *pucWindowName = NULL; + WCHAR MyClass[50] = L"ConsoleWindowClass"; + PWND Parent; + RTL_ATOM ClassAtom = (RTL_ATOM)0; + HWND Desktop = NULL; if (!(DesktopWindow = UserGetDesktopWindow())) { return FALSE; } + /* We need different mouse events if we are in a Console Window. + * We detect this by getting a HWND to any Console Window + * under our cursor, using the next few lines of code. */ + + /* Get the PWND for the Window under our cursor */ + pWnd = IntTopLevelWindowFromPoint(gpsi->ptCursor.x, gpsi->ptCursor.y); + + /* Get the PUNICODE_STRING for our ClassName that we defined above. */ + RtlInitUnicodeString(&ucClassName, MyClass); + pucClassName = &ucClassName; + + /* Get the PUNICODE_STRING for our Window Name if we retrieved one + * using the IntTopLevelWindowFromPoint above. */ + if (pWnd->strName.Buffer != NULL) + { + RtlInitUnicodeString(&ucWindowName, pWnd->strName.Buffer); + pucWindowName = &ucWindowName; + } + + Desktop = IntGetDesktopWindow(); + Parent = UserGetWindowObject(Desktop); + IntGetAtomFromStringOrAtom(pucClassName, &ClassAtom); + + /* This checks for errors on the above conversions */ + if (pucWindowName && Parent && ClassAtom) + /* Find the HWND or any Console Window under our cursor */ + hWnd = IntFindWindow(Parent, NULL, ClassAtom, pucWindowName); + + /* hWnd will be NULL or the HWND if over a console window. */ + TRACE("Got hWnd %p\n", hWnd); + CurInfo = IntGetSysCursorInfo(); /* Clip cursor position */ @@ -264,13 +305,43 @@ BOOL UserSetCursorPos( INT x, INT y, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Ho pt.x = x; pt.y = y; - /* 1. Generate a mouse move message, this sets the htEx and Track Window too. */ - Msg.message = WM_MOUSEMOVE; - Msg.wParam = UserGetMouseButtonsState(); - Msg.lParam = MAKELPARAM(x, y); - Msg.pt = pt; - co_MsqInsertMouseMessage(&Msg, flags, dwExtraInfo, Hook); + /* Handle mouse button up events */ + if (CurInfo->LRLastDown == TRUE && !(CurInfo->ButtonsDown & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON))) + { + if (CurInfo->LDblClk) + { + mmNeeded = FALSE; + CurInfo->LDblClk = FALSE; + } + else + mmNeeded = TRUE; + } + + /* Handle mouse button down events */ + if (CurInfo->ButtonsDown & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON)) + { + /* If Console Window, provide for extra mouse move on button up */ + if (hWnd) + CurInfo->LRLastDown = TRUE; + } + else + /* If no mouse down buttons, reset flags */ + { + CurInfo->LRLastDown = FALSE; + CurInfo->LDblClk = FALSE; + } + + /* I_Kill_Bugs patch for mouse moves + my mmNeeded to add back a few. */ + if ((gpsi->ptCursor.x != x) || (gpsi->ptCursor.y != y) || mmNeeded) + { + /* 1. Generate a mouse move message, this sets the htEx and Track Window too. */ + Msg.message = WM_MOUSEMOVE; + Msg.wParam = UserGetMouseButtonsState(); + Msg.lParam = MAKELPARAM(x, y); + Msg.pt = pt; + co_MsqInsertMouseMessage(&Msg, flags, dwExtraInfo, Hook); + } /* 2. Store the new cursor position */ gpsi->ptCursor = pt;