anon271334
anon271334

Reputation:

Using Custom Cursor WinForms

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

Answers (7)

Eduardo León
Eduardo León

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

Vizel Leonid
Vizel Leonid

Reputation: 543

I had the same problem for a while. So, as far as I understood, these are 2 ways to solving that issue:

  1. Putting cursor .ico file into the Resources
  2. Getting cursor from .ico file without putting it the resources

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

Dude4
Dude4

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

Hari Prakash
Hari Prakash

Reputation: 185

Adding custom icon to cursor in C# :

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

Ilham Mourad
Ilham Mourad

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

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

David Perlman
David Perlman

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

Related Questions