OLE Drag and Drop

From HashVB
Jump to: navigation, search
 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


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

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

External links