The following objects do not provide an OLEDragMode property: Form, Label, Command Button, Frame, Check Box, Option Button, and Bound Data control. To allow users to drag OLE data from any of these objects, call the OLEDrag method on the object, as shown in Listing 19.3. You usually call OLEDrag from the MouseDown event procedure of the object.
Listing 19.3 - Starting a Manual Drag with the OLEDrag Method
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _ X As Single, Y As Single) ' Start drag operation. Form1.OLEDrag End Sub
The OLEDrag method triggers the OLE drag events described in Table 19.3. Use these events to enable OLE drag operations for objects that don't provide an OLEDragMode property, or to control the drag behavior when OLEDragMode is set to Manual.
Table 19.3 - Events to Use When Performing Manual Drag Operations
Event | Occurs When | Use to |
---|---|---|
OLEStartDrag | The OLEDrag method is called from code - usually in a MouseDown event. | Set the data and format of the data being dragged. |
OLEGiveFeedback | The source object is dragged over a target object. | Change the mouse pointer as the object is dragged over different targets. |
OLESetData | The target object requests dta from the source object after the user releases the mouse button, dropping the source object. | Retrieve the source data to drop on the target. This isn't needed if the data was set in OLEStartDrag. |
OLECompleteDrag | The drag operation is completed successfully. | Update the source object to reflet moved or deleted data. |
The OLE drag events give you some flexibility in structuring what happens when. If you want, you can load all your tasks into the first event, OLEStartDrag, as shown in Listing 19.4.
Listing 19.4 - Using the OLEStartDrag Event to Drags Text Off a Form
Private Sub Form_OLEStartDrag(Data As DataObject, _
AllowedEffects As Long) ' Set OLE data and format (mstrBackground variable ' is set by earlier OLEDragDrop event). Data.SetData mstrBackground, vbCFText ' Display the move mouse pointer.. AllowedEffects = vbDropEffectCopy End Sub
OLEStartDrag alone works fine for copy operations, but when you want to move data you need to write code in the OLECompleteDrag event to update the source object. For instance, the two events in Listing 19.5 move the text from the form background, clearing the form and the variable mstrBackground when the drag operation is complete.
Listing 19.5 - Using OLECompleteDrag to Delete Moved Text When the Drag Completes
Private Sub Form_OLEStartDrag(Data As DataObject, _
AllowedEffects As Long) ' Set data and format. Data.SetData mstrBackground, vbCFText ' Display the move mouse pointer.. AllowedEffects = vbDropEffectMove End Sub Private Sub Form_OLECompleteDrag(Effect As Long) ' Check if move is successful If Effect And vbDropEffectMove Then ' Reset the text variable. mstrBackground = "" ' Clear the form. Cls End If End Sub
It's important to wait for OLECompleteDrag before deleting moved items from their source. This ensures that the data is not lost if the drag operation is canceled. Alternately, you can do this in the OLESetData event. OLESetData occurs when the target object requests data from the drag source - just before OLECompleteDrag occurs. OLESetData is generally used to retrieve large items or items that require extra processing. This avoids delays when starting a drag operation and doing unnecessary processing if the drag operation is canceled. You might want to use OLESetData when retrieving items from a database, opening and reading files, connecting to servers or Web pages, or any other time-intensive operation.
When using the OLESetData event, be sure to set the data format and allowed effects in the OLEStartDrag event. Listing 19.6 sets the OLE data format in OLEStartDrag, but waits to create the data (a bitmap file) until the OLE drop target requests the data in OLESetData.
Listing 19.6 - Defer Time-Intensive Operations to OLESetData
Private Sub Form_OLEStartDrag(Data As DataObject, _ AllowedEffects As Long) ' Set data format to file. Data.SetData , vbCFFiles ' Display the move mouse pointer.. AllowedEffects = vbDropEffectCopy End Sub Private Sub Form_OLESetData(Data As DataObject, _ DataFormat As Integer) ' Save the form background as a bitmap file. SavePicture Form1.Picture, "temp.bmp" ' Add the file to the data object files list. Data.Files.Add CurDir & "\" & "temp.bmp" End Sub
The preceding code drags a file (temp.bmp) rather than bitmap data because applications like Microsoft Paint let you drag in files, but not other data. If you try to use the vbCFBitmap format, Windows displays the vbNoDrop mouse pointer when you try to drag the form's image into Microsoft Paint. When working with OLE applications, you'll often need to try out different data formats to see which they accept.
You use the OLEGiveFeedback event primarily to change the default mouse pointers displayed by Windows during an OLE drag. If you set the DefaultCursors parameter to False, you can override the standard OLE mouse pointers with the code in Listing 19.7.
Listing 19.7 - Using OLEGiveFeedback to Change the Mouse Pointer
Private Sub Form_OLEGiveFeedback(Effect As Long, _ DefaultCursors As Boolean) ' Turn off default mouse pointers. DefaultCursors = False ' Change mouse pointer based on Effect parameter. Select Case Effect ' Use the normal pointer for no drop. Case vbDropEffectNone Screen.MousePointer = vbNoDrop ' Use custom mouse pointers for copy and move. Case vbDropEffectCopy Screen.MousePointer = vbCustom Screen.MouseIcon = LoadPicture("drop1pg.ico") Case vbDropEffectMove Screen.MousePointer = vbCustom Screen.MouseIcon = LoadPicture("drag2pg.ico") End Select End Sub Private Sub Form_OLECompleteDrag(Effect As Long) ' Reset mouse pointer when drag is through. Screen.MousePointer = vbDefault End Sub
Be sure to reset the mouse pointer in OLECompleteDrag; otherwise, the custom mouse pointer remains after the drag is finished.