Yeah, the windows cursor has significantly less lag.
To provide some more detail, I've found that the best way to use SetCursor is to place this code in you WndProc:
| case WM_SETCURSOR:
if( LOWORD( lparam ) == HTCLIENT )
{
SetCursor( my_hcursor_handle );
return 0;
}
break;
|
If you just call SetCursor once, the cursor will be changed when you hover over special areas of your window (like when resizing), so you need to call SetCursor in response to the WM_SETCURSOR message. By checking that lparam is HTCLIENT, you ensure that the cursor is only applied when you are actually within your client area - otherwise you will be overriding built in cursors like the resizing cursor.
To create a cursor, with full color and alpha channel, from an argb bitmap (as you would get from stb_image), I use this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 | static HCURSOR create_cursor_from_image( HWND hwnd, int width, int height, uint32_t* pixels_abgr, int hotspot_x, int hotspot_y )
{
BITMAPV5HEADER header;
memset( &header, 0, sizeof( BITMAPV5HEADER ) );
header.bV5Size = sizeof( BITMAPV5HEADER );
header.bV5Width = (LONG) width;
header.bV5Height = -(LONG) height;
header.bV5Planes = 1;
header.bV5BitCount = 32;
header.bV5Compression = BI_BITFIELDS;
header.bV5RedMask = 0x00FF0000;
header.bV5GreenMask = 0x0000FF00;
header.bV5BlueMask = 0x000000FF;
header.bV5AlphaMask = 0xFF000000;
HDC hdc = GetDC( hwnd );
void* bits = NULL;
HBITMAP bitmap = CreateDIBSection( hdc, (BITMAPINFO*)&header, DIB_RGB_COLORS, (void**) &bits, NULL, (DWORD) 0);
ReleaseDC( NULL, hdc );
uint32_t* ptr = (uint32_t*) bits;
for( int y = 0; y < height; ++y )
{
for( int x = 0; x < width; ++x )
{
uint32_t c = pixels_abgr[ x + y * width ];
uint32_t a = ( c & 0xff000000 ) >> 24;
uint32_t b = ( c & 0x00ff0000 ) >> 16;
uint32_t g = ( c & 0x0000ff00 ) >> 8;
uint32_t r = ( c & 0x000000ff );
*ptr++ = ( a << 24 ) | ( r << 16 ) | ( g << 8 ) | b;
}
}
HBITMAP empty_mask = CreateBitmap( width, height, 1, 1, NULL );
ICONINFO icon_info;
icon_info.fIcon = FALSE;
icon_info.xHotspot = (DWORD) hotspot_x;
icon_info.yHotspot = (DWORD) hotspot_y;
icon_info.hbmMask = empty_mask;
icon_info.hbmColor = bitmap;
HCURSOR cursor = CreateIconIndirect( &icon_info );
DeleteObject( bitmap );
DeleteObject( empty_mask );
return cursor;
}
|