From 5166ddea2bf02dc422b70824f121d65e23b56427 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 31 May 2020 23:16:20 +0200 Subject: [PATCH] Create cursors with correct size when DPI changes GetIconInfo does not return DPI aware results. Adjust it to the DPI of the display that shows the cursor. --- src/msw/cursor.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/msw/cursor.cpp b/src/msw/cursor.cpp index d57f980ea5..47b0caeed1 100644 --- a/src/msw/cursor.cpp +++ b/src/msw/cursor.cpp @@ -36,6 +36,8 @@ #include "wx/module.h" #endif +#include "wx/display.h" + #include "wx/msw/private.h" #include "wx/msw/missing.h" // IDC_HAND @@ -263,12 +265,20 @@ wxPoint wxCursor::GetHotSpot() const namespace { -void ReverseBitmap(HBITMAP bitmap, int width, int height) +wxSize ScaleAndReverseBitmap(HBITMAP& bitmap, float scale) { + BITMAP bmp; + if ( !::GetObject(bitmap, sizeof(bmp), &bmp) ) + return wxSize(); + wxSize cs(bmp.bmWidth * scale, bmp.bmHeight * scale); + MemoryHDC hdc; SelectInHDC selBitmap(hdc, bitmap); - ::StretchBlt(hdc, width - 1, 0, -width, height, - hdc, 0, 0, width, height, SRCCOPY); + if ( scale != 1 ) + ::SetStretchBltMode(hdc, HALFTONE); + ::StretchBlt(hdc, cs.x - 1, 0, -cs.x, cs.y, hdc, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); + + return cs; } HCURSOR CreateReverseCursor(HCURSOR cursor) @@ -277,14 +287,15 @@ HCURSOR CreateReverseCursor(HCURSOR cursor) if ( !info.GetFrom(cursor) ) return NULL; - BITMAP bmp; - if ( !::GetObject(info.hbmMask, sizeof(bmp), &bmp) ) - return NULL; + const unsigned displayID = (unsigned)wxDisplay::GetFromPoint(wxGetMousePosition()); + wxDisplay disp(displayID == 0u || displayID < wxDisplay::GetCount() ? displayID : 0u); + const float scale = (float)disp.GetPPI().y / wxGetDisplayPPI().y; - ReverseBitmap(info.hbmMask, bmp.bmWidth, bmp.bmHeight); + wxSize cursorSize = ScaleAndReverseBitmap(info.hbmMask, scale); if ( info.hbmColor ) - ReverseBitmap(info.hbmColor, bmp.bmWidth, bmp.bmHeight); - info.xHotspot = (DWORD)bmp.bmWidth - 1 - info.xHotspot; + ScaleAndReverseBitmap(info.hbmColor, scale); + info.xHotspot = (DWORD)(cursorSize.x - 1 - info.xHotspot * scale); + info.yHotspot = (DWORD)(info.yHotspot * scale); return ::CreateIconIndirect(&info); }