3

I want to get the height and width of a .cur file without look into its format.

I try to use LoadCursorFromFile() to get a HCURSOR, I suppose there is a API function to obtain the HCURSOR infos, but I find that GetCursorInfo() is not I want at all.

Is there any way to get the height and width of a HCURSOR object?

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
Gohan
  • 2,422
  • 2
  • 26
  • 45

3 Answers3

7

Universal C++ code, for any cursor:

SIZE GetSize(HCURSOR ico)
{
    SIZE res = {0};
    if (ico)
    {
        ICONINFO info = {0};
        if ( ::GetIconInfo(ico, &info)!=0 )
        {
            bool bBWCursor = (info.hbmColor==NULL);
            BITMAP bmpinfo = {0};
            if (::GetObject( info.hbmMask, sizeof(BITMAP), &bmpinfo)!=0)
            {
                res.cx = bmpinfo.bmWidth;
                res.cy = abs(bmpinfo.bmHeight) / (bBWCursor ? 2 : 1);
            }

            ::DeleteObject(info.hbmColor);
            ::DeleteObject(info.hbmMask);
        }
    }
    return res;
}
23W
  • 1,413
  • 18
  • 37
  • 1
    Use SM_CXCURSOR or SM_CYCURSOR is nor correct. For example: after switching to huge cursor size in control panel values of SM_CXCURSOR and SM_CYCURSOR remain 32x32. – 23W Nov 08 '12 at 18:30
  • Still returns 32x32 when using the Windows 10 options (Settings > Ease of Access > Mouse pointer size). – Nicke Manarin Jun 10 '21 at 21:55
  • I get back the wrong height – user13947194 Jun 01 '22 at 23:25
  • When you think about it, an icon is a file that stores multiple dimensions of the same image. How will GetIconInfo know the right dimension to return information on? – user13947194 Jun 02 '22 at 00:28
6

THIS ANSWER IS OUT OF DATE

See 23W's answer instead. That looks right to me.

Raymond Chen has a blog post that explains the SM_CXCURSOR and SM_CYCURSOR system metrics were the size of the hardware cursor implemented by the display adapter. Since cursors are no longer a feature of modern display hardware, these values are obsolete, but the OS still reports values for backward compatibility.

Thanks to @SO_fix_the_vote_sorting_bug's comment for bringing this to my attention.


ORIGINAL ANSWER FOR HISTORICAL CONTEXT

There is some overlap in the APIs between icons and cursors in Windows. You can call GetIconInfoEx with an HCURSOR as well as with an HICON. The structure you get back will have information about the hotspot.

I don't see a way to get the actual size. Technically, all cursor icons are a fixed size that you can get by asking the system (with GetSystemMetrics) for SM_CXCURSOR and SM_CYCURSOR. The ones that appear smaller are actually that size, they just have a lots of transparent pixels. If you must know the apparent size, you'll have to extract the mask and scan the bits to figure out the bounding rectangle.

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175
  • With `GetIconInfo*` won't you get back an `HBITMAP` in the `ICONINFO`? Maybe you can get the size that way. But MS has the following remark: "`GetIconInfoEx` creates bitmaps for the `hbmMask` and `hbmCol` or members of `ICONINFOEX`. The calling application must manage these bitmaps and delete them when they are no longer necessary." – SO_fix_the_vote_sorting_bug Aug 20 '21 at 18:11
1

From MSDN:

The nWidth and nHeight parameters must specify a width and height that are supported by the current display driver, because the system cannot create cursors of other sizes. To determine the width and height supported by the display driver, use the GetSystemMetrics function, specifying the SM_CXCURSOR or SM_CYCURSOR value.

gwell
  • 2,695
  • 20
  • 20