You could utilize the WinAPI's GetCursorInfo()
function to get a handle to the current cursor. By then calling Icon.FromHandle()
and passing the cursor handle as a parameter you'll get the cursor as a drawable icon.
As different cursors may have different hotspots you'll have to take that into account too. For this you can use the WinAPI's GetIconInfo()
function to get the X and Y-coordinates for the hotspot, then you'll just have to substract the cursor's position with the hotspot's position.
The method for drawing the cursor:
Public Shared Sub DrawCursor(ByVal Graphics As Graphics)
Dim CursorInfo As New NativeMethods.CURSORINFO With {.cbSize = Marshal.SizeOf(GetType(NativeMethods.CURSORINFO))}
'Get the cursor info.
If NativeMethods.GetCursorInfo(CursorInfo) = True Then
Using CursorIcon As System.Drawing.Icon = System.Drawing.Icon.FromHandle(CursorInfo.hCursor) 'Get the cursor icon.
Dim IconInfo As New NativeMethods.ICONINFO
Try
Dim ModifierPoint As New Point(0, 0) 'Declare the modifier point (the cursor's hotspot).
'Get the info for the cursor icon.
If NativeMethods.GetIconInfo(CursorInfo.hCursor, IconInfo) = True Then
If IconInfo.fIcon = False Then 'If the cursor is an icon the hotspot will always be (0, 0).
ModifierPoint = New Point(IconInfo.xHotspot, IconInfo.yHotspot) 'Set the hotspot modifier.
End If
End If
'Normalize the coordinates according to the hotspot.
Dim FinalPoint As New Point(CursorInfo.ptScreenPos.x - ModifierPoint.X, CursorInfo.ptScreenPos.y - ModifierPoint.Y)
'Draw the cursor.
Graphics.DrawIcon(CursorIcon, New Rectangle(FinalPoint, CursorIcon.Size))
Finally
'Some cleaning up...
If IconInfo.hbmMask <> IntPtr.Zero Then
NativeMethods.DeleteObject(IconInfo.hbmMask)
IconInfo.hbmMask = IntPtr.Zero
End If
If IconInfo.hbmColor <> IntPtr.Zero Then
NativeMethods.DeleteObject(IconInfo.hbmColor)
IconInfo.hbmColor = IntPtr.Zero
End If
End Try
End Using
End If
End Sub
NativeMethods.vb:
Imports System.Runtime.InteropServices
Public NotInheritable Class NativeMethods
<StructLayout(LayoutKind.Sequential)> _
Public Structure POINT
Public x As Integer
Public y As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure CURSORINFO
Public cbSize As Integer
Public flags As Integer
Public hCursor As IntPtr
Public ptScreenPos As POINT
End Structure
<DllImport("user32.dll")> _
Public Shared Function GetCursorInfo(ByRef pci As CURSORINFO) As Boolean
End Function
<StructLayout(LayoutKind.Sequential)> _
Public Structure ICONINFO
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")> _
Public Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As Boolean
End Function
<DllImport("gdi32.dll")> _
Public Shared Function DeleteObject(ByVal hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
End Class
If you take the resulting screenshot you'd draw the cursor onto it like this:
Using g As Graphics = Graphics.FromImage(yourImage)
DrawCursor(g)
End Using