Title: Convert a bitmap into a cursor in C#
Converting a bitmap into a cursor isn't easy, but you can do it by using the CreateIconIndirect API function. This example uses the following BitmapToCursor method to create a cursor from a bitmap.
// Create a cursor from a bitmap.
private Cursor BitmapToCursor(Bitmap bmp, int hot_x, int hot_y)
{
// Initialize the cursor information.
ICONINFO icon_info = new ICONINFO();
IntPtr h_icon = bmp.GetHicon();
GetIconInfo(h_icon, out icon_info);
icon_info.xHotspot = hot_x;
icon_info.yHotspot = hot_y;
icon_info.fIcon = false; // Cursor, not icon.
// Create the cursor.
IntPtr h_cursor = CreateIconIndirect(ref icon_info);
return new Cursor(h_cursor);
}
Download the example and look at the code to see the API declarations.
This code creates an ICONINFO structure to describe the cursor that it will create. It calls the bitmap's GetHicon method to get a handle to an icon that has the same image as the bitmap. It passes that handle to the GetIconInfo API function to get ICONINFO data describing the icon.
Next the code sets the X and Y coordinates of the cursor's hot spot, the position inside the cursor that represents the mouse's position. For example, an arrow cursor would normally use the arrow's tip as the hot spot. A cross would normally use the center of the cursor as its hotspot.
The code then sets the ICONINFO structure's fIcon property to false to indicate that this should be a cursor and not an icon. It then calls the CreateIconIndirect method to create the icon and get a new handle to it. Finally the code passes the handle to the Cursor class's constructor and returns the resulting Cursor object.
Note that these API functions allocate unmanaged memory that is never freed by the program. If the program only creates a few cursors, that's not a problem. If the program could create hundreds of cursors on the fly, this will cause a memory leak that may be a problem. In that case, use the DestroyIcon API function to release cursors that are no longer needed.
The program uses the following code to create its cursor.
private void Form1_Load(object sender, EventArgs e)
{
// Make pixels that match the one in the
// upper left corner transparent.
Bitmap bm = Properties.Resources.Diamond;
bm.MakeTransparent(bm.GetPixel(0, 0));
this.Cursor = BitmapToCursor(bm, 7, 7);
}
The program gets the bitmap resource named Diamond and makes the pixels that match the one in its upper left corner transparent. It then calls the BitmapToCursor method and uses the result as the form's cursor.
Using this technique you can make cursors of any size, but you should probably stick to relatively small sizes such as the typical 16×16 pixels.
Download the example to experiment with it and to see additional details.
|