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
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