Reputation:
Is there a way to use a custom cursor in winforms?
There seems to be no option. But when I try to manually add a cursor as a resource, then call it from code, it says that it cannot convert from type byte[] to Cursor.
Upvotes: 15
Views: 40245
Reputation: 1
here I show you how you can change cursors globally and locally:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Testrix_Helper
{
public partial class Testrix_Helper : Form
{
// Import the SetSystemCursor function from the WinAPI
[DllImport("user32.dll", EntryPoint = "SetSystemCursor")]
private static extern bool SetSystemCursor(IntPtr hCursor, uint id);
// IDs for system cursors
private const uint OCR_NORMAL = 32512; // Default normal cursor
// Import the SystemParametersInfo function to restore system cursors
[DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
private static extern bool SystemParametersInfo(uint action, uint param, IntPtr vparam, uint init);
private const uint SPI_SETCURSORS = 0x0057;
private const uint SPIF_UPDATEINIFILE = 0x01;
private const uint SPIF_SENDCHANGE = 0x02;
// Stores the handle of the custom cursor to release it later
private IntPtr customCursorHandle;
// Import the DestroyCursor function to release custom cursor resources
[DllImport("user32.dll", EntryPoint = "DestroyCursor")]
private static extern bool DestroyCursor(IntPtr hCursor);
public Testrix_Helper()
{
InitializeComponent();
}
private void btnsi_Click(object sender, EventArgs e)
{
// FOR LOCAL CURSOR IN WINDOW: Cursor = new Cursor(bmp.GetHicon());
try
{
// Load the image from Resources and resize it to 48x48 pixels
Bitmap bmp = new Bitmap(new Bitmap(Properties.Resources.A), 48, 48);
// Convert the image into an icon
customCursorHandle = bmp.GetHicon();
// Change the global system cursor
if (SetSystemCursor(customCursorHandle, OCR_NORMAL))
{
Console.Write("Cursor changed globally.", "Success");
}
else
{
Console.Write("Error changing the cursor.", "Error");
}
}
catch (Exception ex)
{
MessageBox.Show($"Error: {ex.Message}", "Exception");
}
}
private void btnno_Click(object sender, EventArgs e)
{
// Restore the system cursors to their default settings
if (SystemParametersInfo(SPI_SETCURSORS, 0, IntPtr.Zero, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE))
{
Console.Write("Cursor restored to default settings.", "Success");
}
else
{
Console.Write("Error restoring the cursor.", "Error");
}
}
private void Testrix_Helper_FormClosing(object sender, FormClosingEventArgs e)
{
// Ensure the original system cursor is restored before closing the program
SystemParametersInfo(SPI_SETCURSORS, 0, IntPtr.Zero, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
// Release the resources of the custom cursor
if (customCursorHandle != IntPtr.Zero)
{
DestroyCursor(customCursorHandle);
}
}
}
}
Upvotes: 0
Reputation: 543
I had the same problem for a while. So, as far as I understood, these are 2 ways to solving that issue:
First case:
After putting to the resources you can just add .Handle
after the name of resource while getting it. For instance:
this.Cursor = new Cursor(Properties.Resources.YourResource.Handle);
Second case:
This one looks a bit easier, but before that you should add your .ico file to project and in properties of that file you should set Always copy
for file to be copied automatically to the execution folder. After that you can easyly use this:
this.Cursor = new Cursor("YourIcon.ico");
To my mind, using the resources for permanent files like cursor icons is the best practice, so the used the first one.
Upvotes: 2
Reputation: 163
Convert your cursor from any format to ico using convertico.com(It is the best way of doing this), copy your cursor to your project's debug folder using file explorer and write this code(C#):
this.Cursor = new Cursor("default.ico");
Upvotes: 2
Reputation: 185
Add Icon file to Project resources (ex : Processing.ico)
And in properties window of image switch "Build Action" to "Embedded"
Cursor cur = new Cursor(Properties.Resources.**Imagename**.Handle);
this.Cursor = cur;
Ex:
Cursor cur = new Cursor(Properties.Resources.Processing.Handle);
this.Cursor = cur;
Upvotes: 12
Reputation: 19
After adding the file to the resources, in the properties window of the image: switch Build Action
to Embedded Resource
and write in your code:
"name of control".Cursor = new System.Windows.Forms.Cursor(Properties.Resources."name of image".Handle);
Upvotes: 1
Reputation: 84725
From the MSDN documentation on the Cursor
class (with minor corrections):
// The following generates a cursor from an embedded resource.
// To add a custom cursor, create or use an existing 16x16 bitmap
// 1. Add a new cursor file to your project:
// File->Add New Item->Local Project Items->Cursor File
// 2. Select 16x16 image type:
// Image->Current Icon Image Types->16x16
// --- To make the custom cursor an embedded resource ---
// In Visual Studio:
// 1. Select the cursor file in the Solution Explorer
// 2. Choose View->Properties.
// 3. In the properties window switch "Build Action" to "Embedded"
// On the command line:
// Add the following flag:
// /res:CursorFileName.Cur,Namespace.CursorFileName.Cur
//
// Where "Namespace" is the namespace in which you want to use
// the cursor and "CursorFileName.Cur" is the cursor filename.
// The following line uses the namespace from the passed-in type
// and looks for CustomCursor.MyCursor.Cur in the assemblies manifest.
// NOTE: The cursor name is case sensitive.
this.Cursor = new Cursor(GetType(), "MyCursor.Cur");
Upvotes: 5
Reputation: 1470
I've used the LoadCursorFromFile()
method from User32.dll. There are plenty of samples for this on the web.
OR
The ctor for the Cursor
type also has a IO.Stream
overload. Load your byte[]
into a MemoryStream
and feed that to the new Cursor
.
Upvotes: 2