# General > Application Testing >  [RESOLVED] Change cursor with code, by pressing keys, to the respective document.cur

## rdrmdr

I'm creating a project,
with a no border [FormBorderStyle=None] transparent [BackColor=White][TransparencyKey=White] screen sized [Size=1366; 768] *form* (with 10 PictureBoxes):

...and I need help to make the application work.

I want it to change the cursor (doesn't matter the location, inside or outside the form, I want always the cursor selected) to one of my 9 cursors stored on my pc (one for each command Alt+1 Alt+2 Alt+3 Alt+4 Alt+5 Alt+6 Alt+7 Alt+8 Alt+9).
I already have the code for the commands *and* the code to change the cursor, *but* it only works at the beggining (when the form is being loaded [Event Form1_Load] and at the end [Event Form1_FormClosed] so that it changes back to the default cursor).
I tried to put on the *if Alt+1to9* code but it just doesn't work.
I think that I need to disable/unload the cursor, then change it, and enable/load it again but I don't know how to do it (or even destroy it and create a new one).
I searched everywhere but I can't understand the informations on the Internet because I can't find any example working or it's in C#/C++.

*Here's all the code on the project:*

```
Imports System.Runtime.InteropServices
Public Class Form1
    <DllImport("user32.dll")> Public Shared Function CopyIcon(ByVal hIcon As IntPtr) As IntPtr
    End Function
    <DllImport("user32.dll")> Private Shared Function LoadCursorFromFile(ByVal fileName As String) As IntPtr
    End Function
    <DllImport("User32.dll")> Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer
    End Function
    <DllImport("user32.dll")> Private Shared Function SetSystemCursor(ByVal hCursor As IntPtr, ByVal id As Integer) As Boolean
    End Function
    <DllImport("User32.dll")> Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, ByVal id As Integer) As Integer
    End Function
    Const OCR_NORMAL As UInteger = 32512
    Dim oldCursor As IntPtr
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        oldCursor = CopyIcon(Cursors.Default.CopyHandle)
        SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Grass Block 3D.cur")), OCR_NORMAL)
        Me.PictureBox2.Location = Me.PictureBox1.PointToClient(Me.PointToScreen(Me.PictureBox2.Location))
        Me.PictureBox2.Parent = Me.PictureBox1
        Me.PictureBox3.Location = Me.PictureBox1.PointToClient(Me.PointToScreen(Me.PictureBox3.Location))
        Me.PictureBox3.Parent = Me.PictureBox1
        Me.PictureBox4.Location = Me.PictureBox1.PointToClient(Me.PointToScreen(Me.PictureBox4.Location))
        Me.PictureBox4.Parent = Me.PictureBox1
        Me.PictureBox5.Location = Me.PictureBox1.PointToClient(Me.PointToScreen(Me.PictureBox5.Location))
        Me.PictureBox5.Parent = Me.PictureBox1
        Me.PictureBox6.Location = Me.PictureBox1.PointToClient(Me.PointToScreen(Me.PictureBox6.Location))
        Me.PictureBox6.Parent = Me.PictureBox1
        Me.PictureBox7.Location = Me.PictureBox1.PointToClient(Me.PointToScreen(Me.PictureBox7.Location))
        Me.PictureBox7.Parent = Me.PictureBox1
        Me.PictureBox8.Location = Me.PictureBox1.PointToClient(Me.PointToScreen(Me.PictureBox8.Location))
        Me.PictureBox8.Parent = Me.PictureBox1
        Me.PictureBox9.Location = Me.PictureBox1.PointToClient(Me.PointToScreen(Me.PictureBox9.Location))
        Me.PictureBox9.Parent = Me.PictureBox1
        Me.PictureBox10.Location = Me.PictureBox1.PointToClient(Me.PointToScreen(Me.PictureBox10.Location))
        Me.PictureBox10.Parent = Me.PictureBox1
        RegisterHotKey(Me.Handle, 0, &H1, 0)
        RegisterHotKey(Me.Handle, 100, &H1, Keys.D1)
        RegisterHotKey(Me.Handle, 200, &H1, Keys.D2)
        RegisterHotKey(Me.Handle, 300, &H1, Keys.D3)
        RegisterHotKey(Me.Handle, 400, &H1, Keys.D4)
        RegisterHotKey(Me.Handle, 500, &H1, Keys.D5)
        RegisterHotKey(Me.Handle, 600, &H1, Keys.D6)
        RegisterHotKey(Me.Handle, 700, &H1, Keys.D7)
        RegisterHotKey(Me.Handle, 800, &H1, Keys.D8)
        RegisterHotKey(Me.Handle, 900, &H1, Keys.D9)
    End Sub
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = &H312 Then
            Dim id As IntPtr = m.WParam
            Select Case (id.ToString)
                Case "0"
                    PictureBox1.Image = My.Resources.Toolbar_0
                    PictureBox1.Visible = True
                Case "100"
                    PictureBox1.Image = My.Resources.Toolbar_1
                    PictureBox1.Visible = True
                Case "200"
                    PictureBox1.Image = My.Resources.Toolbar_2
                    PictureBox1.Visible = True
                Case "300"
                    PictureBox1.Image = My.Resources.Toolbar_3
                    PictureBox1.Visible = True
                Case "400"
                    PictureBox1.Image = My.Resources.Toolbar_4
                    PictureBox1.Visible = True
                Case "500"
                    PictureBox1.Image = My.Resources.Toolbar_5
                    PictureBox1.Visible = True
                Case "600"
                    PictureBox1.Image = My.Resources.Toolbar_6
                    PictureBox1.Visible = True
                Case "700"
                    PictureBox1.Image = My.Resources.Toolbar_7
                    PictureBox1.Visible = True
                Case "800"
                    PictureBox1.Image = My.Resources.Toolbar_8
                    PictureBox1.Visible = True
                Case "900"
                    PictureBox1.Image = My.Resources.Toolbar_9
                    PictureBox1.Visible = True
            End Select
        End If
        MyBase.WndProc(m)
    End Sub
    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        PictureBox1.Visible = False
    End Sub
    Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs)
        UnregisterHotKey(Me.Handle, 0)
        UnregisterHotKey(Me.Handle, 100)
        UnregisterHotKey(Me.Handle, 200)
        UnregisterHotKey(Me.Handle, 300)
        UnregisterHotKey(Me.Handle, 400)
        UnregisterHotKey(Me.Handle, 500)
        UnregisterHotKey(Me.Handle, 600)
        UnregisterHotKey(Me.Handle, 700)
        UnregisterHotKey(Me.Handle, 800)
        UnregisterHotKey(Me.Handle, 900)
    End Sub
    Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        SetSystemCursor(CopyIcon(oldCursor), OCR_NORMAL)
    End Sub
End Class
```

*Note:*The fact that there's no border on the form makes the 'change the cursor back to the default' not work, making me have to change the cursor every time I run the app. The form is invisible so it's like the cursor it's outside the form. On the code above, the 2 lines that sets the cursor are on the load event and what I'm trying to accomplish is to have it on each case statment.
My two threads about it:
http://www.vbforums.com/showthread.p...r-outside-form
http://www.vbforums.com/showthread.p...the-beggining)

If you want the program, inform me where I should display it.  :Blush: 
Any questions about the project, please post and I will try to answer right away...  :Embarrassment:

----------


## .paul.

Are you saying you want the hotkeys to change the system cursor?

----------


## rdrmdr

> Are you saying you want the hotkeys to change the system cursor?


Yes, I want to change to a different cursor for each of the 9 HotKeys (10, the Alt Hotkey changes it back to the default).

----------


## .paul.

where are the .cur files?

----------


## rdrmdr

> where are the .cur files?


[Alt] = C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor.cur
It's just a copy of the default cursor.

[Alt+1] = C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Grass Block 3D.cur


[Alt+2] = C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Dirt 3D.cur


[Alt+3] = C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Oak Wood Planks 3D.cur


[Alt+4] = C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Cobblestone 3D.cur


[Alt+5] = C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Bricks 3D.cur


[Alt+6] = C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Oak Wood 3D.cur


[Alt+7] = C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Sand 3D.cur


[Alt+8] = C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Glass 3D.cur


[Alt+9] = C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Stone Bricks 3D.cur

----------


## rdrmdr

Can only attatch 5 pics for each post, here's the others...





Note: As you can see on the code, I go get the Toolbar (image) at my resorces but to get the cursor I need to go get at the file location because I can't import .cur files. Just pointing that out, not necessary to know  :Smilie:

----------


## .paul.

In the cases in the wndproc, use the same code you used in form_load to change the system cursor. It's just the 1 line and you'll need to change the file path in each case.

----------


## rdrmdr

> In the cases in the wndproc, use the same code you used in form_load to change the system cursor. It's just the 1 line and you'll need to change the file path in each case.


So I put something like this:

```
...
Select Case (id.ToString)
                Case "0"
                    PictureBox1.Image = My.Resources.Toolbar_0
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor.cur")), OCR_NORMAL)
                Case "100"
                    PictureBox1.Image = My.Resources.Toolbar_1
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Grass Block 3D.cur")), OCR_NORMAL)
                Case "200"
...
```

*If yes, and it works, then I'm SUPER DUMB* because I was putting the 2 lines :|

----------


## rdrmdr

It worked

```
...
Select Case (id.ToString)
                Case "0"
                    PictureBox1.Image = My.Resources.Toolbar_0
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor.cur")), OCR_NORMAL)
                Case "100"
                    PictureBox1.Image = My.Resources.Toolbar_1
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Grass Block 3D.cur")), OCR_NORMAL)
                Case "200"
                    PictureBox1.Image = My.Resources.Toolbar_2
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Dirt 3D.cur")), OCR_NORMAL)
                Case "300"
                    PictureBox1.Image = My.Resources.Toolbar_3
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Oak Wood Planks 3D.cur")), OCR_NORMAL)
                Case "400"
                    PictureBox1.Image = My.Resources.Toolbar_4
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Cobblestone 3D.cur")), OCR_NORMAL)
                Case "500"
                    PictureBox1.Image = My.Resources.Toolbar_5
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Bricks 3D.cur")), OCR_NORMAL)
                Case "600"
                    PictureBox1.Image = My.Resources.Toolbar_6
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Oak Wood 3D.cur")), OCR_NORMAL)
                Case "700"
                    PictureBox1.Image = My.Resources.Toolbar_7
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Sand 3D.cur")), OCR_NORMAL)
                Case "800"
                    PictureBox1.Image = My.Resources.Toolbar_8
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Glass 3D.cur")), OCR_NORMAL)
                Case "900"
                    PictureBox1.Image = My.Resources.Toolbar_9
                    PictureBox1.Visible = True
                    SetSystemCursor(CopyIcon(LoadCursorFromFile("C:\Users\Rúben\Desktop\Rúben\Texturas\Cursor Stone Bricks 3D.cur")), OCR_NORMAL)
            End Select
...
```

*but* there's some weird problem, it doesn't changes the cursor back to the default at the end *or* maybe it's setting the oldCursor wrong at the load event...
If I put the border style property of the form as Sizable and I end the program clicking on the [x] it change the cursor back to the default but if I break the program in the button on VB (blue square) it doesn't.
I see the problem, I'm gonna try to add a Hotkey Esc to close and change the cursor back...

----------


## .paul.

As i told you previously, you save the default cursor at the start in form_load in a form level variable called olDCursor. You don't change that variable all the way through the program and in form_closed you use that variable to restore the default cursor. Changing the cursor is permanent, which is why i told you you must save and restore the original cursor.

----------


## rdrmdr

It works, now I can have the border as none because I added the HotKey Key.Escape (Esc) to change it back and close.

Last *two* things, the image doesn't go to the right place, to click on something the cursor needs to be a little above it. Do you know how to change it? *And* I noticed that that code only changes the default cursor, can you give me the changing I need to do on the duplicated code to change all (or almost all) the cursors to be the same...

*Wait, I think I found it. Edgemeal* said on the 1st thread (http://www.vbforums.com/showthread.p...=1#post4997799) this link and now that I can understand a little better the code I know I need to change the hcur(OCR_NORMAL) with one of these of this list (https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx).


*SO*, now, for the final thing. I only need to set the location of cursor's image where it clicks (which I don't know how, do you?)

----------


## .paul.

the hotspot is built into the cursor file

----------


## rdrmdr

> the hotspot is built into the cursor file


I don't know how to change the HotSpot, I just went to this site https://convertio.co/pt/png-cur/ and converted my custom png documents to cur. Is there a way to change the HotSpot?

----------


## .paul.

Use this to create your cursors then you can choose the hotspot:



```
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.Drawing
''' <summary>
''' contains API + local functions for creating
''' a cursor from a bitmap on the fly
''' </summary>
''' <remarks></remarks>
Friend Class create

#Region "   CreateIconIndirect"

    Private Structure IconInfo
        Public fIcon As Boolean
        Public xHotspot As Int32
        Public yHotspot As Int32
        Public hbmMask As IntPtr
        Public hbmColor As IntPtr
    End Structure

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

    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    Public Shared Function DestroyIcon(ByVal handle As IntPtr) As Boolean
    End Function

    <DllImport("gdi32.dll")> _
    Public Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
    End Function

    ''' <summary>
    ''' CreateCursor
    ''' </summary>
    ''' <param name="bmp"></param>
    ''' <returns>custom Cursor</returns>
    ''' <remarks>creates a custom cursor from a bitmap</remarks>
    Public Shared Function CreateCursor(ByVal bmp As Bitmap, ByVal xHotspot As Integer, ByVal yHotspot As Integer) As Cursor
        'Setup the Cursors IconInfo
        Dim tmp As New IconInfo
        tmp.xHotspot = xHotspot
        tmp.yHotspot = yHotspot
        tmp.fIcon = False
        tmp.hbmMask = bmp.GetHbitmap()
        tmp.hbmColor = bmp.GetHbitmap()

        'Create the Pointer for the Cursor Icon
        Dim pnt As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(tmp))
        Marshal.StructureToPtr(tmp, pnt, True)
        Dim curPtr As IntPtr = CreateIconIndirect(pnt)

        'Clean Up
        DestroyIcon(pnt)
        DeleteObject(tmp.hbmMask)
        DeleteObject(tmp.hbmColor)

        Return New Cursor(curPtr)
    End Function

#End Region

End Class
```

----------


## rdrmdr

> Use this to create your cursors then you can choose the hotspot:
> 
> 
> 
> ```
> Imports System.Windows.Forms
> Imports System.Runtime.InteropServices
> Imports System.Drawing
> ''' <summary>
> ...


I added that code and there's no error but it didn't changed anything.
I know I probably have to change some part or put more code, but your code is big and I have no ideia.
Can you try to explain a little better?  :Ehh:

----------


## .paul.

Ok here's a demo project. Remember to read the comments in the form

cursor from bitmap.zip

----------


## rdrmdr

> Ok here's a demo project. Remember to read the comments in the form
> 
> cursor from bitmap.zip


It's some ammount of code but I tried on a new project, changed some stuff, and it worked.
Now I'm gonna try to apply it on my app.

*Form1.vb*

```
Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim img2 As New Bitmap(My.Resources._1)
        Dim img As New Bitmap(Cursors.Default.Size.Width + 20, Cursors.Default.Size.Height + 9)
        Dim gr As Graphics = Graphics.FromImage(img)
        Cursors.Default.Draw(gr, New Rectangle(Point.Empty, Cursors.Default.Size))
        gr.DrawImage(img2, New Point(img.Width - 32, img.Height - 32))
        Me.Cursor = create.CreateCursor(img, 10, 10)
    End Sub
End Class
```

*create.vb*

```
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.Drawing
Friend Class create
#Region "CreateIconIndirect"
    Private Structure IconInfo
        Public fIcon As Boolean
        Public xHotspot As Int32
        Public yHotspot As Int32
        Public hbmMask As IntPtr
        Public hbmColor As IntPtr
    End Structure
    <DllImport("user32.dll", EntryPoint:="CreateIconIndirect")> Private Shared Function CreateIconIndirect(ByVal iconInfo As IntPtr) As IntPtr
    End Function
    <DllImport("user32.dll", CharSet:=CharSet.Auto)> Public Shared Function DestroyIcon(ByVal handle As IntPtr) As Boolean
    End Function
    <DllImport("gdi32.dll")> Public Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
    End Function
    Public Shared Function CreateCursor(ByVal bmp As Bitmap, ByVal xHotspot As Integer, ByVal yHotspot As Integer) As Windows.Forms.Cursor
        Dim tmp As New IconInfo
        tmp.xHotspot = xHotspot
        tmp.yHotspot = yHotspot
        tmp.fIcon = False
        tmp.hbmMask = bmp.GetHbitmap()
        tmp.hbmColor = bmp.GetHbitmap()
        Dim pnt As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(tmp))
        Marshal.StructureToPtr(tmp, pnt, True)
        Dim curPtr As IntPtr = CreateIconIndirect(pnt)
        DestroyIcon(pnt)
        DeleteObject(tmp.hbmMask)
        DeleteObject(tmp.hbmColor)
        Return New Windows.Forms.Cursor(curPtr)
    End Function
#End Region
End Class
```

*Resources*
 1.png



I tried to attach my project as .rar but it gave error (no problem).
Random question: How do you add that text in the end of all your posts?
I think that's all for now, I will try to continue with the project wich, by the way, I had the idea from this cool video: https://www.youtube.com/watch?v=GW_fdXHOWp4
*Thank you* very much and see you soon.  :wave: 
Hint: The next time you see me will be probably a question related to mouse on/off desktop...

----------


## .paul.

I'd just use it to create and save some cursors. No need to incorporate it into your project...

----------


## rdrmdr

I'm trying to understand how to incorporate it on my project because of the hotspot (and because the other way makes the image scretch out for no obvious reason).
Well, I think I can figure this out. The only thing missing is make so that the created cursor isn't only activated on the form *Me*.Cursor = create.CreateCursor(img, 10, 10) and a lot of work to put that code creating 9 cursors, put it on the cases statments, test it and *purify* the code...  :LOL: 
EDIT: Gonna try to create my cursors smaller so that I can use the first methot (I found out that the problem with the hotspot and the scretched image was because the max size is 32x32pixels and the image was 44x32pixels). And I found this helpfull site to create cursors and change the hotspot easly: http://www.cursor.cc/
 [RESOLVED] Thread!

----------

