0 Replies - 1283 Views - Last Post: 26 February 2016 - 01:33 PM

#1 IronRazer  Icon User is offline

  • Custom Control Freak
  • member icon

Reputation: 1464
  • View blog
  • Posts: 3,713
  • Joined: 01-February 13

Create cursors for your application from bitmap images

Posted 26 February 2016 - 01:33 PM

Here is a handy way to create and use custom cursors in your application from common Png image files. You can either add the Png images to your application`s Resources or you can load them from the hard drive. This method will allow you to set the X and Y hotspot of the cursor too.

This will create the cursor the same size as the bitmap image you use to create the cursor. Cursor files can only be a maximum of 512x512 but, i would recommend sticking with standard cursor sizes for your images such as 24x24, 32x32, 48x48, or 64x64.

Here is a Png image you can right click on and save to your hard drive for testing this example out.
Attached Image

First add the CursorHelper class to your project.
Imports System.Runtime.InteropServices

Public Class CursorHelper
    <StructLayout(LayoutKind.Sequential)> _
    Private Structure ICONINFO
        <MarshalAs(UnmanagedType.Bool)> Public fIcon As Boolean
        Public xHotspot As Integer
        Public yHotspot As Integer
        Public hbmMask As IntPtr
        Public hbmColor As IntPtr
    End Structure

    <DllImport("user32.dll", EntryPoint:="CreateIconIndirect")> Private Shared Function CreateIconIndirect(ByRef iconInfo As ICONINFO) As IntPtr
    End Function

    <DllImport("gdi32.dll", EntryPoint:="DeleteObject")> Private Shared Function DeleteObject(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    ''' <summary>Creates a Cursor from a bitmap image.</summary>
    ''' <param name="SourceImage">The bitmap image to create the cursor from.</param>
    ''' <param name="HotSpot">The X and Y hotspot location of the cursor.</param>
    Public Shared Function CreateCursorFromImage(ByVal SourceImage As Bitmap, ByVal HotSpot As Point) As Cursor
        'make sure the image is not nothing
        If SourceImage Is Nothing Then Throw New ArgumentException("The image can not be Nothing.", "SourceImage")

        'make sure the image is within a valid cursor size
        If SourceImage.Width > 512 Or SourceImage.Height > 512 Then Throw New ArgumentException("The size of the image can not ecceed 512x512.", "SourceImage")

        'make shore the HotSpot is within valid limits
        If HotSpot.X < 0 Then HotSpot.X = 0
        If HotSpot.Y < 0 Then HotSpot.Y = 0
        If HotSpot.X > SourceImage.Width Then HotSpot.X = SourceImage.Width
        If HotSpot.Y > SourceImage.Height Then HotSpot.Y = SourceImage.Height

        Dim Crsr As Cursor = Nothing 'declare a Cursor to return from this function

        Using bm As New Bitmap(SourceImage) 'create a New Bitmap image that is the specified Size from the specified SourceImage

            Dim hBitmap As IntPtr = bm.GetHbitmap 'create a GDI Bitmap in the memory and get the handle to it

            Dim ii As New ICONINFO       'create a new IconInfo structure
            ii.fIcon = False             'False indicates this is a Cursor instead of an Icon
            ii.hbmColor = hBitmap        'set the color bitmap to the handle of the bitmap in memory
            ii.hbmMask = hBitmap         'set the bitmap mask to the handle of the bitmap in memory
            ii.xHotspot = HotSpot.X      'set the X hotspot
            ii.yHotspot = HotSpot.Y      'set the Y hotspot

            'call the CreateIconInderect function to create the Cursor image in the memory and get the handle to the Cursor
            Dim hCursor As IntPtr = CreateIconIndirect(ii)

            'now that the Cursor image was created in the memory, you need to delete the GDI bitmap that was created in the memory
            DeleteObject(hBitmap)

            Crsr = New Cursor(hCursor) 'create a new instance of the Cursor class from the Cursor that was created in the memory
        End Using

        Return Crsr 'return the new cursor that was created
    End Function
End Class



If you just wish to set some custom cursors when the form loads and do not plan on changing them at runtime then here is a simple example for doing that.
Public Class Form1

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        'I imagine that as the form and all of its controls are disposed that the Cursors would be disposed too since they Implement IDisposable.
        'However, i like to Dispose them myself when the form is closing just to be sure they are destroyed and i have no memory leaks.
        Me.Cursor.Dispose()
        Button1.Cursor.Dispose()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'set the Form`s cursor to the red arrow png image that was saved to the application`s Resources
        Me.Cursor = CursorHelper.CreateCursorFromImage(My.Resources.PngArrowImage, New Point(5, 5))

        'set Button1`s cursor using a Png image on the hard drive
        Using bmpImage As New Bitmap("C:\TestFolder\BlueMagGlass.png")
            Button1.Cursor = CursorHelper.CreateCursorFromImage(bmpImage, New Point(5, 5))
        End Using
    End Sub

End Class



If you want to use one or more cursor for a control such as one cursor when the mouse is pressed down on a Button and another when the mouse is released, here is an example of doing that.
Public Class Form1
    Private ButtonUpCursor As Cursor = Nothing
    Private ButtonDownCursor As Cursor = Nothing

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        'since only one cursor is assigned to the Button`s cursor, we can not depend on the Dispose method being called
        'on it when the Form is closing. So, you need to be sure to Dispose of the cursors.
        ButtonUpCursor.Dispose()
        ButtonDownCursor.Dispose()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'set the ButtonUpCursor to the red arrow png image that was saved to the application`s Resources
        ButtonUpCursor = CursorHelper.CreateCursorFromImage(My.Resources.PngArrowImage, New Point(5, 5))

        'set ButtonDownCursor using a Png image on the hard drive
        Using bmpImage As New Bitmap("C:\TestFolder\BlueMagGlass.png")
            ButtonDownCursor = CursorHelper.CreateCursorFromImage(bmpImage, New Point(5, 5))
        End Using

        Button1.Cursor = ButtonUpCursor
    End Sub

    Private Sub Button1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown
        Button1.Cursor = ButtonDownCursor 'when the mouse is down, use the ButtonDownCursor
    End Sub

    Private Sub Button1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseUp
        Button1.Cursor = ButtonUpCursor 'when the button is released, use the ButtonUpCursor
    End Sub
End Class


This post has been edited by IronRazer: 26 February 2016 - 02:19 PM


Is This A Good Question/Topic? 0
  • +

Page 1 of 1