1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Second attempt to fix DPI unaware cursor position

See issue #319.
This commit is contained in:
narzoul 2024-06-09 16:35:09 +02:00
parent 471cd11389
commit 3d1197f863
3 changed files with 72 additions and 28 deletions

View File

@ -37,16 +37,21 @@ namespace
return LOG_RESULT(TRUE); return LOG_RESULT(TRUE);
} }
BOOL WINAPI getClipCursor(LPRECT lpRect) BOOL WINAPI getClipCursorInternal(LPRECT lpRect)
{ {
LOG_FUNC("GetClipCursor", lpRect);
Compat::ScopedCriticalSection lock(g_cs); Compat::ScopedCriticalSection lock(g_cs);
BOOL result = CALL_ORIG_FUNC(GetClipCursor)(lpRect); BOOL result = CALL_ORIG_FUNC(GetClipCursor)(lpRect);
if (result && !IsRectEmpty(&g_monitorClipRect)) if (result && !IsRectEmpty(&g_monitorClipRect))
{ {
*lpRect = g_clipRect; *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() HCURSOR WINAPI getCursor()
@ -125,31 +130,18 @@ namespace Gdi
{ {
namespace Cursor 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) void clip(POINT& pt)
{ {
Compat::ScopedCriticalSection lock(g_cs); RECT r = {};
if (!IsRectEmpty(&g_monitorClipRect)) if (!getClipCursorInternal(&r))
{ {
pt.x = std::max(pt.x, g_monitorClipRect.left); return;
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);
} }
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() CURSORINFO getEmulatedCursorInfo()

View File

@ -6,7 +6,6 @@ namespace Gdi
{ {
namespace Cursor namespace Cursor
{ {
void clip();
void clip(POINT& pt); void clip(POINT& pt);
CURSORINFO getEmulatedCursorInfo(); CURSORINFO getEmulatedCursorInfo();
void installHooks(); void installHooks();

View File

@ -92,6 +92,51 @@ namespace
return LOG_RESULT(CALL_ORIG_FUNC(AnimateWindow)(hWnd, dwTime, dwFlags)); 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<POINTS*>(&msg.lParam)->x = static_cast<SHORT>(pt.x);
reinterpret_cast<POINTS*>(&msg.lParam)->y = static_cast<SHORT>(pt.y);
}
template <auto func, typename Result, typename... Params> template <auto func, typename Result, typename... Params>
Result WINAPI createDialog(Params... params) Result WINAPI createDialog(Params... params)
{ {
@ -351,8 +396,12 @@ namespace
decltype(&GetMessageA) origGetMessage) decltype(&GetMessageA) origGetMessage)
{ {
DDraw::RealPrimarySurface::setUpdateReady(); DDraw::RealPrimarySurface::setUpdateReady();
Gdi::Cursor::clip(); BOOL result = origGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
return origGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); if (-1 != result)
{
clipMouseCoords(*lpMsg);
}
return result;
} }
BOOL WINAPI getMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) BOOL WINAPI getMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax)
@ -572,8 +621,12 @@ namespace
decltype(&PeekMessageA) origPeekMessage) decltype(&PeekMessageA) origPeekMessage)
{ {
DDraw::RealPrimarySurface::setUpdateReady(); DDraw::RealPrimarySurface::setUpdateReady();
Gdi::Cursor::clip();
BOOL result = origPeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); BOOL result = origPeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
if (result)
{
clipMouseCoords(*lpMsg);
}
if (!g_isFrameStarted || Config::Settings::FpsLimiter::MSGLOOP != Config::fpsLimiter.get()) if (!g_isFrameStarted || Config::Settings::FpsLimiter::MSGLOOP != Config::fpsLimiter.get())
{ {
return result; return result;