diff --git a/DDrawCompat/Gdi/Cursor.cpp b/DDrawCompat/Gdi/Cursor.cpp index a277f79..8d93eb8 100644 --- a/DDrawCompat/Gdi/Cursor.cpp +++ b/DDrawCompat/Gdi/Cursor.cpp @@ -37,16 +37,21 @@ namespace return LOG_RESULT(TRUE); } - BOOL WINAPI getClipCursor(LPRECT lpRect) + BOOL WINAPI getClipCursorInternal(LPRECT lpRect) { - LOG_FUNC("GetClipCursor", lpRect); Compat::ScopedCriticalSection lock(g_cs); BOOL result = CALL_ORIG_FUNC(GetClipCursor)(lpRect); if (result && !IsRectEmpty(&g_monitorClipRect)) { *lpRect = g_clipRect; } - return LOG_RESULT(result); + return result; + } + + BOOL WINAPI getClipCursor(LPRECT lpRect) + { + LOG_FUNC("GetClipCursor", lpRect); + return LOG_RESULT(getClipCursorInternal(lpRect)); } HCURSOR WINAPI getCursor() @@ -125,31 +130,18 @@ namespace Gdi { namespace Cursor { - void clip() - { - Compat::ScopedCriticalSection lock(g_cs); - if (!IsRectEmpty(&g_monitorClipRect)) - { - POINT cp = {}; - CALL_ORIG_FUNC(GetCursorPos)(&cp); - if (!PtInRect(&g_monitorClipRect, cp)) - { - clip(cp); - CALL_ORIG_FUNC(SetCursorPos)(cp.x, cp.y); - } - } - } - void clip(POINT& pt) { - Compat::ScopedCriticalSection lock(g_cs); - if (!IsRectEmpty(&g_monitorClipRect)) + RECT r = {}; + if (!getClipCursorInternal(&r)) { - pt.x = std::max(pt.x, g_monitorClipRect.left); - pt.x = std::min(pt.x, g_monitorClipRect.right); - pt.y = std::max(pt.y, g_monitorClipRect.top); - pt.y = std::min(pt.y, g_monitorClipRect.bottom); + return; } + + pt.x = std::max(pt.x, r.left); + pt.x = std::min(pt.x, r.right); + pt.y = std::max(pt.y, r.top); + pt.y = std::min(pt.y, r.bottom); } CURSORINFO getEmulatedCursorInfo() diff --git a/DDrawCompat/Gdi/Cursor.h b/DDrawCompat/Gdi/Cursor.h index d98a205..68cf8df 100644 --- a/DDrawCompat/Gdi/Cursor.h +++ b/DDrawCompat/Gdi/Cursor.h @@ -6,7 +6,6 @@ namespace Gdi { namespace Cursor { - void clip(); void clip(POINT& pt); CURSORINFO getEmulatedCursorInfo(); void installHooks(); diff --git a/DDrawCompat/Gdi/WinProc.cpp b/DDrawCompat/Gdi/WinProc.cpp index 4834196..4825260 100644 --- a/DDrawCompat/Gdi/WinProc.cpp +++ b/DDrawCompat/Gdi/WinProc.cpp @@ -92,6 +92,51 @@ namespace return LOG_RESULT(CALL_ORIG_FUNC(AnimateWindow)(hWnd, dwTime, dwFlags)); } + void clipMouseCoords(MSG& msg) + { + Gdi::Cursor::clip(msg.pt); + + bool isClient = false; + if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST) + { + isClient = WM_MOUSEWHEEL != msg.message && WM_MOUSEHWHEEL != msg.message; + } + else if (msg.message >= WM_NCMOUSEMOVE && msg.message <= WM_NCMBUTTONDBLCLK || + msg.message >= WM_NCXBUTTONDOWN && msg.message <= WM_NCXBUTTONDBLCLK || + WM_NCHITTEST == msg.message) + { + isClient = false; + } + else if (WM_MOUSEHOVER == msg.message || + WM_NCMOUSEHOVER == msg.message) + { + isClient = true; + } + else + { + return; + } + + POINT pt = {}; + pt.x = GET_X_LPARAM(msg.lParam); + pt.y = GET_Y_LPARAM(msg.lParam); + + if (isClient) + { + ClientToScreen(msg.hwnd, &pt); + } + + Gdi::Cursor::clip(pt); + + if (isClient) + { + ScreenToClient(msg.hwnd, &pt); + } + + reinterpret_cast(&msg.lParam)->x = static_cast(pt.x); + reinterpret_cast(&msg.lParam)->y = static_cast(pt.y); + } + template Result WINAPI createDialog(Params... params) { @@ -351,8 +396,12 @@ namespace decltype(&GetMessageA) origGetMessage) { DDraw::RealPrimarySurface::setUpdateReady(); - Gdi::Cursor::clip(); - return origGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); + BOOL result = origGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); + if (-1 != result) + { + clipMouseCoords(*lpMsg); + } + return result; } BOOL WINAPI getMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) @@ -572,8 +621,12 @@ namespace decltype(&PeekMessageA) origPeekMessage) { DDraw::RealPrimarySurface::setUpdateReady(); - Gdi::Cursor::clip(); BOOL result = origPeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); + if (result) + { + clipMouseCoords(*lpMsg); + } + if (!g_isFrameStarted || Config::Settings::FpsLimiter::MSGLOOP != Config::fpsLimiter.get()) { return result;