OLE Drag and Drop
|This article is based on Visual Basic 6. Find other Visual Basic 6 articles.|
Supporting OLE drag and drop allows you to do some nifty stuff including allowing files to be dropped on your application. It can also be used to drag items internal to your own application or even between them.
Registering the object type
If you are planning on using generic object types, you can skip this step, but it means your object may get dropped in places you don't want.
Private Declare Function RegisterClipboardFormat Lib "user32" Alias "RegisterClipboardFormatA" (ByVal lpString As String) As Long Public CF_CUSTOMTYPE As Long
And when it comes to register the format itself:
'Register the custom OLE/Clipboard ID CF_CUSTOMTYPE = RegisterClipboardFormat("CF_CUSTOMTYPE") 'Convert to a signed value for use later CF_CUSTOMTYPE = Val("&H" & Hex(CF_CUSTOMTYPE))
Dragging the object
If your source control natively supports OLE dragging, it should have an OLEDragMode property. If this is not set to Automatic, then you will need to manually start the drag in code using the OLEDrag method.
When the drag is started, the control will fire the OLEStartDrag mode which allows you to add your custom data for the target to use:
Private Sub SourceList_OLEStartDrag(Data As ComctlLib.DataObject, AllowedEffects As Long) Dim DragData() As Byte 'Only allow dragging child nodes If SourceList.SelectedItem.Parent Is Nothing Then 'As it's a root node, don't allow anything AllowedEffects = vbDropEffectNone Else 'Convert to a byte array to pass through the OLE system DragData = SourceList.SelectedItem.Key Data.SetData DragData, CInt(CF_CUSTOMTYPE) 'Allow copy and move.. AllowedEffects = vbDropEffectCopy Or vbDropEffectMove End If End Sub
Dropping the object
Once the drag has been started, you will get the OLEDragOver event fired on all controls with OLEDropMode set to Manual. This event allows you to specify whether you want to allow dropping of a particular object or not.
Private Sub TargetBox_OLEDragOver(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single, State As Integer) 'We're only interested our custom data type If Data.GetFormat(CF_CUSTOMTYPE) Then Effect = vbDropEffectMove Else Effect = vbDropEffectNone End If End Sub
Once the user has dropped the object, you will get the OLEDragDrop event fired in the target object
Private Sub TargetBox_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) Dim DragData() As Byte Dim DragDataString As String 'If it is our type, accept it If Data.GetFormat(CF_CUSTOMTYPE) Then 'Get the item key DragData = Data.GetData(CF_CUSTOMTYPE) 'Convert back from a byte array to a string DragDataString = DragData 'Print the dragged objects Key at the drop location TargetBox.CurrentX = X TargetBox.CurrentY = Y TargetBox.Print DragDataString End If End Sub
There are other events that allow the source to know when and where the object was dropped, but this is left as an excercise to the reader to investigate.