1

A C++ Windows application desires to annotate the cursor bitmap with a small colored icon which conveys context dependent information, i.e. while hovering specific items. User preferences are to be respected, thus the system cursor must be modified instead of using an application specific cursor.

  • If the modified bitmap exists a new cursor can be created by a CreateIconIndirect API call.

  • We can create the modified bitmap by pixel manipulation of the original cursor bitmap.

  • We have access to the HCURSOR handle, e.g. by calling GetCursor (alternatives like LoadImage give similar results).

  • By searching the internet I found a possible solutions for obtaining the original bitmap, here the problem arises:

  • We use GetIconInfo (or GetIconInfoExW) to retrieve its color HBITMAP and use GetObject to retrieve the BITMAP.

  • The returned bitmap always has the dimensions 32x32, regardless of the DPI or the user's cursor scaling settings.

  • An alternative is using DrawIconEx onto a memory DC, however it seems to crudely upscale the 32x32 raster image and has inaccurate transparency pixels. Incurring loss of quality by upscaling a small raster image is not an option!

How can we get the exact cursor bitmap which is drawn onto the screen?

8

1 Answer 1

0

If cursor was created via CreateCursor/CreateIconIndirect/CreateIconFromResource/CreateIconFromResourceEx call then there is only one instance of HICON and you can get bitmap from it with GetIconInfoEx/GetIconInfoEx call (as you already doing).

But if cursor was loaded from file or resource via for LoadCursor/LoadImage then you can try to get ICONINFOEX structure with GetIconInfoEx and then use wResID/szModName/szResName in LoadImage call with desired size (DPI-aware).

Something like:

UINT dpi = GetDpiForWindow(hWnd);
INT x = GetSystemMetricsForDpi(SM_CXICON, dpi);
INT y = GetSystemMetricsForDpi(SM_CYICON, dpi);

ICONINFOEX iconInfoEx = {0};
GetIconInfoEx(hIcon, &iconInfoEx);
HMODULE hModule = GetModuleHandle(iconInfoEx.szModName);

HCURSOR hCursor = LoadImage(hModule, iconInfoEx.szResName != NULL ? iconInfoEx.szResName : MAKEINTRESOURCE(iconInfoEx.wResID), x, y, LR_DEFAULTSIZE);

Some info on this topic in Raymond Chen blog:

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.