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.
This commit is contained in:
Maarten Bent
2020-05-31 23:16:20 +02:00
parent e59a5d17da
commit 5166ddea2b

View File

@@ -36,6 +36,8 @@
#include "wx/module.h" #include "wx/module.h"
#endif #endif
#include "wx/display.h"
#include "wx/msw/private.h" #include "wx/msw/private.h"
#include "wx/msw/missing.h" // IDC_HAND #include "wx/msw/missing.h" // IDC_HAND
@@ -263,12 +265,20 @@ wxPoint wxCursor::GetHotSpot() const
namespace 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; MemoryHDC hdc;
SelectInHDC selBitmap(hdc, bitmap); SelectInHDC selBitmap(hdc, bitmap);
::StretchBlt(hdc, width - 1, 0, -width, height, if ( scale != 1 )
hdc, 0, 0, width, height, SRCCOPY); ::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) HCURSOR CreateReverseCursor(HCURSOR cursor)
@@ -277,14 +287,15 @@ HCURSOR CreateReverseCursor(HCURSOR cursor)
if ( !info.GetFrom(cursor) ) if ( !info.GetFrom(cursor) )
return NULL; return NULL;
BITMAP bmp; const unsigned displayID = (unsigned)wxDisplay::GetFromPoint(wxGetMousePosition());
if ( !::GetObject(info.hbmMask, sizeof(bmp), &bmp) ) wxDisplay disp(displayID == 0u || displayID < wxDisplay::GetCount() ? displayID : 0u);
return NULL; 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 ) if ( info.hbmColor )
ReverseBitmap(info.hbmColor, bmp.bmWidth, bmp.bmHeight); ScaleAndReverseBitmap(info.hbmColor, scale);
info.xHotspot = (DWORD)bmp.bmWidth - 1 - info.xHotspot; info.xHotspot = (DWORD)(cursorSize.x - 1 - info.xHotspot * scale);
info.yHotspot = (DWORD)(info.yHotspot * scale);
return ::CreateIconIndirect(&info); return ::CreateIconIndirect(&info);
} }