Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Custom Colored Cursors in a C# Windows Application [closed]

I am developing a SDG (Single Display Groupware) application, and for that I need multiple cursors (to the simplest of different colors) for the single window. I came to know that with C# you can just use black and white cursors, which does not solve my problem.

like image 456
Himanshu Avatar asked Nov 29 '10 16:11

Himanshu


People also ask

How do I change my custom cursor color?

Go to Accessibility > Mouse pointer and touch. In Mouse pointer and touch, click to expand the Mouse pointer style and pick Custom. Once you select Custom, you can pick one of the 8 Recommended colors shown below or click the plus (+) button to change your mouse cursor to pick a custom color.

How do I get animated cursors?

To create an animated cursor use the "File/New/New Cursor..." menu item. This will open the New Cursor dialog. On the New Cursor dialog select the desired image size and bit count. Make sure that the "Animated Cursor (ANI)" radio button is selected.


2 Answers

The Cursor class is rather poorly done. For some mysterious reason it uses a legacy COM interface (IPicture), that interface doesn't support colored and animated cursors. It is fixable with some fairly ugly elbow grease:

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;

static class NativeMethods {
    public static Cursor LoadCustomCursor(string path) {
        IntPtr hCurs = LoadCursorFromFile(path);
        if (hCurs == IntPtr.Zero) throw new Win32Exception();
        var curs = new Cursor(hCurs);
        // Note: force the cursor to own the handle so it gets released properly
        var fi = typeof(Cursor).GetField("ownHandle", BindingFlags.NonPublic | BindingFlags.Instance);
        fi.SetValue(curs, true);
        return curs;
    }
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr LoadCursorFromFile(string path);
}

Sample usage:

this.Cursor = NativeMethods.LoadCustomCursor(@"c:\windows\cursors\aero_busy.ani");
like image 143
Hans Passant Avatar answered Nov 14 '22 22:11

Hans Passant


I also tried something different and it seems to work with different colored cursors, but the only problem with this piece of code is that the Hotspot coordinates for the mouse cursors are not exact i.e. the are moved slightly to the right. But this can be fixed by considering an offset in the code.

The code is as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;

namespace MID
{    
    public partial class CustomCursor : Form
    {
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr LoadCursorFromFile(string filename);

        public CustomCursor()
        {
            InitializeComponent();

            Bitmap bmp = (Bitmap)Bitmap.FromFile("Path of the cursor file saved as .bmp");
            bmp.MakeTransparent(Color.Black);
            IntPtr ptr1 = blue.GetHicon();

            Cursor cur = new Cursor(ptr1);
            this.Cursor = cur;

        }
    }
}
like image 36
Himanshu Avatar answered Nov 14 '22 22:11

Himanshu