WinForms Drag Drop with Custom Image/Cursor

L

Lloyd Sheen

A few days ago I posted a question about how to create and use a custom
image when using drag/drop in winforms. I had googled but could not find
anything other than asp.net code. Today I used different terms and found an
answer which I will share. The link I found is:

http://blog.paranoidferret.com/index.php/2008/03/18/winforms-using-custom-cursors-with-drag-drop/

The code is C# so I have included the VB.NET code that I translated to
provide a small test platform. I used CLRInsideOut which you can get from
MS to get the code for the windows API function that were used.

The test used a button which was the drag source and a panel as the drag
destination.

Form Code:

Public Class Form1

Private _MouseDown As Boolean = False
Private _MouseX As Integer
Private _MouseY As Integer
Private _MouseButtons As MouseButtons
Private _SwitchContext As Boolean = False

Private Sub Button1_GiveFeedback(ByVal sender As Object, ByVal e As
System.Windows.Forms.GiveFeedbackEventArgs) Handles Button1.GiveFeedback
e.UseDefaultCursors = False
End Sub

Private Sub Button1_MouseDown(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown
_MouseButtons = e.Button
_SwitchContext = False
_MouseDown = True
_MouseX = e.X
_MouseY = e.Y
End Sub

Private Sub Button1_MouseMove(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.MouseEventArgs) Handles Button1.MouseMove
If _MouseDown Then
Dim xx As DataObject = New DataObject
xx.SetText("here we go")
Try
Button1.DoDragDrop(xx, DragDropEffects.Copy)
_MouseDown = False
Catch ex As Exception
Dim zzzz As Integer = 1
End Try

End If
End Sub

Private Sub Button1_MouseUp(ByVal sender As Object, ByVal e As
System.Windows.Forms.MouseEventArgs) Handles Button1.MouseUp
_MouseDown = False
End Sub

Private Sub Panel1_DragEnter(ByVal sender As Object, ByVal e As
System.Windows.Forms.DragEventArgs) Handles Panel1.DragEnter
Dim str As String = TryCast(e.Data.GetData(GetType(String)), String)

Dim size As SizeF
Dim f As New Font(FontFamily.GenericSerif, 10, FontStyle.Bold)
Using tmpBmp As New Bitmap(1, 1)
Using g As Graphics = Graphics.FromImage(tmpBmp)
size = g.MeasureString(str, f)
End Using
End Using

Dim bitmap As New Bitmap(CInt(Math.Ceiling(size.Width)),
CInt(Math.Ceiling(size.Height)))
Using g As Graphics = Graphics.FromImage(bitmap)
g.DrawString(str, f, Brushes.Black, 0, 0)
End Using

Cursor.Current = CreateCursor(bitmap, 0, 0)

bitmap.Dispose()
f.Dispose()

End Sub

Private Sub Panel1_DragOver(ByVal sender As Object, ByVal e As
System.Windows.Forms.DragEventArgs) Handles Panel1.DragOver
e.Effect = DragDropEffects.All
End Sub

Public Shared Function CreateCursor(ByVal bmp As Bitmap, ByVal xHotSpot As
Integer, ByVal yHotSpot As Integer) As Cursor
Dim ptr As IntPtr = bmp.GetHicon()
Dim tmp As New ICONINFO()
Module1.NativeMethods.GetIconInfo(ptr, tmp)
tmp.xHotspot = CType(xHotSpot, UInteger)
tmp.yHotspot = CType(yHotSpot, UInteger)
tmp.fIcon = False
ptr = Module1.NativeMethods.CreateIconIndirect(tmp)
Return New Cursor(ptr)
End Function
End Class


Module Code:

Module Module1

<System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)>_ Public Structure HICON__ '''int Public unused As Integer End Structure <System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)> _ Public Structure ICONINFO '''BOOL->int <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)> _ Public fIcon As Boolean '''DWORD->unsigned int Public xHotspot As UInteger '''DWORD->unsigned int Public yHotspot As UInteger '''HBITMAP->HBITMAP__* Public hbmMask As System.IntPtr '''HBITMAP->HBITMAP__* Public hbmColor As System.IntPtr End Structure <System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)> _ Public Structure HBITMAP__ '''int Public unused As Integer End Structure Partial Public Class NativeMethods '''Return Type: BOOL->int '''hIcon: HICON->HICON__* '''piconinfo: PICONINFO->ICONINFO* <System.Runtime.InteropServices.DllImportAttribute("user32.dll",EntryPoint:="GetIconInfo")> _ Public Shared FunctionGetIconInfo(<System.Runtime.InteropServices.InAttribute()> ByVal hIcon AsSystem.IntPtr, <System.Runtime.InteropServices.OutAttribute()> ByRefpiconinfo As ICONINFO) As<System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)> Boolean End Function End Class Partial Public Class NativeMethods '''Return Type: HICON->HICON__* '''piconinfo: PICONINFO->ICONINFO* <System.Runtime.InteropServices.DllImportAttribute("user32.dll",EntryPoint:="CreateIconIndirect")> _ Public Shared FunctionCreateIconIndirect(<System.Runtime.InteropServices.InAttribute()> ByRefpiconinfo As ICONINFO) As System.IntPtr End Function End ClassEnd ModuleHope this helps those who may have looked at doing this but could not findcode to get it done.LS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top