August 19th, 2021

What is the deal with the SM_CXCURSOR system metric?

There is a system metric known as SM_CXCURSOR. It ostensibly tells you the width of the cursor, but that doesn’t really hold up to scrutiny. First of all, there are multiple cursors in the system; which one does it give you the width of? And if you try it, you find that even if the cursors are all the same size, the metric doesn’t give you the right number. What’s going on?

Rewind to 16-bit Windows.

In 16-bit Windows, the standard cursors were provided by the display driver. All of those cursors were the same size, so a single metric was sufficient.

Windows 95 added the ability to customize the standard cursors, and that’s when things started to get messy. With this new feature, you could customize your cursors to be a size different from the size the display driver would have given. The SM_CXCURSOR metric still gave you the size of the driver-provided cursors, though, even if they weren’t the cursors that were in active use.

In Windows NT, the story is different. The display drivers are no longer in the default cursor business. The default cursors come from the window manager, but most users probably choose a custom one from the Mouse control panel.

Okay, so what does SM_CXCURSOR mean in this new world where nobody is using cursors from the display driver?

The SM_CXCURSOR metric returns the width of the cursor if the system were using the defaults. Which it rarely does any more. You can use them as the “nominal” cursor size, but understand that the actual cursors may not be that size. So what size are they, really? We’ll look into that next time.

Bonus chatter: In case you were wondering, here are the nominal cursor sizes, as of this writing. These values are not contractual and can change at any time, but I’m providing them to satisfy your curiosity:

DPI (scale) Cursor size
    x < 144dpi (150%)  32 ×  32 (100%)
144dpi (150%) ≤ x < 192dpi (200%)  48 ×  48 (150%)
192dpi (200%) ≤ x < 288dpi (300%)  64 ×  64 (200%)
288dpi (300%) ≤ x < 384dpi (400%)  96 ×  96 (300%)
384dpi (400%) ≤ x     128 × 128 (400%)
Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

2 comments

Discussion is closed. Login to edit/delete existing comments.

  • Neil Rashbrook

    The default I-beam cursor is still an inverting cursor, unlike most of the other default cursors. This works with Remote Desktop, but occasionally I need to remote desktop to an intermediate computer and then remote desktop from there to the final computer. Annoyingly, the inverting cursor no longer works in this case, and it simply disappears, so I have to temporarily have to choose an alternative opaque cursor.

  • Jan RingoÅ¡

    It would be nice if this progress was documented on GetSystemMetrics, which entries lost their meaning and in which version.

    The same, since 2015, I'm hoping for a proper documentation on Taskbar button icon size, since that's changed, so that vast majority of apps don't end up with blurred icon. If changing SM_CXICON to 24 is too breaking, then add something like SM_CXTASKBARICON, and document it in WNDCLASSEX, or something like that.

    Read more